diff --git a/llvm/include/llvm/Transforms/Utils/FixIrreducible.h b/llvm/include/llvm/Transforms/Utils/FixIrreducible.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/Transforms/Utils/FixIrreducible.h @@ -0,0 +1,20 @@ +//===- FixIrreducible.h - Convert irreducible control-flow into loops -----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_UTILS_FIXIRREDUCIBLE_H +#define LLVM_TRANSFORMS_UTILS_FIXIRREDUCIBLE_H + +#include "llvm/IR/PassManager.h" + +namespace llvm { +struct FixIrreduciblePass : PassInfoMixin { + PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); +}; +} // namespace llvm + +#endif // LLVM_TRANSFORMS_UTILS_FIXIRREDUCIBLE_H diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -196,6 +196,7 @@ #include "llvm/Transforms/Utils/CanonicalizeAliases.h" #include "llvm/Transforms/Utils/CanonicalizeFreezeInLoops.h" #include "llvm/Transforms/Utils/EntryExitInstrumenter.h" +#include "llvm/Transforms/Utils/FixIrreducible.h" #include "llvm/Transforms/Utils/InjectTLIMappings.h" #include "llvm/Transforms/Utils/LCSSA.h" #include "llvm/Transforms/Utils/LibCallsShrinkWrap.h" diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -205,6 +205,7 @@ FUNCTION_PASS("early-cse", EarlyCSEPass(/*UseMemorySSA=*/false)) FUNCTION_PASS("early-cse-memssa", EarlyCSEPass(/*UseMemorySSA=*/true)) FUNCTION_PASS("ee-instrument", EntryExitInstrumenterPass(/*PostInlining=*/false)) +FUNCTION_PASS("fix-irreducible", FixIrreduciblePass()) FUNCTION_PASS("make-guards-explicit", MakeGuardsExplicitPass()) FUNCTION_PASS("post-inline-ee-instrument", EntryExitInstrumenterPass(/*PostInlining=*/true)) FUNCTION_PASS("gvn-hoist", GVNHoistPass()) diff --git a/llvm/lib/Transforms/Utils/FixIrreducible.cpp b/llvm/lib/Transforms/Utils/FixIrreducible.cpp --- a/llvm/lib/Transforms/Utils/FixIrreducible.cpp +++ b/llvm/lib/Transforms/Utils/FixIrreducible.cpp @@ -66,6 +66,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Transforms/Utils/FixIrreducible.h" #include "llvm/ADT/SCCIterator.h" #include "llvm/Analysis/LoopIterator.h" #include "llvm/InitializePasses.h" @@ -304,11 +305,9 @@ return Changed; } -bool FixIrreducible::runOnFunction(Function &F) { +static bool FixIrreducibleImpl(Function &F, LoopInfo &LI, DominatorTree &DT) { LLVM_DEBUG(dbgs() << "===== Fix irreducible control-flow in function: " << F.getName() << "\n"); - auto &LI = getAnalysis().getLoopInfo(); - auto &DT = getAnalysis().getDomTree(); bool Changed = false; SmallVector WorkList; @@ -335,3 +334,21 @@ return Changed; } + +bool FixIrreducible::runOnFunction(Function &F) { + auto &LI = getAnalysis().getLoopInfo(); + auto &DT = getAnalysis().getDomTree(); + return FixIrreducibleImpl(F, LI, DT); +} + +PreservedAnalyses FixIrreduciblePass::run(Function &F, + FunctionAnalysisManager &AM) { + auto &LI = AM.getResult(F); + auto &DT = AM.getResult(F); + if (!FixIrreducibleImpl(F, LI, DT)) + return PreservedAnalyses::all(); + PreservedAnalyses PA; + PA.preserve(); + PA.preserve(); + return PA; +} diff --git a/llvm/test/Transforms/FixIrreducible/basic.ll b/llvm/test/Transforms/FixIrreducible/basic.ll --- a/llvm/test/Transforms/FixIrreducible/basic.ll +++ b/llvm/test/Transforms/FixIrreducible/basic.ll @@ -1,5 +1,6 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -fix-irreducible -S | FileCheck %s -check-prefix=CHECK +; RUN: opt < %s -passes=fix-irreducible -S | FileCheck %s -check-prefix=CHECK define i32 @basic(i1 %PredEntry, i1 %PredLeft, i1 %PredRight, i32 %X, i32 %Y) { ; CHECK-LABEL: @basic( diff --git a/llvm/test/Transforms/FixIrreducible/switch.ll b/llvm/test/Transforms/FixIrreducible/switch.ll --- a/llvm/test/Transforms/FixIrreducible/switch.ll +++ b/llvm/test/Transforms/FixIrreducible/switch.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt < %s -fix-irreducible -S | FileCheck %s +; RUN: opt < %s -fix-irreducible -enable-new-pm=0 -S | FileCheck %s define void @loop_1(i32 %Value, i1 %PredEntry, i1 %PredD) { ; CHECK-LABEL: @loop_1(