[PATCH] D102234: [SimpleLoopBoundSplit] Split Bound of Loop which has conditional branch with IV
JinGu Kang via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 2 07:06:58 PDT 2021
jaykang10 added inline comments.
================
Comment at: llvm/lib/Transforms/Scalar/LoopBoundSplit.cpp:28
+
+using namespace llvm;
+using namespace llvm::PatternMatch;
----------------
mkazantsev wrote:
> namespace llvm {
Yep, I will update it.
================
Comment at: llvm/lib/Transforms/Scalar/LoopBoundSplit.cpp:88
+ // AddRec <= Bound --> AddRec < Bound + 1
+ if (Cond.Pred == ICmpInst::ICMP_ULE || Cond.Pred == ICmpInst::ICMP_SLE) {
+ if (IntegerType *BoundSCEVIntType =
----------------
mkazantsev wrote:
> nit: I'd suggest resturure it as
> ```
> if (pred != ULE && pred != SLE)
> return false;
>
> ```
>
> this will reduce the nest for the biggest code piece. Just an idea.
Yep, I will update it.
================
Comment at: llvm/lib/Transforms/Scalar/LoopBoundSplit.cpp:108
+ }
+ }
+ return false;
----------------
mkazantsev wrote:
> Please add a TODO to handle ICMP_NE/EQ (I guess it was in the earlier versions of this patch and still good to support, but not necessarily in this revision).
Yep, I will add ToDo for it.
================
Comment at: llvm/lib/Transforms/Scalar/LoopBoundSplit.cpp:131
+ // Allowed constant step.
+ if (!isa<SCEVConstant>(StepRecSCEV))
+ return false;
----------------
mkazantsev wrote:
> ```
> ConstantInt *StepCI = dyn_cast<SCEVConstant>(StepRecSCEV)->getValue();
> if (!StepCI || !StepCI->isPositive())
> return false;
> ...
> ```
>
It looked there is no `isPositive` in ConstantInt. I will update it with isNegative() and isZero(),
================
Comment at: llvm/lib/Transforms/Scalar/LoopBoundSplit.cpp:152
+ Value *LHS = nullptr;
+ Value *RHS = nullptr;
+ if (!match(BI, m_Br(m_ICmp(Pred, m_Value(LHS), m_Value(RHS)),
----------------
mkazantsev wrote:
> Could declare as `Value *LHS, *RHS;` Just an idea.
Yep, I will update it.
================
Comment at: llvm/lib/Transforms/Scalar/LoopBoundSplit.cpp:157
+
+ if (!SE.isSCEVable(LHS->getType()) || !SE.isSCEVable(RHS->getType()))
+ return false;
----------------
mkazantsev wrote:
> It's enough to check LHS type and assert on RHS type.
Yep, I will update it.
================
Comment at: llvm/lib/Transforms/Scalar/LoopBoundSplit.cpp:166
+
+static bool CanSplitLoopBound(Loop &L, LoopInfo &LI, DominatorTree &DT,
+ ScalarEvolution &SE, ConditionInfo &Cond) {
----------------
mkazantsev wrote:
> canSplit...
sorry for inconvenient. I will update it.
================
Comment at: llvm/lib/Transforms/Scalar/LoopBoundSplit.cpp:167
+static bool CanSplitLoopBound(Loop &L, LoopInfo &LI, DominatorTree &DT,
+ ScalarEvolution &SE, ConditionInfo &Cond) {
+ // Skip function with optsize.
----------------
mkazantsev wrote:
> Consider making params `const` where suitable.
Yep, let me try to add it.
================
Comment at: llvm/lib/Transforms/Scalar/LoopBoundSplit.cpp:217
+ if (BI->getParent() != L.getHeader())
+ return false;
+
----------------
mkazantsev wrote:
> Why is that needed?
Ah, I have tried to follow the below comment from @reames.
> For a profitability check, I'd start specifically with the case where the condition precisely splits a loop into two halves. e.g. for ... { if (C) { body1 } else { body2 }. This is the easiest to believe is generally profitable, and we can generalize the heuristic selection later.
For the condition precisely splits a loop into two halves, I have checked that the conditional branch is in header and the join point is latch. Let me remove them.
================
Comment at: llvm/lib/Transforms/Scalar/LoopBoundSplit.cpp:221
+ BasicBlock *Succ0 = BI->getSuccessor(0);
+ BasicBlock *Succ1 = BI->getSuccessor(1);
+
----------------
mkazantsev wrote:
> This is still a very strict limitation I think. I can always split critical edges if you need it. I'm fine if you just add a TODO to consider it in the future.
Yep, I will remove the checks with single predecessor.
================
Comment at: llvm/lib/Transforms/Scalar/LoopBoundSplit.cpp:244
+ ConditionInfo &ExitingCond,
+ ConditionInfo &SplitCandidateCond) {
+ for (auto *BB : L.blocks()) {
----------------
mkazantsev wrote:
> Consider marking params as `const` where suitable.
Yep, I will update it.
================
Comment at: llvm/lib/Transforms/Scalar/LoopBoundSplit.cpp:355
+ Instruction *OrigBI = PostLoopPreHeader->getTerminator();
+ ICmpInst::Predicate Pred = ICmpInst::ICMP_NE;
+ Value *Cond =
----------------
mkazantsev wrote:
> Two points here:
> 1. Functional concern. Will NE work ok for step other than 1?
> 2. `lt` generally gives more info to the opt than `ne` (at least because `lt` implies `ne`). Any reason for `ne` here?
I have tried to follow below comment from @reames.
> The "if (i != N)" is a loop guard and can be identified by getLoopGuardBranch.
I was also not sure whether `ne` is better than `lt` here...
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D102234/new/
https://reviews.llvm.org/D102234
More information about the llvm-commits
mailing list