Skip to content

Commit 35bc0a3

Browse files
committed
[DFAJumpThreading] Avoid exploring the paths that never come back
1 parent 402f15e commit 35bc0a3

File tree

1 file changed

+21
-7
lines changed

1 file changed

+21
-7
lines changed

llvm/lib/Transforms/Scalar/DFAJumpThreading.cpp

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ class SelectInstToUnfold {
131131
explicit operator bool() const { return SI && SIUse; }
132132
};
133133

134-
void unfold(DomTreeUpdater *DTU, SelectInstToUnfold SIToUnfold,
134+
void unfold(DomTreeUpdater *DTU, LoopInfo *LI, SelectInstToUnfold SIToUnfold,
135135
std::vector<SelectInstToUnfold> *NewSIsToUnfold,
136136
std::vector<BasicBlock *> *NewBBs);
137137

@@ -157,7 +157,7 @@ class DFAJumpThreading {
157157

158158
std::vector<SelectInstToUnfold> NewSIsToUnfold;
159159
std::vector<BasicBlock *> NewBBs;
160-
unfold(&DTU, SIToUnfold, &NewSIsToUnfold, &NewBBs);
160+
unfold(&DTU, LI, SIToUnfold, &NewSIsToUnfold, &NewBBs);
161161

162162
// Put newly discovered select instructions into the work list.
163163
for (const SelectInstToUnfold &NewSIToUnfold : NewSIsToUnfold)
@@ -201,7 +201,7 @@ void createBasicBlockAndSinkSelectInst(
201201
/// created basic blocks into \p NewBBs.
202202
///
203203
/// TODO: merge it with CodeGenPrepare::optimizeSelectInst() if possible.
204-
void unfold(DomTreeUpdater *DTU, SelectInstToUnfold SIToUnfold,
204+
void unfold(DomTreeUpdater *DTU, LoopInfo *LI, SelectInstToUnfold SIToUnfold,
205205
std::vector<SelectInstToUnfold> *NewSIsToUnfold,
206206
std::vector<BasicBlock *> *NewBBs) {
207207
SelectInst *SI = SIToUnfold.getInst();
@@ -307,6 +307,12 @@ void unfold(DomTreeUpdater *DTU, SelectInstToUnfold SIToUnfold,
307307
DTU->applyUpdates({{DominatorTree::Insert, StartBlock, TT},
308308
{DominatorTree::Insert, StartBlock, FT}});
309309

310+
// Preserve loop info
311+
if (Loop *L = LI->getLoopFor(SI->getParent())) {
312+
for (BasicBlock *NewBB : *NewBBs)
313+
L->addBasicBlockToLoop(NewBB, *LI);
314+
}
315+
310316
// The select is now dead.
311317
assert(SI->use_empty() && "Select must be dead now");
312318
SI->eraseFromParent();
@@ -522,9 +528,10 @@ struct MainSwitch {
522528
};
523529

524530
struct AllSwitchPaths {
525-
AllSwitchPaths(const MainSwitch *MSwitch, OptimizationRemarkEmitter *ORE)
526-
: Switch(MSwitch->getInstr()), SwitchBlock(Switch->getParent()),
527-
ORE(ORE) {}
531+
AllSwitchPaths(const MainSwitch *MSwitch, OptimizationRemarkEmitter *ORE,
532+
LoopInfo *LI)
533+
: Switch(MSwitch->getInstr()), SwitchBlock(Switch->getParent()), ORE(ORE),
534+
LI(LI) {}
528535

529536
std::vector<ThreadingPath> &getThreadingPaths() { return TPaths; }
530537
unsigned getNumThreadingPaths() { return TPaths.size(); }
@@ -596,6 +603,12 @@ struct AllSwitchPaths {
596603

597604
Visited.insert(BB);
598605

606+
// Stop if we have reached the BB out of loop, since its successors have no
607+
// impact on the DFA.
608+
// TODO: Do we need to stop exploring if BB is the outer loop of the switch?
609+
if (!LI->getLoopFor(BB))
610+
return Res;
611+
599612
// Some blocks have multiple edges to the same successor, and this set
600613
// is used to prevent a duplicate path from being generated
601614
SmallSet<BasicBlock *, 4> Successors;
@@ -737,6 +750,7 @@ struct AllSwitchPaths {
737750
BasicBlock *SwitchBlock;
738751
OptimizationRemarkEmitter *ORE;
739752
std::vector<ThreadingPath> TPaths;
753+
LoopInfo *LI;
740754
};
741755

742756
struct TransformDFA {
@@ -1304,7 +1318,7 @@ bool DFAJumpThreading::run(Function &F) {
13041318
if (!Switch.getSelectInsts().empty())
13051319
MadeChanges = true;
13061320

1307-
AllSwitchPaths SwitchPaths(&Switch, ORE);
1321+
AllSwitchPaths SwitchPaths(&Switch, ORE, LI);
13081322
SwitchPaths.run();
13091323

13101324
if (SwitchPaths.getNumThreadingPaths() > 0) {

0 commit comments

Comments
 (0)