@@ -35,52 +35,77 @@ int getOperandNumber(Operation* op, Value value) {
3535 return -1 ;
3636}
3737
38- Attribute findAttributeForBlockArgument (BlockArgument blockArg,
39- StringRef attrName) {
38+ struct BlockArgAttrTarget {
39+ enum class Kind { None, FunctionArg, OperandAttr } kind = Kind::None;
40+ FunctionOpInterface funcOp = nullptr ;
41+ OperandAndResultAttrInterface operandAttrOp = nullptr ;
42+ int index = -1 ;
43+ };
44+
45+ static BlockArgAttrTarget resolveBlockArgAttrTarget (BlockArgument blockArg) {
4046 auto * parentOp = blockArg.getOwner ()->getParentOp ();
4147 assert (parentOp != nullptr &&
4248 " Missing parent op! Was this value not properly remapped?" );
4349
44- return llvm::TypeSwitch<Operation*, Attribute>(parentOp)
45- .Case <FunctionOpInterface>([&](auto op) -> Attribute {
46- return op.getArgAttr (blockArg.getArgNumber (), attrName);
50+ return llvm::TypeSwitch<Operation*, BlockArgAttrTarget>(parentOp)
51+ .Case <FunctionOpInterface>([&](FunctionOpInterface op) {
52+ return BlockArgAttrTarget{BlockArgAttrTarget::Kind::FunctionArg, op,
53+ nullptr ,
54+ static_cast <int >(blockArg.getArgNumber ())};
4755 })
4856 // AffineForOp needs a special case because its operands do not
4957 // line up perfectly with its block arguments.
5058 // This could be potentially improved by adding an interface method to
5159 // OperandAndResultAttrInterface to map from block arguments to operands
52- .Case <affine::AffineForOp>([&](affine::AffineForOp op) -> Attribute {
60+ .Case <affine::AffineForOp>([&](affine::AffineForOp op) {
5361 // For op has as its first block argument the induction
5462 // variable, which does not correspond to a single operand.
55- if (blockArg.getArgNumber () == 0 ) return nullptr ;
63+ if (blockArg.getArgNumber () == 0 ) return BlockArgAttrTarget{} ;
5664
5765 auto argAttrInterface = cast<OperandAndResultAttrInterface>(*op);
5866 auto initArg = op.getInits ()[blockArg.getArgNumber () - 1 ];
5967 int operandNumber = getOperandNumber (op, initArg);
60- if (operandNumber == -1 ) return nullptr ;
61- return argAttrInterface.getOperandAttr (operandNumber, attrName);
68+ if (operandNumber == -1 ) return BlockArgAttrTarget{};
69+ return BlockArgAttrTarget{BlockArgAttrTarget::Kind::OperandAttr,
70+ nullptr , argAttrInterface, operandNumber};
6271 })
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- })
80- .Case <OperandAndResultAttrInterface>([&](auto op) -> Attribute {
81- return op.getOperandAttr (blockArg.getArgNumber (), attrName);
72+ .Case <RegionBranchOpInterface>([&](RegionBranchOpInterface op) {
73+ auto argAttrInterface =
74+ dyn_cast<OperandAndResultAttrInterface>(op.getOperation ());
75+ if (!argAttrInterface) return BlockArgAttrTarget{};
76+
77+ RegionBranchSuccessorMapping mapping;
78+ op.getSuccessorOperandInputMapping (mapping,
79+ RegionBranchPoint::parent ());
80+ auto inverseMapping = invertRegionBranchSuccessorMapping (mapping);
81+ if (inverseMapping.count (blockArg)) {
82+ return BlockArgAttrTarget{
83+ BlockArgAttrTarget::Kind::OperandAttr, nullptr , argAttrInterface,
84+ static_cast <int >(
85+ inverseMapping.lookup (blockArg)[0 ]->getOperandNumber ())};
86+ }
87+ return BlockArgAttrTarget{};
8288 })
83- .Default ([](Operation* op) { return nullptr ; });
89+ .Case <OperandAndResultAttrInterface>(
90+ [&](OperandAndResultAttrInterface op) {
91+ return BlockArgAttrTarget{
92+ BlockArgAttrTarget::Kind::OperandAttr, nullptr , op,
93+ static_cast <int >(blockArg.getArgNumber ())};
94+ })
95+ .Default ([](Operation* op) { return BlockArgAttrTarget{}; });
96+ }
97+
98+ Attribute findAttributeForBlockArgument (BlockArgument blockArg,
99+ StringRef attrName) {
100+ BlockArgAttrTarget target = resolveBlockArgAttrTarget (blockArg);
101+ switch (target.kind ) {
102+ case BlockArgAttrTarget::Kind::FunctionArg:
103+ return target.funcOp .getArgAttr (target.index , attrName);
104+ case BlockArgAttrTarget::Kind::OperandAttr:
105+ return target.operandAttrOp .getOperandAttr (target.index , attrName);
106+ case BlockArgAttrTarget::Kind::None:
107+ return nullptr ;
108+ }
84109}
85110
86111Attribute getUndistinguishedResultAttr (Operation* op, int resultNumber,
@@ -150,43 +175,17 @@ FailureOr<Attribute> findAttributeAssociatedWith(Value value,
150175
151176void setAttributeForBlockArgument (BlockArgument blockArg, StringRef attrName,
152177 Attribute attr) {
153- auto * parentOp = blockArg.getOwner ()->getParentOp ();
154- assert (parentOp != nullptr &&
155- " Missing parent op! Was this value not properly remapped?" );
156-
157- llvm::TypeSwitch<Operation*>(parentOp)
158- .Case <FunctionOpInterface>([&](auto op) {
159- return op.setArgAttr (blockArg.getArgNumber (), attrName, attr);
160- })
161- .Case <affine::AffineForOp>([&](affine::AffineForOp op) {
162- // For op has as its first block argument the induction
163- // variable, which does not correspond to a single operand.
164- if (blockArg.getArgNumber () == 0 ) return ;
165-
166- auto argAttrInterface = cast<OperandAndResultAttrInterface>(*op);
167- auto initArg = op.getInits ()[blockArg.getArgNumber () - 1 ];
168- int operandNumber = getOperandNumber (op, initArg);
169- if (operandNumber == -1 ) return ;
170- return argAttrInterface.setOperandAttr (operandNumber, attrName, attr);
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- })
187- .Case <OperandAndResultAttrInterface>([&](auto op) {
188- return op.setOperandAttr (blockArg.getArgNumber (), attrName, attr);
189- });
178+ BlockArgAttrTarget target = resolveBlockArgAttrTarget (blockArg);
179+ switch (target.kind ) {
180+ case BlockArgAttrTarget::Kind::FunctionArg:
181+ target.funcOp .setArgAttr (target.index , attrName, attr);
182+ return ;
183+ case BlockArgAttrTarget::Kind::OperandAttr:
184+ target.operandAttrOp .setOperandAttr (target.index , attrName, attr);
185+ return ;
186+ case BlockArgAttrTarget::Kind::None:
187+ return ;
188+ }
190189}
191190
192191void setAttributeForResult (Value result, StringRef attrName, Attribute attr) {
@@ -240,39 +239,17 @@ void setAttributeAssociatedWith(Value value, StringRef attrName,
240239
241240static void removeAttributeForBlockArgument (BlockArgument blockArg,
242241 StringRef attrName) {
243- auto * parentOp = blockArg.getOwner ()->getParentOp ();
244- assert (parentOp != nullptr &&
245- " Missing parent op! Was this value not properly remapped?" );
246-
247- llvm::TypeSwitch<Operation*>(parentOp)
248- .Case <FunctionOpInterface>(
249- [&](auto op) { op.removeArgAttr (blockArg.getArgNumber (), attrName); })
250- .Case <affine::AffineForOp>([&](affine::AffineForOp op) {
251- if (blockArg.getArgNumber () == 0 ) return ;
252-
253- auto argAttrInterface = cast<OperandAndResultAttrInterface>(*op);
254- auto initArg = op.getInits ()[blockArg.getArgNumber () - 1 ];
255- int operandNumber = getOperandNumber (op, initArg);
256- if (operandNumber == -1 ) return ;
257- argAttrInterface.removeOperandAttr (operandNumber, attrName);
258- })
259- .Case <RegionBranchOpInterface>([&](RegionBranchOpInterface op) {
260- auto argAttrInterface =
261- dyn_cast<OperandAndResultAttrInterface>(op.getOperation ());
262- if (!argAttrInterface) return ;
263-
264- RegionBranchSuccessorMapping mapping;
265- op.getSuccessorOperandInputMapping (mapping,
266- RegionBranchPoint::parent ());
267- auto inverseMapping = invertRegionBranchSuccessorMapping (mapping);
268- if (inverseMapping.count (blockArg)) {
269- argAttrInterface.removeOperandAttr (
270- inverseMapping.lookup (blockArg)[0 ]->getOperandNumber (), attrName);
271- }
272- })
273- .Case <OperandAndResultAttrInterface>([&](auto op) {
274- op.removeOperandAttr (blockArg.getArgNumber (), attrName);
275- });
242+ BlockArgAttrTarget target = resolveBlockArgAttrTarget (blockArg);
243+ switch (target.kind ) {
244+ case BlockArgAttrTarget::Kind::FunctionArg:
245+ target.funcOp .removeArgAttr (target.index , attrName);
246+ return ;
247+ case BlockArgAttrTarget::Kind::OperandAttr:
248+ target.operandAttrOp .removeOperandAttr (target.index , attrName);
249+ return ;
250+ case BlockArgAttrTarget::Kind::None:
251+ return ;
252+ }
276253}
277254
278255static void removeAttributeForResult (Value result, StringRef attrName) {
0 commit comments