diff options
author | darkbuck <michael.hliao@gmail.com> | 2024-07-26 12:15:49 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-26 12:15:49 -0400 |
commit | ba45453c0a5df3e6c3eddee647e14c97e02243fa (patch) | |
tree | 352cf526977ae7e2907102b37f8dc33b9f28b472 /llvm/lib/Transforms/Utils/SimplifyCFG.cpp | |
parent | b582b658d60fb23ce39c48b42be265093e5e889d (diff) | |
download | llvm-ba45453c0a5df3e6c3eddee647e14c97e02243fa.zip llvm-ba45453c0a5df3e6c3eddee647e14c97e02243fa.tar.gz llvm-ba45453c0a5df3e6c3eddee647e14c97e02243fa.tar.bz2 |
[SimplifyCFG] Skip threading if the target may have divergent branches
- This patch skips the threading on known values if the target has
divergent branch.
- So far, threading on known values is skipped when the basic block has
covergent calls. However, even without convergent calls, if that
condition is divergent, threading duplicates the execution of that
block threaded and hence results in lower performance. E.g.,
```
BB1:
if (cond) BB3, BB2
BB2:
// work2
br BB3
BB3:
// work3
if (cond) BB5, BB4
BB4:
// work4
br BB5
BB5:
```
after threading,
```
BB1:
if (cond) BB3', BB2'
BB2':
// work3
br BB5
BB3':
// work2
// work3
// work4
br BB5
BB5:
```
After threading, work3 is executed twice if 'cond' is a divergent one.
Reviewers: yxsamliu, nikic
Pull Request: https://github.com/llvm/llvm-project/pull/100185
Diffstat (limited to 'llvm/lib/Transforms/Utils/SimplifyCFG.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index f23e288..1a17524 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -3246,7 +3246,12 @@ bool SimplifyCFGOpt::SpeculativelyExecuteBB(BranchInst *BI, } /// Return true if we can thread a branch across this block. -static bool BlockIsSimpleEnoughToThreadThrough(BasicBlock *BB) { +static bool BlockIsSimpleEnoughToThreadThrough(BasicBlock *BB, + const TargetTransformInfo &TTI) { + // Skip threading if the branch may be divergent. + if (TTI.hasBranchDivergence(BB->getParent())) + return false; + int Size = 0; EphemeralValueTracker EphTracker; @@ -3301,10 +3306,9 @@ static ConstantInt *getKnownValueOnEdge(Value *V, BasicBlock *From, /// If we have a conditional branch on something for which we know the constant /// value in predecessors (e.g. a phi node in the current block), thread edges /// from the predecessor to their ultimate destination. -static std::optional<bool> -FoldCondBranchOnValueKnownInPredecessorImpl(BranchInst *BI, DomTreeUpdater *DTU, - const DataLayout &DL, - AssumptionCache *AC) { +static std::optional<bool> FoldCondBranchOnValueKnownInPredecessorImpl( + BranchInst *BI, DomTreeUpdater *DTU, const DataLayout &DL, + const TargetTransformInfo &TTI, AssumptionCache *AC) { SmallMapVector<ConstantInt *, SmallSetVector<BasicBlock *, 2>, 2> KnownValues; BasicBlock *BB = BI->getParent(); Value *Cond = BI->getCondition(); @@ -3332,7 +3336,7 @@ FoldCondBranchOnValueKnownInPredecessorImpl(BranchInst *BI, DomTreeUpdater *DTU, // Now we know that this block has multiple preds and two succs. // Check that the block is small enough and values defined in the block are // not used outside of it. - if (!BlockIsSimpleEnoughToThreadThrough(BB)) + if (!BlockIsSimpleEnoughToThreadThrough(BB, TTI)) return false; for (const auto &Pair : KnownValues) { @@ -3459,15 +3463,14 @@ FoldCondBranchOnValueKnownInPredecessorImpl(BranchInst *BI, DomTreeUpdater *DTU, return false; } -static bool FoldCondBranchOnValueKnownInPredecessor(BranchInst *BI, - DomTreeUpdater *DTU, - const DataLayout &DL, - AssumptionCache *AC) { +static bool FoldCondBranchOnValueKnownInPredecessor( + BranchInst *BI, DomTreeUpdater *DTU, const DataLayout &DL, + const TargetTransformInfo &TTI, AssumptionCache *AC) { std::optional<bool> Result; bool EverChanged = false; do { // Note that None means "we changed things, but recurse further." - Result = FoldCondBranchOnValueKnownInPredecessorImpl(BI, DTU, DL, AC); + Result = FoldCondBranchOnValueKnownInPredecessorImpl(BI, DTU, DL, TTI, AC); EverChanged |= Result == std::nullopt || *Result; } while (Result == std::nullopt); return EverChanged; @@ -7543,7 +7546,7 @@ bool SimplifyCFGOpt::simplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) { // If this is a branch on something for which we know the constant value in // predecessors (e.g. a phi node in the current block), thread control // through this block. - if (FoldCondBranchOnValueKnownInPredecessor(BI, DTU, DL, Options.AC)) + if (FoldCondBranchOnValueKnownInPredecessor(BI, DTU, DL, TTI, Options.AC)) return requestResimplify(); // Scan predecessor blocks for conditional branches. |