[PATCH] D32409: [PM/LoopUnswitch] Introduce a new, simpler loop unswitch pass.

Chandler Carruth via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 27 01:45:40 PDT 2017


chandlerc added a comment.

Thanks for the reviews! Updated patch and responses inline.

In https://reviews.llvm.org/D32409#737397, @davide wrote:

> In https://reviews.llvm.org/D32409#737387, @davide wrote:
>
> > I focused on the logic to update the dominator and I think it's correct. Some comments below.
> >  Also, recently there have been some changes wrt divergent conditions. Do you plan to integrate them in the new pass?
>
>
> The reason why I'm asking is that I'm not an expert about DivergenceAnalysis so I can't really reason about all the implications there.


I do plan to integrate them. I'm just starting with what seemed like a reasonably useful to review subset. Does this seem like a reasonable thing to do in a follow-up?



================
Comment at: lib/Transforms/Scalar/SimpleLoopUnswitch.cpp:50
+STATISTIC(NumSwitches, "Number of switches unswitched");
+STATISTIC(NumTrivial, "Number of unswitches that are trivial");
+
----------------
davide wrote:
> Do we really need `NumTrivial`? From what I see here it's just `NumBranches + NumSwitches`
Well, in the next patch we start doing non-trivial ones... I can wait until then if you prefer, I don't have a strong opinion.


================
Comment at: lib/Transforms/Scalar/SimpleLoopUnswitch.cpp:122
+  // exit block.
+  DT.changeImmediateDominator(UnswitchedNode, OldPHNode);
+
----------------
davide wrote:
> sanjoy wrote:
> > Instead of special casing here, why not just
> > 
> > ```
> >   SmallSetVector<BasicBlock *, 4> Worklist;
> >   Worklist.insert(UnswitchedNode);
> > ```
> > 
> > and let nature run its course?
> +1
I mean, I still need the comment on that line, and it is no shorter, and it avoids a pointless query to the DomChain set?

I can make the change if you want, just seems odd.


================
Comment at: lib/Transforms/Scalar/SimpleLoopUnswitch.cpp:179-184
+  // FIXME: We should compute this once at the start and update it!
+  SmallVector<BasicBlock *, 16> ExitBlocks;
+  L.getExitBlocks(ExitBlocks);
+  SmallPtrSet<BasicBlock *, 16> ExitBlockSet(ExitBlocks.begin(),
+                                             ExitBlocks.end());
+
----------------
davide wrote:
> Instead of having `getExitBlocks()` taking a `SmallVector<>` can we have it or a variant of it which takes a `SmallPtrSet` ? 
> I could use it in `LCSSA` to compute the dominance chain as well, FWIW.
Sure, could I add that in a follow-up patch?


================
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;
----------------
sanjoy wrote:
> 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.
It isn't at all. I just left this in from the old pass. I'd like to fix this in a subsequent patch though, added a comment.


================
Comment at: lib/Transforms/Scalar/SimpleLoopUnswitch.cpp:223
+  if (llvm::all_of(predecessors(LoopExitBB), [&](BasicBlock *PredBB) {
+        return PredBB == BI.getParent();
+      })) {
----------------
sanjoy wrote:
> 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);
> }
> ```
> 
Oooo, I like getSinglePredecessor. Done!


================
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,
----------------
sanjoy wrote:
> What does this routine change in the cases where nothing is unswitched?
This comment predates me making it *not* change anything. Updated comment.


================
Comment at: lib/Transforms/Scalar/SimpleLoopUnswitch.cpp:485
+      if (ConstantInt *Cond = dyn_cast<ConstantInt>(SI->getCondition())) {
+        CurrentBB = SI->findCaseValue(Cond)->getCaseSuccessor();
+        continue;
----------------
sanjoy wrote:
> 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`).
No, this is a holdover from when we restarted this entire thing on each unswitch. Thanks, updated.


================
Comment at: lib/Transforms/Scalar/SimpleLoopUnswitch.cpp:518
+      // We do not understand other terminator instructions.
+      return false;
+
----------------
sanjoy wrote:
> Should this be `return Changed;`?
Wow, good catch.


https://reviews.llvm.org/D32409





More information about the llvm-commits mailing list