[PATCH] D32409: [PM/LoopUnswitch] Introduce a new, simpler loop unswitch pass.
Sanjoy Das via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 25 00:48:12 PDT 2017
sanjoy added a comment.
Looks good overall, mostly minor comments inline.
================
Comment at: lib/Transforms/Scalar/SimpleLoopUnswitch.cpp:71
+/// exit block.
+static void updateLoopExitIDomAfterUnswitch(BasicBlock *LoopExitBB, Loop &L,
+ DominatorTree &DT) {
----------------
I'd prefer calling this function just `updateLoopExitIDom`, since nothing in it is specific to unswitching.
================
Comment at: lib/Transforms/Scalar/SimpleLoopUnswitch.cpp:75
+ "Cannot have empty predecessors of the loop exit block if we split "
+ "off a block to unswitch1");
+
----------------
s/unswitch1/unswitch!/
================
Comment at: lib/Transforms/Scalar/SimpleLoopUnswitch.cpp:80
+ // until all predecessors are covered or we reach the loop header. The loop
+ // header necesasrily dominates all loop exit blocks in loop simplified form
+ // so we can early-exit the moment we hit that block.
----------------
s/necesasrily/necessarily/
================
Comment at: lib/Transforms/Scalar/SimpleLoopUnswitch.cpp:122
+ // exit block.
+ DT.changeImmediateDominator(UnswitchedNode, OldPHNode);
+
----------------
Instead of special casing here, why not just
```
SmallSetVector<BasicBlock *, 4> Worklist;
Worklist.insert(UnswitchedNode);
```
and let nature run its course?
================
Comment at: lib/Transforms/Scalar/SimpleLoopUnswitch.cpp:136
+ assert(!DomChain.count(Node) &&
+ "Cannot be dominated by a block you can reach1");
+ // If this block doesn't have an immediate dominator somewhere in the chain
----------------
s/reach1/reach!/
================
Comment at: lib/Transforms/Scalar/SimpleLoopUnswitch.cpp:200
+ }
+ auto *ContinueBB = BI.getSuccessor((LoopExitSuccIdx + 1) % 2);
+ assert(L.contains(ContinueBB) &&
----------------
This is very minor, but I'm used to seeing `1 - LoopExitSuccIdx` in cases like these.
================
Comment at: lib/Transforms/Scalar/SimpleLoopUnswitch.cpp:205
+ // If the loop exit block contains phi nodes, this isn't trivial.
+ if (isa<PHINode>(LoopExitBB->begin()))
+ return false;
----------------
Why is a PHI on the exit block a problem? Are you saying this because the PHI can require you to copy some computation into `OldPH`? If so, perhaps we can be a bit more aggressive here, and allow PHIs that have constant incoming values for the edge we're unswitching? It would be fine to do in a later patch, but please add a quick TODO or explanation if that's the reason.
================
Comment at: lib/Transforms/Scalar/SimpleLoopUnswitch.cpp:223
+ if (llvm::all_of(predecessors(LoopExitBB), [&](BasicBlock *PredBB) {
+ return PredBB == BI.getParent();
+ })) {
----------------
I found this bit of code a bit convoluted to understand. I'd have written this as (if I understood the intent correctly):
```
if (LoopExitBB->getSinglePredecessor()) {
assert(LoopExitBB->getSinglePredecessor() == BI.getParent());
UnswitchedBB = LoopExitBB
} else {
// We know something other than BI is branching to LoopExitBB and since the
// loop is simplified, we know that all those other things are from within
// the loop. Hence the unswitched branch needs to branch to the a split out
// block.
UnswitchedBB = SplitBlock(LoopExitBB, &LoopExitBB->front(), &DT, &LI);
}
```
================
Comment at: lib/Transforms/Scalar/SimpleLoopUnswitch.cpp:238
+ BI.setSuccessor(LoopExitSuccIdx, UnswitchedBB);
+ BI.setSuccessor((LoopExitSuccIdx + 1) % 2, NewPH);
+
----------------
Same suggestion here regarding `1 - LoopExitSuccIdx`.
================
Comment at: lib/Transforms/Scalar/SimpleLoopUnswitch.cpp:261
+
+/// Unswitch a trivial switcih if the condition is loop invariant.
+///
----------------
s/switcih/switch/
================
Comment at: lib/Transforms/Scalar/SimpleLoopUnswitch.cpp:365
+ // Split the preheader, so that we know that there is a safe
+ // place to insert the conditional branch. We will change the preheader to
+ // have a conditional branch on Cond.
----------------
Minor, but s/conditional branch/switch/
================
Comment at: lib/Transforms/Scalar/SimpleLoopUnswitch.cpp:445
+
+/// This routine cans the loop to find a branch or switch which occurs before
+/// any side effects occur. These can potentially be unswitched without
----------------
s/cans/scans/
================
Comment at: lib/Transforms/Scalar/SimpleLoopUnswitch.cpp:453
+/// The return value indicates whether any changes were made, not whether
+/// anything was actually unswitched.
+static bool unswitchAllTrivialConditions(Loop &L, DominatorTree &DT,
----------------
What does this routine change in the cases where nothing is unswitched?
================
Comment at: lib/Transforms/Scalar/SimpleLoopUnswitch.cpp:475
+ // stores, calls, volatile loads) in the part of the loop that the code
+ // *would* execute. Check the header first.
+ for (Instruction &I : *CurrentBB)
----------------
The ` Check the header first.` comment seems out of place. I'd also be tempted to use `llvm::any_of` here.
================
Comment at: lib/Transforms/Scalar/SimpleLoopUnswitch.cpp:485
+ if (ConstantInt *Cond = dyn_cast<ConstantInt>(SI->getCondition())) {
+ CurrentBB = SI->findCaseValue(Cond)->getCaseSuccessor();
+ continue;
----------------
Are handling these cases here necessary? I'd imagine `LoopSimplifyCFG` to be a better place for these (especially the second one, which is just an unconditional `br` written as a `switch`).
================
Comment at: lib/Transforms/Scalar/SimpleLoopUnswitch.cpp:518
+ // We do not understand other terminator instructions.
+ return false;
+
----------------
Should this be `return Changed;`?
https://reviews.llvm.org/D32409
More information about the llvm-commits
mailing list