33 FunctionOpInterface func2) {
35 assert(func1->getParentOp() == func2->getParentOp() &&
36 "expected func1 and func2 to be in the same parent op");
39 if (func1.getFunctionType() != func2.getFunctionType()) {
40 return func1.emitError()
41 <<
"external definition has a mismatching signature ("
42 << func2.getFunctionType() <<
")";
48 StringAttr consumedName = td->getConsumedAttrName();
49 StringAttr readOnlyName = td->getReadOnlyAttrName();
50 for (
unsigned i = 0, e = func1.getNumArguments(); i < e; ++i) {
51 bool isExternalConsumed = func2.getArgAttr(i, consumedName) !=
nullptr;
52 bool isExternalReadonly = func2.getArgAttr(i, readOnlyName) !=
nullptr;
53 bool isConsumed = func1.getArgAttr(i, consumedName) !=
nullptr;
54 bool isReadonly = func1.getArgAttr(i, readOnlyName) !=
nullptr;
55 if (!isExternalConsumed && !isExternalReadonly) {
57 func2.setArgAttr(i, consumedName, UnitAttr::get(context));
59 func2.setArgAttr(i, readOnlyName, UnitAttr::get(context));
63 if ((isExternalConsumed && !isConsumed) ||
64 (isExternalReadonly && !isReadonly)) {
65 return func1.emitError()
66 <<
"external definition has mismatching consumption "
67 "annotations for argument #"
73 assert(func1.isExternal());
83 "requires target to implement the 'SymbolTable' trait");
85 "requires target to implement the 'SymbolTable' trait");
94 LDBG() <<
"renaming private symbols to resolve conflicts:";
96 for (
auto &&[symbolTable, otherSymbolTable] : llvm::zip(
99 &targetSymbolTable})) {
100 Operation *symbolTableOp = symbolTable->getOp();
102 auto symbolOp = dyn_cast<SymbolOpInterface>(op);
105 StringAttr name = symbolOp.getNameAttr();
106 LDBG() <<
" found @" << name.getValue();
110 cast_or_null<SymbolOpInterface>(otherSymbolTable->
lookup(name));
114 LDBG() <<
" collision found for @" << name.getValue();
117 if (
auto funcOp = dyn_cast<FunctionOpInterface>(op),
119 dyn_cast<FunctionOpInterface>(collidingOp.getOperation());
120 funcOp && collidingFuncOp) {
123 LDBG() <<
" but both ops are functions and will be merged";
128 LDBG() <<
" and both ops are function definitions";
132 auto renameToUnique =
133 [&](SymbolOpInterface op, SymbolOpInterface otherOp,
136 LDBG() <<
", renaming";
137 FailureOr<StringAttr> maybeNewName =
138 symbolTable.renameToUnique(op, {&otherSymbolTable});
139 if (failed(maybeNewName)) {
141 diag.attachNote(otherOp->getLoc())
142 <<
"attempted renaming due to collision with this op";
145 LDBG() <<
" renamed to @" << maybeNewName->getValue();
149 if (symbolOp.isPrivate()) {
151 symbolOp, collidingOp, *symbolTable, *otherSymbolTable);
156 if (collidingOp.isPrivate()) {
158 collidingOp, symbolOp, *otherSymbolTable, *symbolTable);
163 LDBG() <<
", emitting error";
165 <<
"doubly defined symbol @" << name.getValue();
166 diag.attachNote(collidingOp->getLoc()) <<
"previously defined here";
175 return op->emitError()
176 <<
"failed to verify symbol table after symbol renaming";
182 LDBG() <<
"moving all symbols into target";
185 for (
Operation &op : other->getRegion(0).front()) {
186 if (
auto symbol = dyn_cast<SymbolOpInterface>(op))
187 opsToMove.push_back(symbol);
190 for (SymbolOpInterface op : opsToMove) {
192 auto collidingOp = cast_or_null<SymbolOpInterface>(
193 targetSymbolTable.
lookup(op.getNameAttr()));
196 LDBG() <<
" moving @" << op.getName();
197 op->moveBefore(&
target->getRegion(0).front(),
198 target->getRegion(0).front().end());
202 LDBG() <<
" without collision";
208 auto funcOp = cast<FunctionOpInterface>(op.getOperation());
209 auto collidingFuncOp =
210 cast<FunctionOpInterface>(collidingOp.getOperation());
216 std::swap(funcOp, collidingFuncOp);
220 LDBG() <<
" with collision, trying to keep op at "
221 << collidingFuncOp.getLoc() <<
":\n"
225 targetSymbolTable.
remove(funcOp);
226 targetSymbolTable.
insert(collidingFuncOp);
227 assert(targetSymbolTable.
lookup(funcOp.getName()) == collidingFuncOp);
242 return target->emitError()
243 <<
"failed to verify target op after merging symbols";
245 LDBG() <<
"done merging ops";
MLIRContext is the top-level object for a collection of MLIR operations.
Dialect * getLoadedDialect(StringRef name)
Get a registered IR dialect with the given namespace.
LogicalResult verify(Operation *op, bool verifyRecursively=true)
Perform (potentially expensive) checks of invariants, used to detect compiler bugs,...