default:
llvm_unreachable("Invalid optimization level!");
- case 0:
- return PassBuilder::OptimizationLevel::O0;
-
case 1:
return PassBuilder::OptimizationLevel::O1;
ModulePassManager MPM(CodeGenOpts.DebugPassManager);
if (!CodeGenOpts.DisableLLVMPasses) {
- // Map our optimization levels into one of the distinct levels used to
- // configure the pipeline.
- PassBuilder::OptimizationLevel Level = mapToLevel(CodeGenOpts);
-
bool IsThinLTO = CodeGenOpts.PrepareForThinLTO;
bool IsLTO = CodeGenOpts.PrepareForLTO;
MPM.addPass(NameAnonGlobalPass());
}
} else {
+ // Map our optimization levels into one of the distinct levels used to
+ // configure the pipeline.
+ PassBuilder::OptimizationLevel Level = mapToLevel(CodeGenOpts);
+
// If we reached here with a non-empty index file name, then the index
// file was empty and we are not performing ThinLTO backend compilation
// (used in testing in a distributed build environment). Drop any the type
}
if (CodeGenOpts.OptimizationLevel == 0) {
- PB.runRegisteredEPCallbacks(MPM, Level, CodeGenOpts.DebugPassManager);
-
// FIXME: the backends do not handle matrix intrinsics currently. Make
// sure they are also lowered in O0. A lightweight version of the pass
// should run in the backend pipeline on demand.
+++ /dev/null
-// RUN: %clang -O0 %s -target bpf -g -c -o /dev/null -fexperimental-new-pass-manager
-// REQUIRES: bpf-registered-target
-
-struct ss {
- int a;
-};
-int foo() { return __builtin_btf_type_id(0, 0) + __builtin_preserve_type_info(*(struct ss *)0, 0); }
/// Register a callback for a default optimizer pipeline extension point
///
/// This extension point allows adding optimizations at the very end of the
- /// function optimization pipeline.
+ /// function optimization pipeline. A key difference between this and the
+ /// legacy PassManager's OptimizerLast callback is that this extension point
+ /// is not triggered at O0. Extensions to the O0 pipeline should append their
+ /// passes to the end of the overall pipeline.
void registerOptimizerLastEPCallback(
const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
OptimizerLastEPCallbacks.push_back(C);
}
- /// Run all registered extension point callbacks
- ///
- /// This runs the registered callbacks in the order they would be run in a
- /// typical build*Pipeline(). This allows for reusing register*EPCallback()
- /// between O0 and O[123] pipelines.
- void runRegisteredEPCallbacks(ModulePassManager &MPM, OptimizationLevel Level,
- bool DebugLogging);
-
/// Register a callback for parsing an AliasAnalysis Name to populate
/// the given AAManager \p AA
void registerParseAACallback(
return MPM;
}
-void PassBuilder::runRegisteredEPCallbacks(ModulePassManager &MPM,
- OptimizationLevel Level,
- bool DebugLogging) {
- assert(Level == OptimizationLevel::O0 &&
- "runRegisteredEPCallbacks should only be used with O0");
- for (auto &C : PipelineStartEPCallbacks)
- C(MPM, Level);
- if (!LateLoopOptimizationsEPCallbacks.empty()) {
- LoopPassManager LPM(DebugLogging);
- for (auto &C : LateLoopOptimizationsEPCallbacks)
- C(LPM, Level);
- MPM.addPass(createModuleToFunctionPassAdaptor(
- createFunctionToLoopPassAdaptor(std::move(LPM))));
- }
- if (!LoopOptimizerEndEPCallbacks.empty()) {
- LoopPassManager LPM(DebugLogging);
- for (auto &C : LoopOptimizerEndEPCallbacks)
- C(LPM, Level);
- MPM.addPass(createModuleToFunctionPassAdaptor(
- createFunctionToLoopPassAdaptor(std::move(LPM))));
- }
- if (!ScalarOptimizerLateEPCallbacks.empty()) {
- FunctionPassManager FPM(DebugLogging);
- for (auto &C : ScalarOptimizerLateEPCallbacks)
- C(FPM, Level);
- MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
- }
- if (!CGSCCOptimizerLateEPCallbacks.empty()) {
- CGSCCPassManager CGPM(DebugLogging);
- for (auto &C : CGSCCOptimizerLateEPCallbacks)
- C(CGPM, Level);
- MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
- }
- if (!VectorizerStartEPCallbacks.empty()) {
- FunctionPassManager FPM(DebugLogging);
- for (auto &C : VectorizerStartEPCallbacks)
- C(FPM, Level);
- MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
- }
- for (auto &C : OptimizerLastEPCallbacks)
- C(MPM, Level);
-}
-
AAManager PassBuilder::buildDefaultAAPipeline() {
AAManager AA;
MPM.addPass(createModuleToFunctionPassAdaptor(CoroCleanupPass()));
}
- runRegisteredEPCallbacks(MPM, L, DebugLogging);
-
// Do nothing else at all!
return Error::success();
}
; RUN: opt < %s -passes='default<O2>' | llc -march=bpfel -filetype=asm -o /dev/null -
-; RUN: opt < %s -passes='default<O0>' | llc -march=bpfel -filetype=asm -o /dev/null -
+; TODO: add -O0 once that's supported
; IR generated by
; $ cat /tmp/a.c
; CHECK-CALLGRAPH: Running analysis: CallGraphAnalysis
; CHECK-CALLGRAPH: Finished llvm::Module pass manager run
-;; If Polly is enabled, registerPollyPasses adds an ep-vectorizer-start callback.
-;; There may or may not be a function pass manager run.
-;; Add a no-op-function to unify the two cases.
; RUN: opt -disable-output -disable-verify -debug-pass-manager \
-; RUN: -passes='default<O0>' -passes-ep-vectorizer-start=no-op-function %s 2>&1 \
+; RUN: -passes='default<O0>' %s 2>&1 \
; RUN: | FileCheck %s --check-prefix=CHECK-O0
; CHECK-O0: Starting llvm::Module pass manager run
-; CHECK-O0-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}>
-; CHECK-O0-NEXT: Starting llvm::Function pass manager run
-; CHECK-O0-NEXT: Running pass: NoOpFunctionPass on foo
-; CHECK-O0-NEXT: Finished llvm::Function pass manager run
; CHECK-O0-NEXT: Finished llvm::Module pass manager run
; RUN: opt -disable-output -disable-verify -debug-pass-manager \
+++ /dev/null
-; RUN: opt -disable-output -debug-pass-manager -passes-ep-late-loop-optimizations=no-op-loop -passes='default<O0>' 2>&1 < %s | FileCheck %s
-; RUN: opt -disable-output -debug-pass-manager -passes-ep-loop-optimizer-end=no-op-loop -passes='default<O0>' 2>&1 < %s | FileCheck %s
-; RUN: opt -disable-output -debug-pass-manager -passes-ep-scalar-optimizer-late=no-op-function -passes='default<O0>' 2>&1 < %s | FileCheck %s
-; RUN: opt -disable-output -debug-pass-manager -passes-ep-cgscc-optimizer-late=no-op-cgscc -passes='default<O0>' 2>&1 < %s | FileCheck %s
-; RUN: opt -disable-output -debug-pass-manager -passes-ep-vectorizer-start=no-op-function -passes='default<O0>' 2>&1 < %s | FileCheck %s
-; RUN: opt -disable-output -debug-pass-manager -passes-ep-pipeline-start=no-op-module -passes='default<O0>' 2>&1 < %s | FileCheck %s
-; RUN: opt -disable-output -debug-pass-manager -passes-ep-optimizer-last=no-op-function -passes='default<O0>' 2>&1 < %s | FileCheck %s
-
-; CHECK: Running pass: NoOp
-
-declare void @bar() local_unnamed_addr
-
-define void @foo(i32 %n) local_unnamed_addr {
-entry:
- br label %loop
-loop:
- %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
- %iv.next = add i32 %iv, 1
- tail call void @bar()
- %cmp = icmp eq i32 %iv, %n
- br i1 %cmp, label %exit, label %loop
-exit:
- ret void
-}