23#define GEN_PASS_DEF_SCFFORLOOPRANGEFOLDING
24#include "mlir/Dialect/SCF/Transforms/Passes.h.inc"
31struct ForLoopRangeFolding
32 :
public impl::SCFForLoopRangeFoldingBase<ForLoopRangeFolding> {
33 void runOnOperation()
override;
37void ForLoopRangeFolding::runOnOperation() {
38 getOperation()->walk([&](ForOp op) {
39 Value indVar = op.getInductionVar();
41 auto canBeFolded = [&](Value value) {
42 return op.isDefinedOutsideOfLoop(value) || value == indVar;
53 Operation *user = *indVar.
getUsers().begin();
54 if (!isa<arith::AddIOp, arith::MulIOp>(user))
57 if (!llvm::all_of(user->
getOperands(), canBeFolded))
62 lbMap.
map(indVar, op.getLowerBound());
64 ubMap.
map(indVar, op.getUpperBound());
66 stepMap.
map(indVar, op.getStep());
68 if (isa<arith::AddIOp>(user)) {
69 Operation *lbFold =
b.clone(*user, lbMap);
70 Operation *ubFold =
b.clone(*user, ubMap);
75 }
else if (
auto mulOp = dyn_cast<arith::MulIOp>(user)) {
80 (mulOp.getLhs() == indVar) ? mulOp.getRhs() : mulOp.getLhs();
82 if (!multiplierVal || *multiplierVal <= 0)
85 Operation *lbFold =
b.
clone(*user, lbMap);
86 Operation *ubFold =
b.
clone(*user, ubMap);
87 Operation *stepFold =
b.
clone(*user, stepMap);
102 return std::make_unique<ForLoopRangeFolding>();
void map(Value from, Value to)
Inserts a new mapping for 'from' to 'to'.
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'.
Operation * clone(IRMapping &mapper, const CloneOptions &options=CloneOptions::all())
Create a deep copy of this operation, remapping any operands that use values outside of the operation...
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::optional< int64_t > getConstantIntValue(OpFoldResult ofr)
If ofr is a constant integer or an IntegerAttr, return the integer.
std::unique_ptr< Pass > createForLoopRangeFoldingPass()
Creates a pass which folds arith ops on induction variable into loop range.