https://github.com/apolloww created https://github.com/llvm/llvm-project/pull/107153
#100205 skips CoroSplit and CoroCleanup in ThinLTO pre-link pipeline unconditionally. It defers coroutine optimizations to ThinLTO post-link so that across-module CoroElide is possible by leaving coroutine functions in pre-split state after pre-link. However, this makes the bitcode module unconsumable directly by codegen passes because of the coroutine intrinsics. With -defer-thinlto-prelink-coro-split, the deferral action is made explicit and conditional. >From 559ce8f93a69309332e77d5e8a9db52339c66acb Mon Sep 17 00:00:00 2001 From: Wei Wang <wang...@meta.com> Date: Tue, 3 Sep 2024 10:17:05 -0700 Subject: [PATCH] Introduce -defer-thinlto-prelink-coro-split that skips CoroSplit in LTO pre-link pipeline --- .../CodeGenCoroutines/coro-elide-thinlto.cpp | 6 +-- llvm/lib/Passes/PassBuilderPipelines.cpp | 15 ++++++-- .../Other/new-pm-thinlto-prelink-defaults.ll | 37 +++++++++++-------- .../new-pm-thinlto-prelink-pgo-defaults.ll | 2 + ...w-pm-thinlto-prelink-samplepgo-defaults.ll | 2 + 5 files changed, 40 insertions(+), 22 deletions(-) diff --git a/clang/test/CodeGenCoroutines/coro-elide-thinlto.cpp b/clang/test/CodeGenCoroutines/coro-elide-thinlto.cpp index 54063cf0704aad..4e328c53b17fcc 100644 --- a/clang/test/CodeGenCoroutines/coro-elide-thinlto.cpp +++ b/clang/test/CodeGenCoroutines/coro-elide-thinlto.cpp @@ -1,10 +1,10 @@ // REQUIRES: x86_64-linux -// This tests that the coroutine elide optimization could happen succesfully with ThinLTO. +// This tests that the coroutine elide optimization could happen succesfully with ThinLTO when coro-split is deferred to ThinLTO post-link. // This test is adapted from coro-elide.cpp and splits functions into two files. // // RUN: split-file %s %t -// RUN: %clang --target=x86_64-linux -std=c++20 -O2 -flto=thin -I %S -c %t/coro-elide-callee.cpp -o %t/coro-elide-callee.bc -// RUN: %clang --target=x86_64-linux -std=c++20 -O2 -flto=thin -I %S -c %t/coro-elide-caller.cpp -o %t/coro-elide-caller.bc +// RUN: %clang --target=x86_64-linux -std=c++20 -O2 -flto=thin -mllvm -defer-thinlto-prelink-coro-split -I %S -c %t/coro-elide-callee.cpp -o %t/coro-elide-callee.bc +// RUN: %clang --target=x86_64-linux -std=c++20 -O2 -flto=thin -mllvm -defer-thinlto-prelink-coro-split -I %S -c %t/coro-elide-caller.cpp -o %t/coro-elide-caller.bc // RUN: llvm-lto --thinlto %t/coro-elide-callee.bc %t/coro-elide-caller.bc -o %t/summary // RUN: %clang_cc1 -O2 -x ir %t/coro-elide-caller.bc -fthinlto-index=%t/summary.thinlto.bc -emit-llvm -o - | FileCheck %s diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp index 9c3d49cabbd38c..58b33a3f1a0d03 100644 --- a/llvm/lib/Passes/PassBuilderPipelines.cpp +++ b/llvm/lib/Passes/PassBuilderPipelines.cpp @@ -305,6 +305,12 @@ static cl::opt<bool> UseLoopVersioningLICM( "enable-loop-versioning-licm", cl::init(false), cl::Hidden, cl::desc("Enable the experimental Loop Versioning LICM pass")); +static cl::opt<bool> DeferThinLTOPreLinkCoroSplit( + "defer-thinlto-prelink-coro-split", cl::init(false), cl::Hidden, + cl::desc("Do not run CoroSplit pass in ThinLTO pre-link pipeline. " + "This allows coroutine optimizations to be run in the ThinLTO " + "post-link pipeline.")); + extern cl::opt<std::string> UseCtxProfile; namespace llvm { @@ -984,7 +990,8 @@ PassBuilder::buildInlinerPipeline(OptimizationLevel Level, MainCGPipeline.addPass(createCGSCCToFunctionPassAdaptor( RequireAnalysisPass<ShouldNotRunFunctionPassesAnalysis, Function>())); - if (Phase != ThinOrFullLTOPhase::ThinLTOPreLink) + if (Phase != ThinOrFullLTOPhase::ThinLTOPreLink || + !DeferThinLTOPreLinkCoroSplit) MainCGPipeline.addPass(CoroSplitPass(Level != OptimizationLevel::O0)); // Make sure we don't affect potential future NoRerun CGSCC adaptors. @@ -1027,7 +1034,8 @@ PassBuilder::buildModuleInlinerPipeline(OptimizationLevel Level, buildFunctionSimplificationPipeline(Level, Phase), PTO.EagerlyInvalidateAnalyses)); - if (Phase != ThinOrFullLTOPhase::ThinLTOPreLink) + if (Phase != ThinOrFullLTOPhase::ThinLTOPreLink || + !DeferThinLTOPreLinkCoroSplit) MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor( CoroSplitPass(Level != OptimizationLevel::O0))); @@ -1236,7 +1244,8 @@ PassBuilder::buildModuleSimplificationPipeline(OptimizationLevel Level, // and argument promotion. MPM.addPass(DeadArgumentEliminationPass()); - if (Phase != ThinOrFullLTOPhase::ThinLTOPreLink) + if (Phase != ThinOrFullLTOPhase::ThinLTOPreLink || + !DeferThinLTOPreLinkCoroSplit) MPM.addPass(CoroCleanupPass()); // Optimize globals now that functions are fully simplified. diff --git a/llvm/test/Other/new-pm-thinlto-prelink-defaults.ll b/llvm/test/Other/new-pm-thinlto-prelink-defaults.ll index ab04f80abc5722..b950a99ce0dd32 100644 --- a/llvm/test/Other/new-pm-thinlto-prelink-defaults.ll +++ b/llvm/test/Other/new-pm-thinlto-prelink-defaults.ll @@ -10,52 +10,55 @@ ; Prelink pipelines: ; RUN: opt -disable-verify -verify-analysis-invalidation=0 -eagerly-invalidate-analyses=0 -debug-pass-manager \ ; RUN: -passes='thinlto-pre-link<O1>' -S %s 2>&1 \ -; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O1,CHECK-O-NODIS +; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O1,CHECK-O-NODIS,CHECK-O-CORO ; RUN: opt -disable-verify -verify-analysis-invalidation=0 -eagerly-invalidate-analyses=0 -debug-pass-manager \ ; RUN: -unified-lto -passes='lto-pre-link<O1>' -S %s 2>&1 \ -; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O1,CHECK-O-NODIS +; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O1,CHECK-O-NODIS,CHECK-O-CORO ; RUN: opt -disable-verify -verify-analysis-invalidation=0 -eagerly-invalidate-analyses=0 -debug-pass-manager \ ; RUN: -passes='thinlto-pre-link<O2>' -S %s 2>&1 \ -; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O2,CHECK-O23SZ,CHECK-O-NODIS +; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O2,CHECK-O23SZ,CHECK-O-NODIS,CHECK-O-CORO ; RUN: opt -disable-verify -verify-analysis-invalidation=0 -eagerly-invalidate-analyses=0 -debug-pass-manager \ ; RUN: -unified-lto -passes='lto-pre-link<O2>' -S %s 2>&1 \ -; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O2,CHECK-O23SZ,CHECK-O-NODIS +; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O2,CHECK-O23SZ,CHECK-O-NODIS,CHECK-O-CORO ; RUN: opt -disable-verify -verify-analysis-invalidation=0 -eagerly-invalidate-analyses=0 -debug-pass-manager \ ; RUN: -passes='thinlto-pre-link<O3>' -S -passes-ep-pipeline-start='no-op-module' %s 2>&1 \ -; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O3,CHECK-O23SZ,CHECK-O-NODIS,CHECK-EP-PIPELINE-START +; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O3,CHECK-O23SZ,CHECK-O-NODIS,CHECK-EP-PIPELINE-START,CHECK-O-CORO ; RUN: opt -disable-verify -verify-analysis-invalidation=0 -eagerly-invalidate-analyses=0 -debug-pass-manager \ ; RUN: -unified-lto -passes='lto-pre-link<O3>' -S -passes-ep-pipeline-start='no-op-module' %s 2>&1 \ -; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O3,CHECK-O23SZ,CHECK-O-NODIS,CHECK-EP-PIPELINE-START +; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O3,CHECK-O23SZ,CHECK-O-NODIS,CHECK-EP-PIPELINE-START,CHECK-O-CORO ; RUN: opt -disable-verify -verify-analysis-invalidation=0 -eagerly-invalidate-analyses=0 -debug-pass-manager \ ; RUN: -passes='thinlto-pre-link<O3>' -S -passes-ep-optimizer-early='no-op-module' %s 2>&1 \ -; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O3,CHECK-O23SZ,CHECK-O-NODIS,CHECK-EP-OPT-EARLY +; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O3,CHECK-O23SZ,CHECK-O-NODIS,CHECK-EP-OPT-EARLY,CHECK-O-CORO ; RUN: opt -disable-verify -verify-analysis-invalidation=0 -eagerly-invalidate-analyses=0 -debug-pass-manager \ ; RUN: -unified-lto -passes='lto-pre-link<O3>' -S -passes-ep-optimizer-early='no-op-module' %s 2>&1 \ -; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O3,CHECK-O23SZ,CHECK-O-NODIS,CHECK-EP-OPT-EARLY +; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O3,CHECK-O23SZ,CHECK-O-NODIS,CHECK-EP-OPT-EARLY,CHECK-O-CORO ; RUN: opt -disable-verify -verify-analysis-invalidation=0 -eagerly-invalidate-analyses=0 -debug-pass-manager \ ; RUN: -passes='thinlto-pre-link<O3>' -S -passes-ep-optimizer-last='no-op-module' %s 2>&1 \ -; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O3,CHECK-O23SZ,CHECK-O-NODIS,CHECK-EP-OPT-LAST +; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O3,CHECK-O23SZ,CHECK-O-NODIS,CHECK-EP-OPT-LAST,CHECK-O-CORO ; RUN: opt -disable-verify -verify-analysis-invalidation=0 -eagerly-invalidate-analyses=0 -debug-pass-manager \ ; RUN: -unified-lto -passes='lto-pre-link<O3>' -S -passes-ep-optimizer-last='no-op-module' %s 2>&1 \ -; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O3,CHECK-O23SZ,CHECK-O-NODIS,CHECK-EP-OPT-LAST +; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O3,CHECK-O23SZ,CHECK-O-NODIS,CHECK-EP-OPT-LAST,CHECK-O-CORO ; RUN: opt -disable-verify -verify-analysis-invalidation=0 -eagerly-invalidate-analyses=0 -debug-pass-manager \ ; RUN: -passes='thinlto-pre-link<Os>' -S %s 2>&1 \ -; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O23SZ,CHECK-O-NODIS +; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O23SZ,CHECK-O-NODIS,CHECK-O-CORO ; RUN: opt -disable-verify -verify-analysis-invalidation=0 -eagerly-invalidate-analyses=0 -debug-pass-manager \ ; RUN: -unified-lto -passes='lto-pre-link<Os>' -S %s 2>&1 \ -; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O23SZ,CHECK-O-NODIS +; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O23SZ,CHECK-O-NODIS,CHECK-O-CORO ; RUN: opt -disable-verify -verify-analysis-invalidation=0 -eagerly-invalidate-analyses=0 -debug-pass-manager \ ; RUN: -passes='thinlto-pre-link<Oz>' -S %s 2>&1 \ -; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O23SZ,CHECK-O-NODIS +; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O23SZ,CHECK-O-NODIS,CHECK-O-CORO ; RUN: opt -disable-verify -verify-analysis-invalidation=0 -eagerly-invalidate-analyses=0 -debug-pass-manager \ ; RUN: -unified-lto -passes='lto-pre-link<Oz>' -S %s 2>&1 \ -; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O23SZ,CHECK-O-NODIS +; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O23SZ,CHECK-O-NODIS,CHECK-O-CORO ; RUN: opt -disable-verify -verify-analysis-invalidation=0 -eagerly-invalidate-analyses=0 -debug-pass-manager -debug-info-for-profiling \ ; RUN: -passes='thinlto-pre-link<O2>' -S %s 2>&1 \ -; RUN: | FileCheck %s --check-prefixes=CHECK-DIS,CHECK-O,CHECK-O2,CHECK-O23SZ +; RUN: | FileCheck %s --check-prefixes=CHECK-DIS,CHECK-O,CHECK-O2,CHECK-O23SZ,CHECK-O-CORO ; RUN: opt -disable-verify -verify-analysis-invalidation=0 -eagerly-invalidate-analyses=0 -debug-pass-manager -debug-info-for-profiling \ ; RUN: -unified-lto -passes='lto-pre-link<O2>' -S %s 2>&1 \ -; RUN: | FileCheck %s --check-prefixes=CHECK-DIS,CHECK-O,CHECK-O2,CHECK-O23SZ +; RUN: | FileCheck %s --check-prefixes=CHECK-DIS,CHECK-O,CHECK-O2,CHECK-O23SZ,CHECK-O-CORO +; RUN: opt -disable-verify -verify-analysis-invalidation=0 -eagerly-invalidate-analyses=0 -debug-pass-manager \ +; RUN: -passes='thinlto-pre-link<O1>' -S -defer-thinlto-prelink-coro-split %s 2>&1 \ +; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O1,CHECK-O-NODIS ; ; Suppress FileCheck --allow-unused-prefixes=false diagnostics. @@ -184,10 +187,12 @@ ; CHECK-O-NEXT: Running pass: PostOrderFunctionAttrsPass ; CHECK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis ; CHECK-O-NEXT: Running analysis: ShouldNotRunFunctionPassesAnalysis +; CHECK-O-CORO: Running pass: CoroSplitPass ; CHECK-O-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis ; CHECK-O-NEXT: Invalidating analysis: ShouldNotRunFunctionPassesAnalysis ; CHECK-O-NEXT: Invalidating analysis: InlineAdvisorAnalysis ; CHECK-O-NEXT: Running pass: DeadArgumentEliminationPass +; CHECK-O-CORO-NEXT: Running pass: CoroCleanupPass ; CHECK-O-NEXT: Running pass: GlobalOptPass ; CHECK-O-NEXT: Running pass: GlobalDCEPass ; CHECK-EXT: Running pass: {{.*}}::Bye diff --git a/llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll index cb49cbd22d60c0..e74f88c1a3bf99 100644 --- a/llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll +++ b/llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll @@ -183,10 +183,12 @@ ; CHECK-O-NEXT: Running pass: PostOrderFunctionAttrsPass ; CHECK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis ; CHECK-O-NEXT: Running analysis: ShouldNotRunFunctionPassesAnalysis +; CHECK-O-NEXT: Running pass: CoroSplitPass ; CHECK-O-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis ; CHECK-O-NEXT: Invalidating analysis: ShouldNotRunFunctionPassesAnalysis ; CHECK-O-NEXT: Invalidating analysis: InlineAdvisorAnalysis ; CHECK-O-NEXT: Running pass: DeadArgumentEliminationPass +; CHECK-O-NEXT: Running pass: CoroCleanupPass ; CHECK-O-NEXT: Running pass: GlobalOptPass ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis on bar ; CHECK-O-NEXT: Running pass: GlobalDCEPass diff --git a/llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll b/llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll index 96e83493504426..0bb26330d000a0 100644 --- a/llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll +++ b/llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll @@ -148,10 +148,12 @@ ; CHECK-O-NEXT: Running pass: PostOrderFunctionAttrsPass ; CHECK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis ; CHECK-O-NEXT: Running analysis: ShouldNotRunFunctionPassesAnalysis +; CHECK-O-NEXT: Running pass: CoroSplitPass ; CHECK-O-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ShouldNotRunFunctionPassesAnalysis ; CHECK-O-NEXT: Invalidating analysis: ShouldNotRunFunctionPassesAnalysis ; CHECK-O-NEXT: Invalidating analysis: InlineAdvisorAnalysis ; CHECK-O-NEXT: Running pass: DeadArgumentEliminationPass +; CHECK-O-NEXT: Running pass: CoroCleanupPass ; CHECK-O-NEXT: Running pass: GlobalOptPass ; CHECK-O-NEXT: Running pass: GlobalDCEPass ; CHECK-O-NEXT: Running pass: AnnotationRemarksPass on foo _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits