[PATCH] D142680: [ConstFolding] Modified algorithm of `ConstantFoldConstantImpl` to be iterative
Kolya Panchenko via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 26 17:46:01 PST 2023
nikolaypanchenko created this revision.
Herald added a subscriber: hiraditya.
Herald added a project: All.
nikolaypanchenko added a reviewer: arsenm.
nikolaypanchenko published this revision for review.
Herald added subscribers: llvm-commits, wdng.
Herald added a project: LLVM.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D142680
Files:
llvm/lib/Analysis/ConstantFolding.cpp
Index: llvm/lib/Analysis/ConstantFolding.cpp
===================================================================
--- llvm/lib/Analysis/ConstantFolding.cpp
+++ llvm/lib/Analysis/ConstantFolding.cpp
@@ -1121,36 +1121,58 @@
ConstantFoldConstantImpl(const Constant *C, const DataLayout &DL,
const TargetLibraryInfo *TLI,
SmallDenseMap<Constant *, Constant *> &FoldedOps) {
- if (!isa<ConstantVector>(C) && !isa<ConstantExpr>(C))
- return const_cast<Constant *>(C);
+ SmallVector<Constant *> Worklist = {const_cast<Constant *>(C)};
+
+ // "Recursively" iterate over all users of the constant. Try to fold constant
+ // if all its operand were processed before.
+ while (!Worklist.empty()) {
+ Constant *CurrentC = Worklist.back();
+ if (FoldedOps.count(CurrentC)) {
+ Worklist.pop_back();
+ continue;
+ }
- SmallVector<Constant *, 8> Ops;
- for (const Use &OldU : C->operands()) {
- Constant *OldC = cast<Constant>(&OldU);
- Constant *NewC = OldC;
- // Recursively fold the ConstantExpr's operands. If we have already folded
- // a ConstantExpr, we don't have to process it again.
- if (isa<ConstantVector>(OldC) || isa<ConstantExpr>(OldC)) {
- auto It = FoldedOps.find(OldC);
- if (It == FoldedOps.end()) {
- NewC = ConstantFoldConstantImpl(OldC, DL, TLI, FoldedOps);
- FoldedOps.insert({OldC, NewC});
- } else {
- NewC = It->second;
+ if (!isa<ConstantVector>(CurrentC) && !isa<ConstantExpr>(CurrentC)) {
+ Worklist.pop_back();
+ FoldedOps.try_emplace(CurrentC, CurrentC);
+ continue;
+ }
+
+ SmallVector<Constant *, 8> Ops;
+ for (const Use &U : CurrentC->operands()) {
+ Constant *OldC = cast<Constant>(&U);
+ Constant *NewC = OldC;
+ if (isa<ConstantVector>(OldC) || isa<ConstantExpr>(OldC)) {
+ auto It = FoldedOps.find(OldC);
+ if (It == FoldedOps.end()) {
+ NewC = nullptr;
+ Worklist.push_back(OldC);
+ } else {
+ NewC = It->second;
+ }
}
+ if (NewC)
+ Ops.push_back(NewC);
}
- Ops.push_back(NewC);
- }
- if (auto *CE = dyn_cast<ConstantExpr>(C)) {
- if (Constant *Res =
- ConstantFoldInstOperandsImpl(CE, CE->getOpcode(), Ops, DL, TLI))
- return Res;
- return const_cast<Constant *>(C);
- }
+ // If all operands of the constant were processed, try to fold them
+ if (Ops.size() == CurrentC->getNumOperands()) {
+ assert(Worklist.back() == CurrentC &&
+ "Some operand of the Constant was added to the Worklist.");
+ Worklist.pop_back();
- assert(isa<ConstantVector>(C));
- return ConstantVector::get(Ops);
+ if (auto *CE = dyn_cast<ConstantExpr>(CurrentC)) {
+ if (Constant *Res =
+ ConstantFoldInstOperandsImpl(CE, CE->getOpcode(), Ops, DL, TLI))
+ FoldedOps.try_emplace(CurrentC, Res);
+ else
+ FoldedOps.try_emplace(CurrentC, CurrentC);
+ } else {
+ FoldedOps.try_emplace(CurrentC, ConstantVector::get(Ops));
+ }
+ }
+ }
+ return FoldedOps.find(C)->second;
}
} // end anonymous namespace
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D142680.492615.patch
Type: text/x-patch
Size: 3191 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230127/281a22ee/attachment.bin>
More information about the llvm-commits
mailing list