17 Operation *instanceOp, SymbolTableCollection &symbolTable,
18 mlir::FlatSymbolRefAttr moduleName, Operation *&module) {
19 module = symbolTable.lookupNearestSymbolFrom(instanceOp, moduleName);
20 if (module ==
nullptr)
21 return instanceOp->emitError(
"Cannot find module definition '")
22 << moduleName.getValue() <<
"'";
25 if (!isa<HWModuleLike>(module))
26 return instanceOp->emitError(
"symbol reference '")
27 << moduleName.getValue() <<
"' isn't a module";
33 Location loc, ArrayAttr parameters, ArrayRef<Type> types,
34 SmallVectorImpl<Type> &resolvedTypes,
const EmitErrorFn &emitError) {
35 for (
auto type : types) {
37 if (failed(expectedType)) {
38 emitError([&](
auto &diag) {
39 diag <<
"failed to resolve parametric input of instantiated module";
45 resolvedTypes.push_back(*expectedType);
52 ArrayAttr moduleArgNames,
54 ArrayRef<Type> moduleInputTypes,
57 if (moduleInputTypes.size() != inputTypes.size()) {
58 emitError([&](
auto &diag) {
59 diag <<
"has a wrong number of operands; expected "
60 << moduleInputTypes.size() <<
" but got " << inputTypes.size();
66 if (argNames.size() != inputTypes.size()) {
67 emitError([&](
auto &diag) {
68 diag <<
"has a wrong number of input port names; expected "
69 << inputTypes.size() <<
" but got " << argNames.size();
75 for (
size_t i = 0; i != inputTypes.size(); ++i) {
76 auto expectedType = moduleInputTypes[i];
77 auto operandType = inputTypes[i];
79 if (operandType != expectedType) {
80 emitError([&](
auto &diag) {
81 diag <<
"operand type #" << i <<
" must be " << expectedType
82 <<
", but got " << operandType;
88 if (argNames[i] != moduleArgNames[i]) {
89 emitError([&](
auto &diag) {
90 diag <<
"input label #" << i <<
" must be " << moduleArgNames[i]
91 <<
", but got " << argNames[i];
102 ArrayAttr resultNames, ArrayAttr moduleResultNames, TypeRange resultTypes,
103 ArrayRef<Type> moduleResultTypes,
const EmitErrorFn &emitError) {
105 if (moduleResultTypes.size() != resultTypes.size()) {
106 emitError([&](
auto &diag) {
107 diag <<
"has a wrong number of results; expected "
108 << moduleResultTypes.size() <<
" but got " << resultTypes.size();
114 if (resultNames.size() != resultTypes.size()) {
115 emitError([&](
auto &diag) {
116 diag <<
"has a wrong number of results port labels; expected "
117 << resultTypes.size() <<
" but got " << resultNames.size();
123 for (
size_t i = 0; i != resultTypes.size(); ++i) {
124 auto expectedType = moduleResultTypes[i];
125 auto resultType = resultTypes[i];
127 if (resultType != expectedType) {
128 emitError([&](
auto &diag) {
129 diag <<
"result type #" << i <<
" must be " << expectedType
130 <<
", but got " << resultType;
136 if (resultNames[i] != moduleResultNames[i]) {
137 emitError([&](
auto &diag) {
138 diag <<
"result label #" << i <<
" must be " << moduleResultNames[i]
139 <<
", but got " << resultNames[i];
150 ArrayAttr parameters, ArrayAttr moduleParameters,
151 ArrayRef<Type> resolvedModParametersRefs,
const EmitErrorFn &emitError) {
153 auto numParameters = parameters.size();
154 if (numParameters != moduleParameters.size()) {
155 emitError([&](
auto &diag) {
156 diag <<
"expected " << moduleParameters.size() <<
" parameters but had "
163 for (
size_t i = 0; i != numParameters; ++i) {
164 auto param = cast<ParamDeclAttr>(parameters[i]);
165 auto modParam = cast<ParamDeclAttr>(moduleParameters[i]);
166 auto resolvedModParamType = resolvedModParametersRefs[i];
168 auto paramName = param.getName();
169 if (paramName != modParam.getName()) {
170 emitError([&](
auto &diag) {
171 diag <<
"parameter #" << i <<
" should have name " << modParam.getName()
172 <<
" but has name " << paramName;
178 if (param.getType() != resolvedModParamType) {
179 emitError([&](
auto &diag) {
180 diag <<
"parameter " << paramName <<
" should have type "
181 << modParam.getType() <<
" but has type " << param.getType();
189 if (!param.getValue()) {
190 emitError([&](
auto &diag) {
191 diag <<
"parameter " << paramName <<
" must have a value";
202 Operation *instance, FlatSymbolRefAttr moduleRef, OperandRange inputs,
203 TypeRange results, ArrayAttr argNames, ArrayAttr resultNames,
204 ArrayAttr parameters, SymbolTableCollection &symbolTable) {
216 [&](
const std::function<bool(InFlightDiagnostic & diag)> &fn) {
217 auto diag = instance->emitOpError();
219 diag.attachNote(module->getLoc()) <<
"module declared here";
223 auto mod = cast<HWModuleLike>(module);
225 ArrayAttr::get(instance->getContext(), mod.getInputNames());
226 auto modResultNames =
227 ArrayAttr::get(instance->getContext(), mod.getOutputNames());
229 ArrayRef<Type> resolvedModInputTypesRef =
getModuleType(module).getInputs();
231 SmallVector<Type> resolvedModInputTypes;
234 instance->getLoc(), parameters,
getModuleType(module).getInputs(),
235 resolvedModInputTypes, emitError)))
237 resolvedModInputTypesRef = resolvedModInputTypes;
241 argNames, modArgNames, inputs.getTypes(), resolvedModInputTypesRef,
246 ArrayRef<Type> resolvedModResultTypesRef =
getModuleType(module).getResults();
247 SmallVector<Type> resolvedModResultTypes;
250 instance->getLoc(), parameters,
getModuleType(module).getResults(),
251 resolvedModResultTypes, emitError)))
253 resolvedModResultTypesRef = resolvedModResultTypes;
256 resultNames, modResultNames, results, resolvedModResultTypesRef,
261 auto modParameters =
module->getAttrOfType<ArrayAttr>("parameters");
262 SmallVector<Type> rawModParameters, resolvedModParameters;
263 rawModParameters.reserve(modParameters.size());
264 resolvedModParameters.reserve(modParameters.size());
265 for (
auto paramDecl : modParameters.getAsRange<ParamDeclAttr>())
266 rawModParameters.push_back(paramDecl.getType());
270 instance->getLoc(), parameters, rawModParameters,
271 resolvedModParameters, emitError)))
276 parameters, modParameters, resolvedModParameters, emitError)))
285 ArrayAttr moduleParameters,
289 for (
auto param : parameters) {
290 auto paramAttr = cast<ParamDeclAttr>(param);
291 auto value = paramAttr.getValue();
297 auto typedValue = dyn_cast<mlir::TypedAttr>(value);
299 emitError([&](
auto &diag) {
300 diag <<
"parameter " << paramAttr
301 <<
" should have a typed value; has value " << value;
307 if (typedValue.getType() != paramAttr.getType()) {
308 emitError([&](
auto &diag) {
309 diag <<
"parameter " << paramAttr <<
" should have type "
310 << paramAttr.getType() <<
"; has type " << typedValue.getType();
324 if (names && idx < names.size())
325 return cast<StringAttr>(names[idx]);
331 SmallVector<Attribute> newNames(oldNames.begin(), oldNames.end());
332 if (newNames[i] == name)
335 return ArrayAttr::get(oldNames.getContext(), oldNames);
339 StringRef instanceName,
340 ArrayAttr resultNames,
341 ValueRange results) {
343 std::string name = instanceName.str() +
".";
344 size_t baseNameLen = name.size();
346 for (
size_t i = 0, e = resultNames.size(); i != e; ++i) {
347 auto resName =
getName(resultNames, i);
348 name.resize(baseNameLen);
349 if (resName && !resName.getValue().empty())
350 name += resName.getValue().str();
352 name += std::to_string(i);
353 setNameFn(results[i], name);
360 SmallVector<PortInfo> ports;
361 auto emptyDict = DictionaryAttr::get(instanceOp->getContext());
362 auto argNames = instanceOp->getAttrOfType<ArrayAttr>(
"argNames");
363 auto argTypes = moduleTy.getInputs();
364 auto argLocs = instanceOp->getAttrOfType<ArrayAttr>(
"argLocs");
366 auto resultNames = instanceOp->getAttrOfType<ArrayAttr>(
"resultNames");
367 auto resultTypes = moduleTy.getResults();
368 auto resultLocs = instanceOp->getAttrOfType<ArrayAttr>(
"resultLocs");
370 ports.reserve(argTypes.size() + resultTypes.size());
371 for (
unsigned i = 0, e = argTypes.size(); i < e; ++i) {
372 auto type = argTypes[i];
373 auto direction = ModulePort::Direction::Input;
375 if (
auto inout = dyn_cast<InOutType>(type)) {
376 type = inout.getElementType();
377 direction = ModulePort::Direction::InOut;
382 loc = cast<LocationAttr>(argLocs[i]);
384 {{cast<StringAttr>(argNames[i]), type, direction}, i, emptyDict, loc});
387 for (
unsigned i = 0, e = resultTypes.size(); i < e; ++i) {
390 loc = cast<LocationAttr>(resultLocs[i]);
391 ports.push_back({{cast<StringAttr>(resultNames[i]), resultTypes[i],
392 ModulePort::Direction::Output},
LogicalResult verifyParameterStructure(ArrayAttr parameters, ArrayAttr moduleParameters, const EmitErrorFn &emitError)
Check that all the parameter values specified to the instance are structurally valid.
std::function< void(std::function< bool(InFlightDiagnostic &)>)> EmitErrorFn
Whenever the nested function returns true, a note referring to the referenced module is attached to t...
LogicalResult verifyOutputs(ArrayAttr resultNames, ArrayAttr moduleResultNames, TypeRange resultTypes, ArrayRef< Type > moduleResultTypes, const EmitErrorFn &emitError)
Verify that the list of outputs of the instance and the module match in terms of length,...
LogicalResult verifyInstanceOfHWModule(Operation *instance, FlatSymbolRefAttr moduleRef, OperandRange inputs, TypeRange results, ArrayAttr argNames, ArrayAttr resultNames, ArrayAttr parameters, SymbolTableCollection &symbolTable)
Combines verifyReferencedModule, verifyInputs, verifyOutputs, and verifyParameters.
SmallVector< PortInfo > getPortList(Operation *instanceOp)
Return the port list of an instance, based on the name, type and location attributes present on the i...
StringAttr getName(ArrayAttr names, size_t idx)
Return the name at the specified index of the ArrayAttr or null if it cannot be determined.
LogicalResult resolveParametricTypes(Location loc, ArrayAttr parameters, ArrayRef< Type > types, SmallVectorImpl< Type > &resolvedTypes, const EmitErrorFn &emitError)
Stores a resolved version of each type in.
LogicalResult verifyInputs(ArrayAttr argNames, ArrayAttr moduleArgNames, TypeRange inputTypes, ArrayRef< Type > moduleInputTypes, const EmitErrorFn &emitError)
Verify that the list of inputs of the instance and the module match in terms of length,...
LogicalResult verifyParameters(ArrayAttr parameters, ArrayAttr moduleParameters, ArrayRef< Type > resolvedModParametersRefs, const EmitErrorFn &emitError)
Verify that the parameter lists of the instance and the module match in terms of length,...
ArrayAttr updateName(ArrayAttr oldNames, size_t i, StringAttr name)
Change the name at the specified index of the.
LogicalResult verifyReferencedModule(Operation *instanceOp, SymbolTableCollection &symbolTable, mlir::FlatSymbolRefAttr moduleName, Operation *&module)
Verify that the instance refers to a valid HW module.
void getAsmResultNames(OpAsmSetValueNameFn setNameFn, StringRef instanceName, ArrayAttr resultNames, ValueRange results)
Suggest a name for each result value based on the saved result names attribute.
FunctionType getModuleType(Operation *module)
Return the signature for the specified module as a function type.
LogicalResult checkParameterInContext(Attribute value, Operation *module, Operation *usingOp, bool disallowParamRefs=false)
Check parameter specified by value to see if it is valid within the scope of the specified module mod...
mlir::FailureOr< mlir::Type > evaluateParametricType(mlir::Location loc, mlir::ArrayAttr parameters, mlir::Type type, bool emitErrors=true)
Returns a resolved version of 'type' wherein any parameter reference has been evaluated based on the ...
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.