Skip to content

Commit 4c0f84b

Browse files
committed
[DFAJumpThreading] Avoid exploring the paths that never come back
1 parent dbbdee2 commit 4c0f84b

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
@@ -126,7 +126,7 @@ class SelectInstToUnfold {
126126
explicit operator bool() const { return SI && SIUse; }
127127
};
128128

129-
void unfold(DomTreeUpdater *DTU, SelectInstToUnfold SIToUnfold,
129+
void unfold(DomTreeUpdater *DTU, LoopInfo *LI, SelectInstToUnfold SIToUnfold,
130130
std::vector<SelectInstToUnfold> *NewSIsToUnfold,
131131
std::vector<BasicBlock *> *NewBBs);
132132

@@ -152,7 +152,7 @@ class DFAJumpThreading {
152152

153153
std::vector<SelectInstToUnfold> NewSIsToUnfold;
154154
std::vector<BasicBlock *> NewBBs;
155-
unfold(&DTU, SIToUnfold, &NewSIsToUnfold, &NewBBs);
155+
unfold(&DTU, LI, SIToUnfold, &NewSIsToUnfold, &NewBBs);
156156

157157
// Put newly discovered select instructions into the work list.
158158
for (const SelectInstToUnfold &NewSIToUnfold : NewSIsToUnfold)
@@ -196,7 +196,7 @@ void createBasicBlockAndSinkSelectInst(
196196
/// created basic blocks into \p NewBBs.
197197
///
198198
/// TODO: merge it with CodeGenPrepare::optimizeSelectInst() if possible.
199-
void unfold(DomTreeUpdater *DTU, SelectInstToUnfold SIToUnfold,
199+
void unfold(DomTreeUpdater *DTU, LoopInfo *LI, SelectInstToUnfold SIToUnfold,
200200
std::vector<SelectInstToUnfold> *NewSIsToUnfold,
201201
std::vector<BasicBlock *> *NewBBs) {
202202
SelectInst *SI = SIToUnfold.getInst();
@@ -302,6 +302,12 @@ void unfold(DomTreeUpdater *DTU, SelectInstToUnfold SIToUnfold,
302302
DTU->applyUpdates({{DominatorTree::Insert, StartBlock, TT},
303303
{DominatorTree::Insert, StartBlock, FT}});
304304

305+
// Preserve loop info
306+
if (Loop *L = LI->getLoopFor(SI->getParent())) {
307+
for (BasicBlock *NewBB : *NewBBs)
308+
L->addBasicBlockToLoop(NewBB, *LI);
309+
}
310+
305311
// The select is now dead.
306312
assert(SI->use_empty() && "Select must be dead now");
307313
SI->eraseFromParent();
@@ -501,9 +507,10 @@ struct MainSwitch {
501507
};
502508

503509
struct AllSwitchPaths {
504-
AllSwitchPaths(const MainSwitch *MSwitch, OptimizationRemarkEmitter *ORE)
505-
: Switch(MSwitch->getInstr()), SwitchBlock(Switch->getParent()),
506-
ORE(ORE) {}
510+
AllSwitchPaths(const MainSwitch *MSwitch, OptimizationRemarkEmitter *ORE,
511+
LoopInfo *LI)
512+
: Switch(MSwitch->getInstr()), SwitchBlock(Switch->getParent()), ORE(ORE),
513+
LI(LI) {}
507514

508515
std::vector<ThreadingPath> &getThreadingPaths() { return TPaths; }
509516
unsigned getNumThreadingPaths() { return TPaths.size(); }
@@ -575,6 +582,12 @@ struct AllSwitchPaths {
575582

576583
Visited.insert(BB);
577584

585+
// Stop if we have reached the BB out of loop, since its successors have no
586+
// impact on the DFA.
587+
// TODO: Do we need to stop exploring if BB is the outer loop of the switch?
588+
if (!LI->getLoopFor(BB))
589+
return Res;
590+
578591
// Some blocks have multiple edges to the same successor, and this set
579592
// is used to prevent a duplicate path from being generated
580593
SmallSet<BasicBlock *, 4> Successors;
@@ -716,6 +729,7 @@ struct AllSwitchPaths {
716729
BasicBlock *SwitchBlock;
717730
OptimizationRemarkEmitter *ORE;
718731
std::vector<ThreadingPath> TPaths;
732+
LoopInfo *LI;
719733
};
720734

721735
struct TransformDFA {
@@ -1283,7 +1297,7 @@ bool DFAJumpThreading::run(Function &F) {
12831297
if (!Switch.getSelectInsts().empty())
12841298
MadeChanges = true;
12851299

1286-
AllSwitchPaths SwitchPaths(&Switch, ORE);
1300+
AllSwitchPaths SwitchPaths(&Switch, ORE, LI);
12871301
SwitchPaths.run();
12881302

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

0 commit comments

Comments
 (0)