22#define GEN_PASS_DEF_SCFFORLOOPRANGEFOLDING
23#include "mlir/Dialect/SCF/Transforms/Passes.h.inc"
30struct ForLoopRangeFolding
32 void runOnOperation()
override;
36void ForLoopRangeFolding::runOnOperation() {
37 getOperation()->walk([&](ForOp op) {
38 Value indVar = op.getInductionVar();
40 auto canBeFolded = [&](Value value) {
41 return op.isDefinedOutsideOfLoop(value) || value == indVar;
52 Operation *user = *indVar.
getUsers().begin();
53 if (!isa<arith::AddIOp, arith::MulIOp>(user))
56 if (!llvm::all_of(user->
getOperands(), canBeFolded))
61 lbMap.
map(indVar, op.getLowerBound());
63 ubMap.
map(indVar, op.getUpperBound());
65 stepMap.
map(indVar, op.getStep());
67 if (isa<arith::AddIOp>(user)) {
68 Operation *lbFold =
b.clone(*user, lbMap);
69 Operation *ubFold =
b.clone(*user, ubMap);
74 }
else if (isa<arith::MulIOp>(user)) {
75 Operation *lbFold =
b.
clone(*user, lbMap);
76 Operation *ubFold =
b.
clone(*user, ubMap);
77 Operation *stepFold =
b.
clone(*user, stepMap);
92 return std::make_unique<ForLoopRangeFolding>();
void map(Value from, Value to)
Inserts a new mapping for 'from' to 'to'.
Operation * clone(IRMapping &mapper, CloneOptions options=CloneOptions::all())
Create a deep copy of this operation, remapping any operands that use values outside of the operation...
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
operand_range getOperands()
Returns an iterator on the underlying Value's.
void replaceAllUsesWith(ValuesT &&values)
Replace all uses of results of this operation with the provided 'values'.
void erase()
Remove this operation from its parent block and delete it.
user_range getUsers() const
bool hasOneUse() const
Returns true if this value has exactly one use.
Include the generated interface declarations.
std::unique_ptr< Pass > createForLoopRangeFoldingPass()
Creates a pass which folds arith ops on induction variable into loop range.