|
11 | 11 | #include "mlir/include/mlir/IR/BuiltinAttributes.h" // from @llvm-project |
12 | 12 | #include "mlir/include/mlir/IR/Value.h" // from @llvm-project |
13 | 13 | #include "mlir/include/mlir/IR/Visitors.h" // from @llvm-project |
| 14 | +#include "mlir/include/mlir/Interfaces/ControlFlowInterfaces.h" // from @llvm-project |
14 | 15 | #include "mlir/include/mlir/Interfaces/FunctionInterfaces.h" // from @llvm-project |
15 | 16 | #include "mlir/include/mlir/Support/LLVM.h" // from @llvm-project |
16 | 17 |
|
17 | 18 | namespace mlir { |
18 | 19 | namespace heir { |
19 | 20 |
|
| 21 | +// https://discourse.llvm.org/t/regionbranchopinterface-agnostically-connect-a-region-block-argument-to-parent-opoperand/90199 |
| 22 | +static RegionBranchInverseSuccessorMapping invertRegionBranchSuccessorMapping( |
| 23 | + const RegionBranchSuccessorMapping& operandToInputs) { |
| 24 | + RegionBranchInverseSuccessorMapping inputToOperands; |
| 25 | + for (const auto& [operand, inputs] : operandToInputs) { |
| 26 | + for (Value input : inputs) inputToOperands[input].push_back(operand); |
| 27 | + } |
| 28 | + return inputToOperands; |
| 29 | +} |
| 30 | + |
20 | 31 | int getOperandNumber(Operation* op, Value value) { |
21 | 32 | for (OpOperand& operand : op->getOpOperands()) { |
22 | 33 | if (operand.get() == value) return operand.getOperandNumber(); |
@@ -49,6 +60,23 @@ Attribute findAttributeForBlockArgument(BlockArgument blockArg, |
49 | 60 | if (operandNumber == -1) return nullptr; |
50 | 61 | return argAttrInterface.getOperandAttr(operandNumber, attrName); |
51 | 62 | }) |
| 63 | + .Case<RegionBranchOpInterface>( |
| 64 | + [&](RegionBranchOpInterface op) -> Attribute { |
| 65 | + auto argAttrInterface = |
| 66 | + dyn_cast<OperandAndResultAttrInterface>(op.getOperation()); |
| 67 | + if (!argAttrInterface) return nullptr; |
| 68 | + |
| 69 | + RegionBranchSuccessorMapping mapping; |
| 70 | + op.getSuccessorOperandInputMapping(mapping, |
| 71 | + RegionBranchPoint::parent()); |
| 72 | + auto inverseMapping = invertRegionBranchSuccessorMapping(mapping); |
| 73 | + if (inverseMapping.count(blockArg)) { |
| 74 | + return argAttrInterface.getOperandAttr( |
| 75 | + inverseMapping.lookup(blockArg)[0]->getOperandNumber(), |
| 76 | + attrName); |
| 77 | + } |
| 78 | + return nullptr; |
| 79 | + }) |
52 | 80 | .Case<OperandAndResultAttrInterface>([&](auto op) -> Attribute { |
53 | 81 | return op.getOperandAttr(blockArg.getArgNumber(), attrName); |
54 | 82 | }) |
@@ -141,6 +169,21 @@ void setAttributeForBlockArgument(BlockArgument blockArg, StringRef attrName, |
141 | 169 | if (operandNumber == -1) return; |
142 | 170 | return argAttrInterface.setOperandAttr(operandNumber, attrName, attr); |
143 | 171 | }) |
| 172 | + .Case<RegionBranchOpInterface>([&](RegionBranchOpInterface op) { |
| 173 | + auto argAttrInterface = |
| 174 | + dyn_cast<OperandAndResultAttrInterface>(op.getOperation()); |
| 175 | + if (!argAttrInterface) return; |
| 176 | + |
| 177 | + RegionBranchSuccessorMapping mapping; |
| 178 | + op.getSuccessorOperandInputMapping(mapping, |
| 179 | + RegionBranchPoint::parent()); |
| 180 | + auto inverseMapping = invertRegionBranchSuccessorMapping(mapping); |
| 181 | + if (inverseMapping.count(blockArg)) { |
| 182 | + return argAttrInterface.setOperandAttr( |
| 183 | + inverseMapping.lookup(blockArg)[0]->getOperandNumber(), attrName, |
| 184 | + attr); |
| 185 | + } |
| 186 | + }) |
144 | 187 | .Case<OperandAndResultAttrInterface>([&](auto op) { |
145 | 188 | return op.setOperandAttr(blockArg.getArgNumber(), attrName, attr); |
146 | 189 | }); |
|
0 commit comments