[PATCH] D60565: [LOOPINFO] Extend Loop object to add utilities to get the loop bounds, step, induction variable, and guard branch.
Johannes Doerfert via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 29 21:00:17 PDT 2019
jdoerfert added a comment.
I reviewed up to line 380 in LoopInfo.cpp.
================
Comment at: llvm/include/llvm/Analysis/IVDescriptors.h:319
+ return IK == IK_FpInduction && InductionBinOp &&
+ !cast<FPMathOperator>(InductionBinOp)->isFast();
}
----------------
Why do we need this change? It seems either unrelated, unnecessary, or to complex for me. In the last case, please extend the comment.
================
Comment at: llvm/include/llvm/Analysis/IVDescriptors.h:327
+ return nullptr;
+
if (!InductionBinOp || cast<FPMathOperator>(InductionBinOp)->isFast())
----------------
Same as above
================
Comment at: llvm/include/llvm/Analysis/LoopInfo.h:413
+ /// Derived classes can override this method using static template
+ /// polymorphism.
+ BranchInst *getGuard(ScalarEvolution &SE) const { return nullptr; }
----------------
Could you first describe the "desired" function/semantic of this method before you note that it can be overriden?
================
Comment at: llvm/include/llvm/Analysis/LoopInfo.h:417
+ /// Derived classes can override this method using static template
+ /// polymorphism.
+ PHINode *getInductionVariable(ScalarEvolution &SE,
----------------
Same as above.
================
Comment at: llvm/include/llvm/Analysis/LoopInfo.h:577
+ /// LoopBounds can only be created if an induction variable can be
+ /// identified.
+ LoopBounds(const Loop &Loop, PHINode &IndVar, ICmpInst &C,
----------------
Maybe mention how one is supposed to determine this precondition.
================
Comment at: llvm/include/llvm/Analysis/LoopInfo.h:599
+ /// iteration.
+ Value &getStepValue() const { return *getStepInst().getOperand(1); }
+
----------------
Do you check, or enforce, that the Step is "canonical", e.g., the step is on the right?
I tried to find this below but I couldn't.
================
Comment at: llvm/include/llvm/Analysis/LoopInfo.h:602
+ /// Get the final value of the loop induction variable.
+ Value &getFinalIVValue() const { return *CmpInst.getOperand(1); }
+
----------------
Do you check, or enforce, that the ICmpInst is "canonical", e.g., the bound is on the right?
I tried to find this below but I couldn't.
================
Comment at: llvm/include/llvm/Analysis/LoopInfo.h:606
+ /// - the first successor of the latch branch is the loop header
+ /// - the LHS of the latch comparison is StepInst
+ ICmpInst::Predicate getCanonicalPredicate() const;
----------------
Doesn't this contradict the `getStepInst().getOperand(1);` in line 599?
================
Comment at: llvm/include/llvm/Analysis/LoopInfo.h:633
+
+ // the initial value of the loop induction variable
+ Value *Init;
----------------
I'd start comments with an upper case letter, again below. (sorry for the nitpicking).
================
Comment at: llvm/include/llvm/Analysis/LoopInfo.h:640
+ // the latch condition instruction
+ ICmpInst &CmpInst;
+
----------------
Please rename if it is "the latch condition" to sth like "LatchCmpInst".
================
Comment at: llvm/include/llvm/Analysis/LoopInfo.h:646
+ /// Return the struct LoopBounds collected if all struct members are found,
+ /// else return nullptr.
+ Optional<LoopBounds> getBounds(ScalarEvolution &SE) const;
----------------
else "None".
================
Comment at: llvm/include/llvm/Analysis/LoopInfo.h:654
+ /// - a loop exit block dominates the other successor
+ /// - the condition is to verify loop initial value satisfy the latch
+ /// condition
----------------
Do you really test that? The initial loop fusion patch did not.
================
Comment at: llvm/include/llvm/Analysis/LoopInfo.h:673
+ /// Return true if the given PHINode \p AuxIndVar is
+ /// - in loop header
+ /// - not used outside of the loop
----------------
"in a" or "in the", but I might be wrong here.
================
Comment at: llvm/lib/Analysis/IVDescriptors.cpp:1057
+ BinaryOperator *BOp = dyn_cast_or_null<BinaryOperator>(
+ Phi->getIncomingValueForBlock(AR->getLoop()->getLoopLatch()));
const SCEV *Step = AR->getStepRecurrence(*SE);
----------------
Does this work if there is no loop latch? I have the feeling `Phi->getIncomingValueForBlock` might choke on a nullptr. I might be wrong though.
I feel the changes in this file are unrelated and can go before the rest. If you agree, open a new patch for them, maybe with a test, and I'll accept it as it is pretty straight forward.
================
Comment at: llvm/lib/Analysis/LoopInfo.cpp:194
+
+void Loop::LoopBounds::setStepInst(PHINode &IndVar) {
+ InductionDescriptor IndDesc;
----------------
[I don't care too much but I'm interested:] Any reason you separated `setIniitalIVValue` and `setStepInst`?
================
Comment at: llvm/lib/Analysis/LoopInfo.cpp:220
+ // StepInst
+ if (CmpInst.getOperand(0) != &getStepInst()) {
+ // Cannot flip strictness of NE and EQ
----------------
I am not sure this is in sync with the constant `getOperand(1)` in one of the headers.
================
Comment at: llvm/lib/Analysis/LoopInfo.cpp:224
+ return ICmpInst::getFlippedStrictnessPredicate(Pred);
+ Direction D = getDirection();
+ if (D == Direction::Increasing)
----------------
Why do you have the non-SE path above for certain special cases e.g.,. non-equality conditions, before you have a, what seems to be, general SE based handling?
================
Comment at: llvm/lib/Analysis/LoopInfo.cpp:257
+ BasicBlock *Latch = L.getLoopLatch();
+ assert(Latch && "Expecting valid latch");
+
----------------
Couldn't we return nullptr here as well? It seems nullptr is a valid return value here anyway.
================
Comment at: llvm/lib/Analysis/LoopInfo.cpp:267
+
+ // First operand of CI should be the StepInst
+ if (isa<Instruction>(CI->getOperand(0)))
----------------
[IMPORTANT] How do we know or enforce this?
================
Comment at: llvm/lib/Analysis/LoopInfo.cpp:288
+
+/// Return the closest conditional branch before loop L, where
+/// one successor dominates the loop preheader,
----------------
-"where"
+"if"
================
Comment at: llvm/lib/Analysis/LoopInfo.cpp:290
+/// one successor dominates the loop preheader,
+/// and a loop exit block dominates the other successor.
+/// Example:
----------------
"and a definite successor of a loop exit block (trivially) post-dominates the other successor.
The second condition ensures the branch is a control dependence of the loop."
================
Comment at: llvm/lib/Analysis/LoopInfo.cpp:306
+/// afterloop:
+/// \endcode
+///
----------------
Maybe we need a more general picture here as the example shows the simple case. I can imagine some "ascii-art" or a more elaborate description.
================
Comment at: llvm/lib/Analysis/LoopInfo.cpp:318
+ // the loop preheader.
+ BasicBlock *GuardBB = L.getLoopPreheader();
+ BranchInst *GuardBI = dyn_cast<BranchInst>(GuardBB->getTerminator());
----------------
`if (!GuardBB) return nullptr`
================
Comment at: llvm/lib/Analysis/LoopInfo.cpp:319
+ BasicBlock *GuardBB = L.getLoopPreheader();
+ BranchInst *GuardBI = dyn_cast<BranchInst>(GuardBB->getTerminator());
+ if (!GuardBB || !GuardBI)
----------------
GuardBI is overwritten before used.
================
Comment at: llvm/lib/Analysis/LoopInfo.cpp:336
+ // A Visited set is needed to records blocks already visited, to avoid
+ // infinite loop when ExitBlock single successor loops back to itself.
+ if (Visited.count(GuardBB) != 0)
----------------
The comment is outdated (ExitBlock)
================
Comment at: llvm/lib/Analysis/LoopInfo.cpp:340
+
+ Visited.insert(GuardBB);
+ GuardBI = dyn_cast<BranchInst>(GuardBB->getTerminator());
----------------
We often use the pattern:
```
if (!Visited.insert(GuardBB).second)
return nullptr;
```
================
Comment at: llvm/lib/Analysis/LoopInfo.cpp:356
+ assert((SkipIndex == 1 || GuardBI->getSuccessor(1) == Succ) &&
+ "Expecting one of GuardBI successor to be Succ");
+ ICmpInst *Cond = dyn_cast<ICmpInst>(GuardBI->getCondition());
----------------
Why do we "compute" the index of the Successor if we assert it is 1 anyway? This seems like a specialization of a more general scheme.
================
Comment at: llvm/lib/Analysis/LoopInfo.cpp:359
+ if (!Cond)
+ return nullptr;
+ GuardPred =
----------------
I'm always for newlines to mark control condition changes
================
Comment at: llvm/lib/Analysis/LoopInfo.cpp:360
+ return nullptr;
+ GuardPred =
+ (SkipIndex == 1) ? Cond->getPredicate() : Cond->getInversePredicate();
----------------
This is the general version (see above) again.
================
Comment at: llvm/lib/Analysis/LoopInfo.cpp:369
+ // infinite loop when ExitBlock single successor loops back to itself.
+ SmallPtrSet<BasicBlock *, 4> Visited;
+ while (ExitBlock && ExitBlock != SkipToBlock &&
----------------
You could instead call `Visited.clear()` here but I don't mind a new object.
Repository:
rL LLVM
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D60565/new/
https://reviews.llvm.org/D60565
More information about the llvm-commits
mailing list