diff --git a/include/llvm/Transforms/Scalar/LowerExpectIntrinsic.h b/include/llvm/Transforms/Scalar/LowerExpectIntrinsic.h new file mode 100644 index 00000000000..40283203f3a --- /dev/null +++ b/include/llvm/Transforms/Scalar/LowerExpectIntrinsic.h @@ -0,0 +1,40 @@ +//===- LowerExpectIntrinsic.h - LowerExpectIntrinsic pass -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// +/// The header file for the LowerExpectIntrinsic pass as used by the new pass +/// manager. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_SCALAR_LOWEREXPECTINTRINSIC_H +#define LLVM_TRANSFORMS_SCALAR_LOWEREXPECTINTRINSIC_H + +#include "llvm/IR/Function.h" +#include "llvm/IR/PassManager.h" + +namespace llvm { + +class LowerExpectIntrinsicPass { +public: + static StringRef name() { return "LowerExpectIntrinsicPass"; } + + /// \brief Run the pass over the function. + /// + /// This will lower all of th expect intrinsic calls in this function into + /// branch weight metadata. That metadata will subsequently feed the analysis + /// of the probabilities and frequencies of the CFG. After running this pass, + /// no more expect intrinsics remain, allowing the rest of the optimizer to + /// ignore them. + PreservedAnalyses run(Function &F); +}; + +} + +#endif diff --git a/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp b/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp index 0cea5c5bc59..0c47cbd5bfd 100644 --- a/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp +++ b/lib/Transforms/Scalar/LowerExpectIntrinsic.cpp @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" #include "llvm/IR/BasicBlock.h" @@ -25,6 +25,7 @@ #include "llvm/Pass.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" +#include "llvm/Transforms/Scalar.h" using namespace llvm; @@ -40,24 +41,6 @@ static cl::opt UnlikelyBranchWeight("unlikely-branch-weight", cl::Hidden, cl::init(4), cl::desc("Weight of the branch unlikely to be taken (default = 4)")); -namespace { -/// \brief Legacy pass for lowering expect intrinsics out of the IR. -/// -/// When this pass is run over a function it uses expect intrinsics which feed -/// branches and switches to provide branch weight metadata for those -/// terminators. It then removes the expect intrinsics from the IR so the rest -/// of the optimizer can ignore them. -class LowerExpectIntrinsic : public FunctionPass { -public: - static char ID; - LowerExpectIntrinsic() : FunctionPass(ID) { - initializeLowerExpectIntrinsicPass(*PassRegistry::getPassRegistry()); - } - - bool runOnFunction(Function &F) override; -}; -} - static bool handleSwitchExpect(SwitchInst &SI) { CallInst *CI = dyn_cast(SI.getCondition()); if (!CI) @@ -143,7 +126,7 @@ static bool handleBranchExpect(BranchInst &BI) { return true; } -bool LowerExpectIntrinsic::runOnFunction(Function &F) { +static bool lowerExpectIntrinsic(Function &F) { bool Changed = false; for (BasicBlock &BB : F) { @@ -175,6 +158,31 @@ bool LowerExpectIntrinsic::runOnFunction(Function &F) { return Changed; } +PreservedAnalyses LowerExpectIntrinsicPass::run(Function &F) { + if (lowerExpectIntrinsic(F)) + return PreservedAnalyses::none(); + + return PreservedAnalyses::all(); +} + +namespace { +/// \brief Legacy pass for lowering expect intrinsics out of the IR. +/// +/// When this pass is run over a function it uses expect intrinsics which feed +/// branches and switches to provide branch weight metadata for those +/// terminators. It then removes the expect intrinsics from the IR so the rest +/// of the optimizer can ignore them. +class LowerExpectIntrinsic : public FunctionPass { +public: + static char ID; + LowerExpectIntrinsic() : FunctionPass(ID) { + initializeLowerExpectIntrinsicPass(*PassRegistry::getPassRegistry()); + } + + bool runOnFunction(Function &F) override { return lowerExpectIntrinsic(F); } +}; +} + char LowerExpectIntrinsic::ID = 0; INITIALIZE_PASS(LowerExpectIntrinsic, "lower-expect", "Lower 'expect' Intrinsics", false, false) diff --git a/test/Transforms/LowerExpectIntrinsic/basic.ll b/test/Transforms/LowerExpectIntrinsic/basic.ll index b15edc71514..f4326c8393c 100644 --- a/test/Transforms/LowerExpectIntrinsic/basic.ll +++ b/test/Transforms/LowerExpectIntrinsic/basic.ll @@ -1,4 +1,5 @@ ; RUN: opt -lower-expect -strip-dead-prototypes -S -o - < %s | FileCheck %s +; RUN: opt -S -passes=lower-expect < %s | opt -strip-dead-prototypes -S | FileCheck %s ; CHECK-LABEL: @test1( define i32 @test1(i32 %x) nounwind uwtable ssp { diff --git a/tools/opt/PassRegistry.def b/tools/opt/PassRegistry.def index 2c1b36b01fd..9361d98c9a5 100644 --- a/tools/opt/PassRegistry.def +++ b/tools/opt/PassRegistry.def @@ -63,6 +63,7 @@ FUNCTION_ANALYSIS("targetlibinfo", TargetLibraryAnalysis()) FUNCTION_PASS("instcombine", InstCombinePass()) FUNCTION_PASS("invalidate", InvalidateAllAnalysesPass()) FUNCTION_PASS("no-op-function", NoOpFunctionPass()) +FUNCTION_PASS("lower-expect", LowerExpectIntrinsicPass()) FUNCTION_PASS("print", PrintFunctionPass(dbgs())) FUNCTION_PASS("print", AssumptionPrinterPass(dbgs())) FUNCTION_PASS("print", DominatorTreePrinterPass(dbgs())) diff --git a/tools/opt/Passes.cpp b/tools/opt/Passes.cpp index 1788e695d5e..149432ed3c5 100644 --- a/tools/opt/Passes.cpp +++ b/tools/opt/Passes.cpp @@ -26,6 +26,7 @@ #include "llvm/IR/Verifier.h" #include "llvm/Support/Debug.h" #include "llvm/Transforms/InstCombine/InstCombine.h" +#include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h" using namespace llvm;