[PATCH] D20143: New pass: guard widening

Philip Reames via llvm-commits llvm-commits at lists.llvm.org
Mon May 16 18:53:07 PDT 2016


reames requested changes to this revision.
This revision now requires changes to proceed.

================
Comment at: include/llvm/Transforms/Scalar/GuardWidening.h:12
@@ +11,3 @@
+// that (optimistically) combines multiple guards into one to have fewer checks
+// at runtime.
+//
----------------
You should expand this comment.  Specifically, clarify exceptions around re-execution and healing.

Actually, never mind.  This is available in the source.

================
Comment at: lib/Transforms/Scalar/GuardWidening.cpp:120
@@ +119,3 @@
+  /// InsertPt and return it in \p Result (else no change to the IR is made).
+  bool widenCondCommon(Value *Cond0, Value *Cond1, Instruction *InsertPt,
+                       Value *&Result);
----------------
Interface wise, this might be clearer as returning an optional<Value*> or just a Value* which can be null.

================
Comment at: lib/Transforms/Scalar/GuardWidening.cpp:126
@@ +125,3 @@
+  bool isWideningCondProfitable(Value *Cond0, Value *Cond1) {
+    Value *ResultUnused;
+    return widenCondCommon(Cond0, Cond1, /*InsertPt=*/nullptr, ResultUnused);
----------------
Generating extra IR just for checking profitability seems less than idea.  Could this be combined into a single function which does the replacement if profitable and nothing otherwise?

================
Comment at: lib/Transforms/Scalar/GuardWidening.cpp:213
@@ +212,3 @@
+    auto *CurLoop = LI.getLoopFor(CurBB);
+    const auto &GuardsInCurBB = GuardsInBlock.find(CurBB)->second;
+
----------------
Please add an assert that curBB has been populated in GuardsInBlock.  Your lazy population scheme is fine, but the code doesn't make it *obvious* that's it correct.

================
Comment at: lib/Transforms/Scalar/GuardWidening.cpp:225
@@ +224,3 @@
+      assert(NewEnd != E && "GuardInst not in its own block?");
+      E = NewEnd;
+    }
----------------
You have an assumption here that the guards are recorded in the order they appeared in the original basic block.  Please document that near the definition of the data structure.

================
Comment at: lib/Transforms/Scalar/GuardWidening.cpp:229
@@ +228,3 @@
+    for (auto *Candidate : make_range(I, E)) {
+      auto Score =
+          computeWideningScore(GuardInst, GuardInstLoop, Candidate, CurLoop);
----------------
As far as I understand it, there is never a case where widening one pair of guards would prevent you from merging that widened guard into another.  You code is structured as if this is a possibility and it results in excessive generality.  

The excess generality here is causing you to implement an O(G^2) algorithm for something which should be a collection of a O(N) algorithms.  This is unacceptable.

================
Comment at: lib/Transforms/Scalar/GuardWidening.cpp:253
@@ +252,3 @@
+  GuardInst->setArgOperand(0, ConstantInt::getTrue(GuardInst->getContext()));
+  EliminatedGuards.push_back(GuardInst);
+  WidenedGuards.insert(BestSoFar);
----------------
In general, you *should* be able to simply delete the second guard here.  The fact you can't, indicates there's a problem with the algorithm you've chosen.

================
Comment at: lib/Transforms/Scalar/GuardWidening.cpp:287
@@ +286,3 @@
+
+bool GuardWideningImpl::isAvailableAt(Value *V, Instruction *Loc) {
+  auto *Inst = dyn_cast<Instruction>(V);
----------------
This really seems likely to be excessive generality again.  You don't need a generic hoisting algorithm.  

================
Comment at: lib/Transforms/Scalar/GuardWidening.cpp:300
@@ +299,3 @@
+
+  return all_of(Inst->operands(), [&](Value *Op) {
+      return isAvailableAt(Op, Loc);
----------------
Buggy in the face of unreachable code:
%a = add i32 %a, 1

================
Comment at: lib/Transforms/Scalar/GuardWidening.cpp:358
@@ +357,3 @@
+    Result = BinaryOperator::CreateAnd(Cond0, Cond1, "wide.chk", InsertPt);
+  }
+
----------------
Is there possibly a missing return here?


http://reviews.llvm.org/D20143





More information about the llvm-commits mailing list