diff options
author | Antonio Frighetto <me@antoniofrighetto.com> | 2025-08-18 17:40:08 +0200 |
---|---|---|
committer | Antonio Frighetto <me@antoniofrighetto.com> | 2025-08-18 17:40:08 +0200 |
commit | 33761df961627f9d057fa049509fc8ba8baaaf78 (patch) | |
tree | db256fcfb6b8fef291d5671f04bcee0491bdbef0 /llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp | |
parent | 17f5f5ba55972d1078ca24861d12ea8ffbeef9e2 (diff) | |
download | llvm-33761df961627f9d057fa049509fc8ba8baaaf78.zip llvm-33761df961627f9d057fa049509fc8ba8baaaf78.tar.gz llvm-33761df961627f9d057fa049509fc8ba8baaaf78.tar.bz2 |
Revert "[SimpleLoopUnswitch] Record loops from unswitching non-trivial conditions"
This reverts commit e9de32fd159d30cfd6fcc861b57b7e99ec2742ab due to
multiple performance regressions observed across downstream Numba
benchmarks (https://github.com/llvm/llvm-project/issues/138509#issuecomment-3193855772).
While avoiding non-trivial unswitches on newly-cloned loops helps
mitigate the pathological case reported in https://github.com/llvm/llvm-project/issues/138509,
it may as well make the IR less friendly to vectorization / loop-
canonicalization (in the test reported, previously no select with
loop-carried dependence existed in the new specialized loops),
leading the abovementioned approach to be reconsidered.
Diffstat (limited to 'llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp')
-rw-r--r-- | llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp | 49 |
1 files changed, 23 insertions, 26 deletions
diff --git a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp index f6959ca2..9b40fc0 100644 --- a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp +++ b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp @@ -2144,23 +2144,9 @@ void visitDomSubTree(DominatorTree &DT, BasicBlock *BB, CallableT Callable) { void postUnswitch(Loop &L, LPMUpdater &U, StringRef LoopName, bool CurrentLoopValid, bool PartiallyInvariant, bool InjectedCondition, ArrayRef<Loop *> NewLoops) { - auto RecordLoopAsUnswitched = [&](Loop *TargetLoop, StringRef Tag, - StringRef DisableTag) { - auto &Ctx = TargetLoop->getHeader()->getContext(); - MDNode *DisableMD = MDNode::get(Ctx, MDString::get(Ctx, DisableTag)); - MDNode *NewLoopID = makePostTransformationMetadata( - Ctx, TargetLoop->getLoopID(), {Tag}, {DisableMD}); - TargetLoop->setLoopID(NewLoopID); - }; - - // If we performed a non-trivial unswitch, we have added new cloned loops. - // Mark such newly-created loops as visited. - if (!NewLoops.empty()) { - for (Loop *NL : NewLoops) - RecordLoopAsUnswitched(NL, "llvm.loop.unswitch.nontrivial", - "llvm.loop.unswitch.nontrivial.disable"); + // If we did a non-trivial unswitch, we have added new (cloned) loops. + if (!NewLoops.empty()) U.addSiblingLoops(NewLoops); - } // If the current loop remains valid, we should revisit it to catch any // other unswitch opportunities. Otherwise, we need to mark it as deleted. @@ -2168,12 +2154,24 @@ void postUnswitch(Loop &L, LPMUpdater &U, StringRef LoopName, if (PartiallyInvariant) { // Mark the new loop as partially unswitched, to avoid unswitching on // the same condition again. - RecordLoopAsUnswitched(&L, "llvm.loop.unswitch.partial", - "llvm.loop.unswitch.partial.disable"); + auto &Context = L.getHeader()->getContext(); + MDNode *DisableUnswitchMD = MDNode::get( + Context, + MDString::get(Context, "llvm.loop.unswitch.partial.disable")); + MDNode *NewLoopID = makePostTransformationMetadata( + Context, L.getLoopID(), {"llvm.loop.unswitch.partial"}, + {DisableUnswitchMD}); + L.setLoopID(NewLoopID); } else if (InjectedCondition) { // Do the same for injection of invariant conditions. - RecordLoopAsUnswitched(&L, "llvm.loop.unswitch.injection", - "llvm.loop.unswitch.injection.disable"); + 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 @@ -2811,9 +2809,9 @@ static BranchInst *turnGuardIntoBranch(IntrinsicInst *GI, Loop &L, } /// Cost multiplier is a way to limit potentially exponential behavior -/// of loop-unswitch. Cost is multiplied in proportion of 2^number of unswitch -/// candidates available. Also consider the number of "sibling" loops with -/// the idea of accounting for previous unswitches that already happened on this +/// of loop-unswitch. Cost is multipied in proportion of 2^number of unswitch +/// candidates available. Also accounting for the number of "sibling" loops with +/// the idea to account for previous unswitches that already happened on this /// cluster of loops. There was an attempt to keep this formula simple, /// just enough to limit the worst case behavior. Even if it is not that simple /// now it is still not an attempt to provide a detailed heuristic size @@ -3509,9 +3507,8 @@ static bool unswitchBestCondition(Loop &L, DominatorTree &DT, LoopInfo &LI, SmallVector<NonTrivialUnswitchCandidate, 4> UnswitchCandidates; IVConditionInfo PartialIVInfo; Instruction *PartialIVCondBranch = nullptr; - if (!findOptionMDForLoop(&L, "llvm.loop.unswitch.nontrivial.disable")) - collectUnswitchCandidates(UnswitchCandidates, PartialIVInfo, - PartialIVCondBranch, L, LI, AA, MSSAU); + collectUnswitchCandidates(UnswitchCandidates, PartialIVInfo, + PartialIVCondBranch, L, LI, AA, MSSAU); if (!findOptionMDForLoop(&L, "llvm.loop.unswitch.injection.disable")) collectUnswitchCandidatesWithInjections(UnswitchCandidates, PartialIVInfo, PartialIVCondBranch, L, DT, LI, AA, |