Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SimplifyCFG] Avoid increasing too many phi entries when removing empty blocks #104887

Merged
merged 8 commits into from
Sep 25, 2024
36 changes: 35 additions & 1 deletion llvm/lib/Transforms/Utils/Local.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -1047,6 +1053,34 @@ CanRedirectPredsOfEmptyBBToSucc(BasicBlock *BB, BasicBlock *Succ,
return true;
}

// Check whether removing BB will make the phis in its Succ have too
// many incoming entries. This function does not check whether BB is foldable
// or not.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Check whether removing BB will make the phis in its Succ have too
// many incoming entries. This function does not check whether BB is foldable
// or not.
/// 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 (PHINode *IncomingPhi =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing test for this case.

Chengjunp marked this conversation as resolved.
Show resolved Hide resolved
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.
Expand Down Expand Up @@ -1146,7 +1180,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
Expand Down
Loading
Loading