[llvm] [DFAJumpThreading] Avoid exploring the paths that never come back (PR #85505)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Mar 16 01:02:53 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: XChy (XChy)
<details>
<summary>Changes</summary>
This patch does:
- Preserve loop info when unfolding selects.
- Reduce the search space for loop paths.
---
Full diff: https://github.com/llvm/llvm-project/pull/85505.diff
1 Files Affected:
- (modified) llvm/lib/Transforms/Scalar/DFAJumpThreading.cpp (+21-7)
``````````diff
diff --git a/llvm/lib/Transforms/Scalar/DFAJumpThreading.cpp b/llvm/lib/Transforms/Scalar/DFAJumpThreading.cpp
index e66a1a2ccb318c..d359b701646722 100644
--- a/llvm/lib/Transforms/Scalar/DFAJumpThreading.cpp
+++ b/llvm/lib/Transforms/Scalar/DFAJumpThreading.cpp
@@ -126,7 +126,7 @@ class SelectInstToUnfold {
explicit operator bool() const { return SI && SIUse; }
};
-void unfold(DomTreeUpdater *DTU, SelectInstToUnfold SIToUnfold,
+void unfold(DomTreeUpdater *DTU, LoopInfo *LI, SelectInstToUnfold SIToUnfold,
std::vector<SelectInstToUnfold> *NewSIsToUnfold,
std::vector<BasicBlock *> *NewBBs);
@@ -152,7 +152,7 @@ class DFAJumpThreading {
std::vector<SelectInstToUnfold> NewSIsToUnfold;
std::vector<BasicBlock *> NewBBs;
- unfold(&DTU, SIToUnfold, &NewSIsToUnfold, &NewBBs);
+ unfold(&DTU, LI, SIToUnfold, &NewSIsToUnfold, &NewBBs);
// Put newly discovered select instructions into the work list.
for (const SelectInstToUnfold &NewSIToUnfold : NewSIsToUnfold)
@@ -196,7 +196,7 @@ void createBasicBlockAndSinkSelectInst(
/// created basic blocks into \p NewBBs.
///
/// TODO: merge it with CodeGenPrepare::optimizeSelectInst() if possible.
-void unfold(DomTreeUpdater *DTU, SelectInstToUnfold SIToUnfold,
+void unfold(DomTreeUpdater *DTU, LoopInfo *LI, SelectInstToUnfold SIToUnfold,
std::vector<SelectInstToUnfold> *NewSIsToUnfold,
std::vector<BasicBlock *> *NewBBs) {
SelectInst *SI = SIToUnfold.getInst();
@@ -302,6 +302,12 @@ void unfold(DomTreeUpdater *DTU, SelectInstToUnfold SIToUnfold,
DTU->applyUpdates({{DominatorTree::Insert, StartBlock, TT},
{DominatorTree::Insert, StartBlock, FT}});
+ // Preserve loop info
+ if (Loop *L = LI->getLoopFor(SI->getParent())) {
+ for (BasicBlock *NewBB : *NewBBs)
+ L->addBasicBlockToLoop(NewBB, *LI);
+ }
+
// The select is now dead.
assert(SI->use_empty() && "Select must be dead now");
SI->eraseFromParent();
@@ -501,9 +507,10 @@ struct MainSwitch {
};
struct AllSwitchPaths {
- AllSwitchPaths(const MainSwitch *MSwitch, OptimizationRemarkEmitter *ORE)
- : Switch(MSwitch->getInstr()), SwitchBlock(Switch->getParent()),
- ORE(ORE) {}
+ AllSwitchPaths(const MainSwitch *MSwitch, OptimizationRemarkEmitter *ORE,
+ LoopInfo *LI)
+ : Switch(MSwitch->getInstr()), SwitchBlock(Switch->getParent()), ORE(ORE),
+ LI(LI) {}
std::vector<ThreadingPath> &getThreadingPaths() { return TPaths; }
unsigned getNumThreadingPaths() { return TPaths.size(); }
@@ -575,6 +582,12 @@ struct AllSwitchPaths {
Visited.insert(BB);
+ // Stop if we have reached the BB out of loop, since its successors have no
+ // impact on the DFA.
+ // TODO: Do we need to stop exploring if BB is the outer loop of the switch?
+ if (!LI->getLoopFor(BB))
+ return Res;
+
// Some blocks have multiple edges to the same successor, and this set
// is used to prevent a duplicate path from being generated
SmallSet<BasicBlock *, 4> Successors;
@@ -716,6 +729,7 @@ struct AllSwitchPaths {
BasicBlock *SwitchBlock;
OptimizationRemarkEmitter *ORE;
std::vector<ThreadingPath> TPaths;
+ LoopInfo *LI;
};
struct TransformDFA {
@@ -1283,7 +1297,7 @@ bool DFAJumpThreading::run(Function &F) {
if (!Switch.getSelectInsts().empty())
MadeChanges = true;
- AllSwitchPaths SwitchPaths(&Switch, ORE);
+ AllSwitchPaths SwitchPaths(&Switch, ORE, LI);
SwitchPaths.run();
if (SwitchPaths.getNumThreadingPaths() > 0) {
``````````
</details>
https://github.com/llvm/llvm-project/pull/85505
More information about the llvm-commits
mailing list