[PATCH] D32494: [Loop Deletion] Delete loops that are semantically unreachable

Sanjoy Das via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 25 11:12:10 PDT 2017


sanjoy requested changes to this revision.
sanjoy added a comment.
This revision now requires changes to proceed.

I made a few first pass comments.  I think the term "semantically unreachable" sounds more complicated than it actually is. :)  How about "never executed", as in `isLoopNeverExecuted`?



================
Comment at: lib/Transforms/Scalar/LoopDeletion.cpp:48
+                          LoopInfo &LI,
+                          bool LoopIsSemanticallyUnreachable,
+                          LPMUpdater *Updater = nullptr);
----------------
Indent seems off - clang-format?


================
Comment at: lib/Transforms/Scalar/LoopDeletion.cpp:119
+
+  auto *Preheader = L->getLoopPreheader();
+
----------------
I think this distinction between predecessor and preheader is making the logic a bit more complex than it needs to be.  I'd instead do:

```
auto *Pred = L->getLoopPredecessor();
auto *Succ = L->getHeader();
if (Pred && Pred->getTerminator() is not conditional branch) {
  Succ = Pred;
  Pred = Pred->getSinglePredecessor();
}
if (!Pred || Pred->getTerminator() is not conditional branch)
  return false;
```



================
Comment at: lib/Transforms/Scalar/LoopDeletion.cpp:134
+  // of constant conditional branch. We avoid doing this now, because
+  // Loop-SimplifyCFG will be enhanced to change branches in loop from constant
+  // conditional to unconditional, thereby iterating forward across the straight
----------------
Why is Loop-SimplifyCFG relevant here?  Won't it only simplify control flow //within// a loop?


================
Comment at: lib/Transforms/Scalar/LoopDeletion.cpp:137
+  // line code.
+  TerminatorInst *T = HeaderPred->getTerminator();
+  auto *BI = dyn_cast<BranchInst>(T);
----------------
The `T` seems a bit superfluous here -- why not just `auto *BI = dyn_cast<BranchInst>(HeaderPred->getTerminator())`?


================
Comment at: lib/Transforms/Scalar/LoopDeletion.cpp:145
+  BasicBlock *NotTaken =
+      Cond->getZExtValue() ? BI->getSuccessor(1) : BI->getSuccessor(0);
+  return (NotTaken == FirstLoopBlock);
----------------
What if both the branches branch to the header?


================
Comment at: lib/Transforms/Scalar/LoopDeletion.cpp:146
+      Cond->getZExtValue() ? BI->getSuccessor(1) : BI->getSuccessor(0);
+  return (NotTaken == FirstLoopBlock);
+}
----------------
This can be just `return NotTaken == FirstLoopBlock;`


================
Comment at: lib/Transforms/Scalar/LoopDeletion.cpp:189
+  // The loop is not semantically unreachable. Check for the second case of a
+  // dead loop, i.e.  where the loop has no backedge, and all statements in the
+  // loop are invariant. This is a non-loop if we can move all statements within
----------------
I'm missing where you're checking for this second case?


================
Comment at: lib/Transforms/Scalar/LoopDeletion.cpp:279
+    // We set it to the undef value instead of removing the incoming value to
+    // avoid dealing with dead phi's, which may make the corresponding block
+    // dead.
----------------
How do dead phis make a block dead?

If you're talking about keeping the edge from SourceBB to ExitBlock even though it will never be taken, then I see what you mean, but that comment should be on `SourceBB->getTerminator()->replaceUsesOfWith(L->getHeader(), ExitBlock);`.  Btw, what is the problem with deleting that edge?  Is it with updating LoopInfo or something else?



https://reviews.llvm.org/D32494





More information about the llvm-commits mailing list