aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/Local.cpp
diff options
context:
space:
mode:
authorChengjun <chengjunp@Nvidia.com>2024-09-25 03:41:13 -0700
committerGitHub <noreply@github.com>2024-09-25 12:41:13 +0200
commite4688b98cd2b86035a2b563a8db0819710d6275a (patch)
tree36e271a188564f0bbac44bc5ba3367cca32425b0 /llvm/lib/Transforms/Utils/Local.cpp
parentce6c236c965dc1bb5fa2257e17ea253a015705cc (diff)
downloadllvm-e4688b98cd2b86035a2b563a8db0819710d6275a.zip
llvm-e4688b98cd2b86035a2b563a8db0819710d6275a.tar.gz
llvm-e4688b98cd2b86035a2b563a8db0819710d6275a.tar.bz2
[SimplifyCFG] Avoid increasing too many phi entries when removing empty blocks (#104887)
Now in the simplifycfg and jumpthreading passes, we will remove the empty blocks (blocks only have phis and an unconditional branch). However, in some cases, this will increase size of the IR and slow down the compile of other passes dramatically. For example, we have the following CFG: 1. BB1 has 100 predecessors, and unconditionally branches to BB2 (does not have any other instructions). 2. BB2 has 100 phis. Then in this case, if we remove BB1, for every phi in BB2, we need to increase 99 entries (replace the incoming edge from BB1 with 100 edges from its predecessors). Then in total, we will increase 9900 phi entries, which can slow down the compile time for many other passes. Therefore, in this change, we add a check to see whether removing the empty blocks will increase lots of phi entries. Now, the threshold is 1000 (can be controlled by the command line option `max-phi-entries-increase-after-removing-empty-block`), which means that we will not remove an empty block if it will increase the total number of phi entries by 1000. This threshold is conservative and for most of the cases, we will not have such a large phi. So, this will only be triggered in some unusual IRs.
Diffstat (limited to 'llvm/lib/Transforms/Utils/Local.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/Local.cpp35
1 files changed, 34 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index 725b512..7659fc6 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -112,6 +112,12 @@ static cl::opt<unsigned> PHICSENumPHISmallSize(
"When the basic block contains not more than this number of PHI nodes, "
"perform a (faster!) exhaustive search instead of set-driven one."));
+static cl::opt<unsigned> MaxPhiEntriesIncreaseAfterRemovingEmptyBlock(
+ "max-phi-entries-increase-after-removing-empty-block", cl::init(1000),
+ cl::Hidden,
+ cl::desc("Stop removing an empty block if removing it will introduce more "
+ "than this number of phi entries in its successor"));
+
// Max recursion depth for collectBitParts used when detecting bswap and
// bitreverse idioms.
static const unsigned BitPartRecursionMaxDepth = 48;
@@ -1047,6 +1053,33 @@ CanRedirectPredsOfEmptyBBToSucc(BasicBlock *BB, BasicBlock *Succ,
return true;
}
+/// Check whether removing \p BB will make the phis in its \p Succ have too
+/// many incoming entries. This function does not check whether \p BB is
+/// foldable or not.
+static bool introduceTooManyPhiEntries(BasicBlock *BB, BasicBlock *Succ) {
+ // If BB only has one predecessor, then removing it will not introduce more
+ // incoming edges for phis.
+ if (BB->hasNPredecessors(1))
+ return false;
+ unsigned NumPreds = pred_size(BB);
+ unsigned NumChangedPhi = 0;
+ for (auto &Phi : Succ->phis()) {
+ // If the incoming value is a phi and the phi is defined in BB,
+ // then removing BB will not increase the total phi entries of the ir.
+ if (auto *IncomingPhi = dyn_cast<PHINode>(Phi.getIncomingValueForBlock(BB)))
+ if (IncomingPhi->getParent() == BB)
+ continue;
+ // Otherwise, we need to add entries to the phi
+ NumChangedPhi++;
+ }
+ // For every phi that needs to be changed, (NumPreds - 1) new entries will be
+ // added. If the total increase in phi entries exceeds
+ // MaxPhiEntriesIncreaseAfterRemovingEmptyBlock, it will be considered as
+ // introducing too many new phi entries.
+ return (NumPreds - 1) * NumChangedPhi >
+ MaxPhiEntriesIncreaseAfterRemovingEmptyBlock;
+}
+
/// Replace a value flowing from a block to a phi with
/// potentially multiple instances of that value flowing from the
/// block's predecessors to the phi.
@@ -1146,7 +1179,7 @@ bool llvm::TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB,
BBKillable ||
CanRedirectPredsOfEmptyBBToSucc(BB, Succ, BBPreds, SuccPreds, CommonPred);
- if (!BBKillable && !BBPhisMergeable)
+ if ((!BBKillable && !BBPhisMergeable) || introduceTooManyPhiEntries(BB, Succ))
return false;
// Check to see if merging these blocks/phis would cause conflicts for any of