mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +01:00
[NewPM][SimpleLoopUnswitch] Add option to not trivially unswitch
To help with debugging non-trivial unswitching issues. Don't care about the legacy pass, nobody is using it. If a pass's string params are empty (e.g. "simple-loop-unswitch"), don't default to the empty constructor for the pass params. We should still let the parser take care of it in case the parser has its own defaults. Reviewed By: asbirlea Differential Revision: https://reviews.llvm.org/D105933
This commit is contained in:
parent
74be1319be
commit
78dcef41e1
@ -61,9 +61,11 @@ namespace llvm {
|
||||
/// not currently implement that in any mode.
|
||||
class SimpleLoopUnswitchPass : public PassInfoMixin<SimpleLoopUnswitchPass> {
|
||||
bool NonTrivial;
|
||||
bool Trivial;
|
||||
|
||||
public:
|
||||
SimpleLoopUnswitchPass(bool NonTrivial = false) : NonTrivial(NonTrivial) {}
|
||||
SimpleLoopUnswitchPass(bool NonTrivial = false, bool Trivial = true)
|
||||
: NonTrivial(NonTrivial), Trivial(Trivial) {}
|
||||
|
||||
PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
|
||||
LoopStandardAnalysisResults &AR, LPMUpdater &U);
|
||||
|
@ -2091,9 +2091,8 @@ auto parsePassParameters(ParametersParseCallableT &&Parser, StringRef Name,
|
||||
assert(false &&
|
||||
"unable to strip pass name from parametrized pass specification");
|
||||
}
|
||||
if (Params.empty())
|
||||
return ParametersT{};
|
||||
if (!Params.consume_front("<") || !Params.consume_back(">")) {
|
||||
if (!Params.empty() &&
|
||||
(!Params.consume_front("<") || !Params.consume_back(">"))) {
|
||||
assert(false && "invalid format for parametrized pass name");
|
||||
}
|
||||
|
||||
@ -2234,15 +2233,17 @@ Expected<LoopVectorizeOptions> parseLoopVectorizeOptions(StringRef Params) {
|
||||
return Opts;
|
||||
}
|
||||
|
||||
Expected<bool> parseLoopUnswitchOptions(StringRef Params) {
|
||||
bool Result = false;
|
||||
Expected<std::pair<bool, bool>> parseLoopUnswitchOptions(StringRef Params) {
|
||||
std::pair<bool, bool> Result = {false, true};
|
||||
while (!Params.empty()) {
|
||||
StringRef ParamName;
|
||||
std::tie(ParamName, Params) = Params.split(';');
|
||||
|
||||
bool Enable = !ParamName.consume_front("no-");
|
||||
if (ParamName == "nontrivial") {
|
||||
Result = Enable;
|
||||
Result.first = Enable;
|
||||
} else if (ParamName == "trivial") {
|
||||
Result.second = Enable;
|
||||
} else {
|
||||
return make_error<StringError>(
|
||||
formatv("invalid LoopUnswitch pass parameter '{0}' ", ParamName)
|
||||
|
@ -445,9 +445,9 @@ LOOP_PASS("loop-versioning-licm", LoopVersioningLICMPass())
|
||||
#endif
|
||||
LOOP_PASS_WITH_PARAMS("simple-loop-unswitch",
|
||||
"SimpleLoopUnswitchPass",
|
||||
[](bool NonTrivial) {
|
||||
return SimpleLoopUnswitchPass(NonTrivial);
|
||||
[](std::pair<bool, bool> Params) {
|
||||
return SimpleLoopUnswitchPass(Params.first, Params.second);
|
||||
},
|
||||
parseLoopUnswitchOptions,
|
||||
"no-nontrivial;nontrivial")
|
||||
"nontrivial;no-nontrivial;trivial;no-trivial")
|
||||
#undef LOOP_PASS_WITH_PARAMS
|
||||
|
@ -2984,7 +2984,8 @@ static bool unswitchBestCondition(
|
||||
/// done.
|
||||
static bool
|
||||
unswitchLoop(Loop &L, DominatorTree &DT, LoopInfo &LI, AssumptionCache &AC,
|
||||
AAResults &AA, TargetTransformInfo &TTI, bool NonTrivial,
|
||||
AAResults &AA, TargetTransformInfo &TTI, bool Trivial,
|
||||
bool NonTrivial,
|
||||
function_ref<void(bool, bool, ArrayRef<Loop *>)> UnswitchCB,
|
||||
ScalarEvolution *SE, MemorySSAUpdater *MSSAU) {
|
||||
assert(L.isRecursivelyLCSSAForm(DT, LI) &&
|
||||
@ -2995,7 +2996,7 @@ unswitchLoop(Loop &L, DominatorTree &DT, LoopInfo &LI, AssumptionCache &AC,
|
||||
return false;
|
||||
|
||||
// Try trivial unswitch first before loop over other basic blocks in the loop.
|
||||
if (unswitchAllTrivialConditions(L, DT, LI, SE, MSSAU)) {
|
||||
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, {});
|
||||
@ -3087,7 +3088,7 @@ PreservedAnalyses SimpleLoopUnswitchPass::run(Loop &L, LoopAnalysisManager &AM,
|
||||
if (VerifyMemorySSA)
|
||||
AR.MSSA->verifyMemorySSA();
|
||||
}
|
||||
if (!unswitchLoop(L, AR.DT, AR.LI, AR.AC, AR.AA, AR.TTI, NonTrivial,
|
||||
if (!unswitchLoop(L, AR.DT, AR.LI, AR.AC, AR.AA, AR.TTI, Trivial, NonTrivial,
|
||||
UnswitchCB, &AR.SE,
|
||||
MSSAU.hasValue() ? MSSAU.getPointer() : nullptr))
|
||||
return PreservedAnalyses::all();
|
||||
@ -3181,7 +3182,7 @@ bool SimpleLoopUnswitchLegacyPass::runOnLoop(Loop *L, LPPassManager &LPM) {
|
||||
MSSA->verifyMemorySSA();
|
||||
|
||||
bool Changed =
|
||||
unswitchLoop(*L, DT, LI, AC, AA, TTI, NonTrivial, UnswitchCB, SE,
|
||||
unswitchLoop(*L, DT, LI, AC, AA, TTI, true, NonTrivial, UnswitchCB, SE,
|
||||
MSSAU.hasValue() ? MSSAU.getPointer() : nullptr);
|
||||
|
||||
if (MSSA && VerifyMemorySSA)
|
||||
|
@ -21,6 +21,6 @@
|
||||
; CHECK: Loop passes:
|
||||
; CHECK: no-op-loop
|
||||
; CHECK: Loop passes with params:
|
||||
; CHECK: simple-loop-unswitch<no-nontrivial;nontrivial>
|
||||
; CHECK: simple-loop-unswitch<nontrivial;no-nontrivial;trivial;no-trivial>
|
||||
; CHECK: Loop analyses:
|
||||
; CHECK: no-op-loop
|
||||
|
26
test/Transforms/SimpleLoopUnswitch/options.ll
Normal file
26
test/Transforms/SimpleLoopUnswitch/options.ll
Normal file
@ -0,0 +1,26 @@
|
||||
; RUN: opt -passes='simple-loop-unswitch<no-trivial>' -S < %s | FileCheck %s --check-prefix=NOTRIVIAL
|
||||
; RUN: opt -passes='simple-loop-unswitch' -S < %s | FileCheck %s --check-prefix=TRIVIAL
|
||||
; RUN: opt -passes='simple-loop-unswitch<trivial>' -S < %s | FileCheck %s --check-prefix=TRIVIAL
|
||||
|
||||
declare void @some_func() noreturn
|
||||
|
||||
; NOTRIVIAL-NOT: split
|
||||
; TRIVIAL: split
|
||||
define i32 @test1(i32* %var, i1 %cond1, i1 %cond2) {
|
||||
entry:
|
||||
br label %loop_begin
|
||||
|
||||
loop_begin:
|
||||
br i1 %cond1, label %continue, label %loop_exit ; first trivial condition
|
||||
|
||||
continue:
|
||||
%var_val = load i32, i32* %var
|
||||
br i1 %cond2, label %do_something, label %loop_exit ; second trivial condition
|
||||
|
||||
do_something:
|
||||
call void @some_func() noreturn nounwind
|
||||
br label %loop_begin
|
||||
|
||||
loop_exit:
|
||||
ret i32 0
|
||||
}
|
Loading…
Reference in New Issue
Block a user