Skip to content

PR for llvm/llvm-project#66868 #705

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

Merged
merged 2 commits into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 34 additions & 27 deletions llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2126,9 +2126,10 @@ static void unswitchNontrivialInvariants(
Loop &L, Instruction &TI, ArrayRef<Value *> Invariants,
IVConditionInfo &PartialIVInfo, DominatorTree &DT, LoopInfo &LI,
AssumptionCache &AC,
function_ref<void(bool, bool, ArrayRef<Loop *>)> UnswitchCB,
function_ref<void(bool, bool, bool, ArrayRef<Loop *>)> UnswitchCB,
ScalarEvolution *SE, MemorySSAUpdater *MSSAU,
function_ref<void(Loop &, StringRef)> DestroyLoopCB, bool InsertFreeze) {
function_ref<void(Loop &, StringRef)> DestroyLoopCB, bool InsertFreeze,
bool InjectedCondition) {
auto *ParentBB = TI.getParent();
BranchInst *BI = dyn_cast<BranchInst>(&TI);
SwitchInst *SI = BI ? nullptr : cast<SwitchInst>(&TI);
Expand Down Expand Up @@ -2581,7 +2582,7 @@ static void unswitchNontrivialInvariants(
for (Loop *UpdatedL : llvm::concat<Loop *>(NonChildClonedLoops, HoistedLoops))
if (UpdatedL->getParentLoop() == ParentL)
SibLoops.push_back(UpdatedL);
UnswitchCB(IsStillLoop, PartiallyInvariant, SibLoops);
UnswitchCB(IsStillLoop, PartiallyInvariant, InjectedCondition, SibLoops);

if (MSSAU && VerifyMemorySSA)
MSSAU->getMemorySSA()->verifyMemorySSA();
Expand Down Expand Up @@ -2979,13 +2980,6 @@ static bool shouldTryInjectInvariantCondition(
/// the metadata.
bool shouldTryInjectBasingOnMetadata(const BranchInst *BI,
const BasicBlock *TakenSucc) {
// Skip branches that have already been unswithed this way. After successful
// unswitching of injected condition, we will still have a copy of this loop
// which looks exactly the same as original one. To prevent the 2nd attempt
// of unswitching it in the same pass, mark this branch as "nothing to do
// here".
if (BI->hasMetadata("llvm.invariant.condition.injection.disabled"))
return false;
SmallVector<uint32_t> Weights;
if (!extractBranchWeights(*BI, Weights))
return false;
Expand Down Expand Up @@ -3060,7 +3054,6 @@ injectPendingInvariantConditions(NonTrivialUnswitchCandidate Candidate, Loop &L,
auto *InjectedCond =
ICmpInst::Create(Instruction::ICmp, Pred, LHS, RHS, "injected.cond",
Preheader->getTerminator());
auto *OldCond = TI->getCondition();

BasicBlock *CheckBlock = BasicBlock::Create(Ctx, BB->getName() + ".check",
BB->getParent(), InLoopSucc);
Expand All @@ -3069,12 +3062,9 @@ injectPendingInvariantConditions(NonTrivialUnswitchCandidate Candidate, Loop &L,
Builder.CreateCondBr(InjectedCond, InLoopSucc, CheckBlock);

Builder.SetInsertPoint(CheckBlock);
auto *NewTerm = Builder.CreateCondBr(OldCond, InLoopSucc, OutOfLoopSucc);

Builder.CreateCondBr(TI->getCondition(), TI->getSuccessor(0),
TI->getSuccessor(1));
TI->eraseFromParent();
// Prevent infinite unswitching.
NewTerm->setMetadata("llvm.invariant.condition.injection.disabled",
MDNode::get(BB->getContext(), {}));

// Fixup phis.
for (auto &I : *InLoopSucc) {
Expand Down Expand Up @@ -3442,7 +3432,7 @@ static bool shouldInsertFreeze(Loop &L, Instruction &TI, DominatorTree &DT,
static bool unswitchBestCondition(
Loop &L, DominatorTree &DT, LoopInfo &LI, AssumptionCache &AC,
AAResults &AA, TargetTransformInfo &TTI,
function_ref<void(bool, bool, ArrayRef<Loop *>)> UnswitchCB,
function_ref<void(bool, bool, bool, ArrayRef<Loop *>)> UnswitchCB,
ScalarEvolution *SE, MemorySSAUpdater *MSSAU,
function_ref<void(Loop &, StringRef)> DestroyLoopCB) {
// Collect all invariant conditions within this loop (as opposed to an inner
Expand All @@ -3452,9 +3442,10 @@ static bool unswitchBestCondition(
Instruction *PartialIVCondBranch = nullptr;
collectUnswitchCandidates(UnswitchCandidates, PartialIVInfo,
PartialIVCondBranch, L, LI, AA, MSSAU);
collectUnswitchCandidatesWithInjections(UnswitchCandidates, PartialIVInfo,
PartialIVCondBranch, L, DT, LI, AA,
MSSAU);
if (!findOptionMDForLoop(&L, "llvm.loop.unswitch.injection.disable"))
collectUnswitchCandidatesWithInjections(UnswitchCandidates, PartialIVInfo,
PartialIVCondBranch, L, DT, LI, AA,
MSSAU);
// If we didn't find any candidates, we're done.
if (UnswitchCandidates.empty())
return false;
Expand All @@ -3475,8 +3466,11 @@ static bool unswitchBestCondition(
return false;
}

if (Best.hasPendingInjection())
bool InjectedCondition = false;
if (Best.hasPendingInjection()) {
Best = injectPendingInvariantConditions(Best, L, DT, LI, AC, MSSAU);
InjectedCondition = true;
}
assert(!Best.hasPendingInjection() &&
"All injections should have been done by now!");

Expand Down Expand Up @@ -3504,7 +3498,7 @@ static bool unswitchBestCondition(
<< ") terminator: " << *Best.TI << "\n");
unswitchNontrivialInvariants(L, *Best.TI, Best.Invariants, PartialIVInfo, DT,
LI, AC, UnswitchCB, SE, MSSAU, DestroyLoopCB,
InsertFreeze);
InsertFreeze, InjectedCondition);
return true;
}

Expand Down Expand Up @@ -3533,7 +3527,7 @@ static bool
unswitchLoop(Loop &L, DominatorTree &DT, LoopInfo &LI, AssumptionCache &AC,
AAResults &AA, TargetTransformInfo &TTI, bool Trivial,
bool NonTrivial,
function_ref<void(bool, bool, ArrayRef<Loop *>)> UnswitchCB,
function_ref<void(bool, bool, bool, ArrayRef<Loop *>)> UnswitchCB,
ScalarEvolution *SE, MemorySSAUpdater *MSSAU,
ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI,
function_ref<void(Loop &, StringRef)> DestroyLoopCB) {
Expand All @@ -3548,7 +3542,8 @@ unswitchLoop(Loop &L, DominatorTree &DT, LoopInfo &LI, AssumptionCache &AC,
if (Trivial && unswitchAllTrivialConditions(L, DT, LI, SE, MSSAU)) {
// If we unswitched successfully we will want to clean up the loop before
// processing it further so just mark it as unswitched and return.
UnswitchCB(/*CurrentLoopValid*/ true, false, {});
UnswitchCB(/*CurrentLoopValid*/ true, /*PartiallyInvariant*/ false,
/*InjectedCondition*/ false, {});
return true;
}

Expand Down Expand Up @@ -3644,6 +3639,7 @@ PreservedAnalyses SimpleLoopUnswitchPass::run(Loop &L, LoopAnalysisManager &AM,

auto UnswitchCB = [&L, &U, &LoopName](bool CurrentLoopValid,
bool PartiallyInvariant,
bool InjectedCondition,
ArrayRef<Loop *> NewLoops) {
// If we did a non-trivial unswitch, we have added new (cloned) loops.
if (!NewLoops.empty())
Expand All @@ -3663,6 +3659,16 @@ PreservedAnalyses SimpleLoopUnswitchPass::run(Loop &L, LoopAnalysisManager &AM,
Context, L.getLoopID(), {"llvm.loop.unswitch.partial"},
{DisableUnswitchMD});
L.setLoopID(NewLoopID);
} else if (InjectedCondition) {
// Do the same for injection of invariant conditions.
auto &Context = L.getHeader()->getContext();
MDNode *DisableUnswitchMD = MDNode::get(
Context,
MDString::get(Context, "llvm.loop.unswitch.injection.disable"));
MDNode *NewLoopID = makePostTransformationMetadata(
Context, L.getLoopID(), {"llvm.loop.unswitch.injection"},
{DisableUnswitchMD});
L.setLoopID(NewLoopID);
} else
U.revisitCurrentLoop();
} else
Expand Down Expand Up @@ -3755,6 +3761,7 @@ bool SimpleLoopUnswitchLegacyPass::runOnLoop(Loop *L, LPPassManager &LPM) {
auto *SE = SEWP ? &SEWP->getSE() : nullptr;

auto UnswitchCB = [&L, &LPM](bool CurrentLoopValid, bool PartiallyInvariant,
bool InjectedCondition,
ArrayRef<Loop *> NewLoops) {
// If we did a non-trivial unswitch, we have added new (cloned) loops.
for (auto *NewL : NewLoops)
Expand All @@ -3765,9 +3772,9 @@ bool SimpleLoopUnswitchLegacyPass::runOnLoop(Loop *L, LPPassManager &LPM) {
// but it is the best we can do in the old PM.
if (CurrentLoopValid) {
// If the current loop has been unswitched using a partially invariant
// condition, we should not re-add the current loop to avoid unswitching
// on the same condition again.
if (!PartiallyInvariant)
// condition or injected invariant condition, we should not re-add the
// current loop to avoid unswitching on the same condition again.
if (!PartiallyInvariant && !InjectedCondition)
LPM.addLoop(*L);
} else
LPM.markLoopAsDeleted(*L);
Expand Down
Loading