Skip to content

Commit cbcc7f3

Browse files
committed
[SimplifyCFG] Not folding branch in constant loops which expected unroll
Constant iteration loop with unroll hint usually expected do unroll by consumers, folding branches in such loop header at SimplifyCFG will break unroll optimization.
1 parent af7995f commit cbcc7f3

File tree

2 files changed

+860
-48
lines changed

2 files changed

+860
-48
lines changed

llvm/lib/Transforms/Utils/SimplifyCFG.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
#include "llvm/Support/raw_ostream.h"
7474
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
7575
#include "llvm/Transforms/Utils/Local.h"
76+
#include "llvm/Transforms/Utils/UnrollLoop.h"
7677
#include "llvm/Transforms/Utils/ValueMapper.h"
7778
#include <algorithm>
7879
#include <cassert>
@@ -3634,6 +3635,59 @@ static bool extractPredSuccWeights(BranchInst *PBI, BranchInst *BI,
36343635
}
36353636
}
36363637

3638+
bool hasUnrollHint(Instruction *TI) {
3639+
MDNode *MD = TI->getMetadata(LLVMContext::MD_loop);
3640+
if (!MD)
3641+
return false;
3642+
3643+
return GetUnrollMetadata(MD, "llvm.loop.unroll.enable") ||
3644+
GetUnrollMetadata(MD, "llvm.loop.unroll.full") ||
3645+
GetUnrollMetadata(MD, "llvm.loop.unroll.count");
3646+
}
3647+
3648+
// Escape folding "I < ConstNum" with "Cond2" when loops with constant
3649+
// iterations and expected unroll.
3650+
// #pragma unroll
3651+
// for (int I = 0; I < ConstNum; ++I) { // ConstNum > 1
3652+
// if (Cond2) {
3653+
// break;
3654+
// }
3655+
// xxx loop body;
3656+
// }
3657+
// Folding these conditional branches may break/affect loop unroll.
3658+
static bool isConstantLoopWithUnrollHint(BranchInst *PBI) {
3659+
ICmpInst *ICmp = dyn_cast<ICmpInst>(PBI->getCondition());
3660+
if (!ICmp)
3661+
return false;
3662+
3663+
// Make sure ConstNum > 1
3664+
bool DoFold = true;
3665+
for (unsigned I = 0; I < ICmp->getNumOperands(); ++I) {
3666+
ConstantInt *Op = dyn_cast<ConstantInt>(ICmp->getOperand(I));
3667+
if (!Op)
3668+
continue;
3669+
if (Op->getSExtValue() > 1) {
3670+
DoFold = false;
3671+
break;
3672+
}
3673+
}
3674+
if (DoFold)
3675+
return false;
3676+
3677+
// Loop information has not been established yet, so here we easily judge
3678+
// whether it is a loop by backedge.
3679+
BasicBlock *PBB = PBI->getParent();
3680+
for (Function::iterator I = PBB->getIterator(), E = PBB->getParent()->end();
3681+
I != E; ++I) {
3682+
BasicBlock *BB = &*I;
3683+
if (is_contained(predecessors(PBB), BB)) {
3684+
if (hasUnrollHint(BB->getTerminator()))
3685+
return true;
3686+
}
3687+
}
3688+
return false;
3689+
}
3690+
36373691
/// Determine if the two branches share a common destination and deduce a glue
36383692
/// that joins the branches' conditions to arrive at the common destination if
36393693
/// that would be profitable.
@@ -3645,6 +3699,9 @@ shouldFoldCondBranchesToCommonDestination(BranchInst *BI, BranchInst *PBI,
36453699
assert(is_contained(predecessors(BI->getParent()), PBI->getParent()) &&
36463700
"PredBB must be a predecessor of BB.");
36473701

3702+
if (isConstantLoopWithUnrollHint(PBI))
3703+
return std::nullopt;
3704+
36483705
// We have the potential to fold the conditions together, but if the
36493706
// predecessor branch is predictable, we may not want to merge them.
36503707
uint64_t PTWeight, PFWeight;

0 commit comments

Comments
 (0)