[Pipelines] Do not run CoroSplit and CoroCleanup in LTO pre-link pipeline (#100205)
This is re-land of #90310 after making asan skip pre-split coroutines in #99415. Skip CoroSplit and CoroCleanup in LTO pre-link pipeline so that CoroElide can happen after callee coroutine is imported into caller's module in ThinLTO.
This commit is contained in:
parent
ee6d932b4f
commit
3a9ef4e69a
78
clang/test/CodeGenCoroutines/coro-elide-thinlto.cpp
Normal file
78
clang/test/CodeGenCoroutines/coro-elide-thinlto.cpp
Normal file
@ -0,0 +1,78 @@
|
||||
// REQUIRES: x86_64-linux
|
||||
// This tests that the coroutine elide optimization could happen succesfully with ThinLTO.
|
||||
// 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 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 coro-elide-caller.bc
|
||||
// RUN: llvm-lto --thinlto coro-elide-callee.bc coro-elide-caller.bc -o summary
|
||||
// RUN: %clang_cc1 -O2 -x ir coro-elide-caller.bc -fthinlto-index=summary.thinlto.bc -emit-llvm -o - | FileCheck %s
|
||||
|
||||
//--- coro-elide-task.h
|
||||
#pragma once
|
||||
#include "Inputs/coroutine.h"
|
||||
|
||||
struct Task {
|
||||
struct promise_type {
|
||||
struct FinalAwaiter {
|
||||
bool await_ready() const noexcept { return false; }
|
||||
template <typename PromiseType>
|
||||
std::coroutine_handle<> await_suspend(std::coroutine_handle<PromiseType> h) noexcept {
|
||||
if (!h)
|
||||
return std::noop_coroutine();
|
||||
return h.promise().continuation;
|
||||
}
|
||||
void await_resume() noexcept {}
|
||||
};
|
||||
Task get_return_object() noexcept {
|
||||
return std::coroutine_handle<promise_type>::from_promise(*this);
|
||||
}
|
||||
std::suspend_always initial_suspend() noexcept { return {}; }
|
||||
FinalAwaiter final_suspend() noexcept { return {}; }
|
||||
void unhandled_exception() noexcept {}
|
||||
void return_value(int x) noexcept {
|
||||
_value = x;
|
||||
}
|
||||
std::coroutine_handle<> continuation;
|
||||
int _value;
|
||||
};
|
||||
|
||||
Task(std::coroutine_handle<promise_type> handle) : handle(handle) {}
|
||||
~Task() {
|
||||
if (handle)
|
||||
handle.destroy();
|
||||
}
|
||||
|
||||
struct Awaiter {
|
||||
bool await_ready() const noexcept { return false; }
|
||||
void await_suspend(std::coroutine_handle<void> continuation) noexcept {}
|
||||
int await_resume() noexcept {
|
||||
return 43;
|
||||
}
|
||||
};
|
||||
|
||||
auto operator co_await() {
|
||||
return Awaiter{};
|
||||
}
|
||||
|
||||
private:
|
||||
std::coroutine_handle<promise_type> handle;
|
||||
};
|
||||
|
||||
//--- coro-elide-callee.cpp
|
||||
#include "coro-elide-task.h"
|
||||
Task task0() {
|
||||
co_return 43;
|
||||
}
|
||||
|
||||
//--- coro-elide-caller.cpp
|
||||
#include "coro-elide-task.h"
|
||||
|
||||
Task task0();
|
||||
|
||||
Task task1() {
|
||||
co_return co_await task0();
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define{{.*}} void @_Z5task1v.resume
|
||||
// CHECK-NOT: {{.*}}_Znwm
|
||||
@ -979,7 +979,8 @@ PassBuilder::buildInlinerPipeline(OptimizationLevel Level,
|
||||
MainCGPipeline.addPass(createCGSCCToFunctionPassAdaptor(
|
||||
RequireAnalysisPass<ShouldNotRunFunctionPassesAnalysis, Function>()));
|
||||
|
||||
MainCGPipeline.addPass(CoroSplitPass(Level != OptimizationLevel::O0));
|
||||
if (Phase != ThinOrFullLTOPhase::ThinLTOPreLink)
|
||||
MainCGPipeline.addPass(CoroSplitPass(Level != OptimizationLevel::O0));
|
||||
|
||||
// Make sure we don't affect potential future NoRerun CGSCC adaptors.
|
||||
MIWP.addLateModulePass(createModuleToFunctionPassAdaptor(
|
||||
@ -1021,8 +1022,9 @@ PassBuilder::buildModuleInlinerPipeline(OptimizationLevel Level,
|
||||
buildFunctionSimplificationPipeline(Level, Phase),
|
||||
PTO.EagerlyInvalidateAnalyses));
|
||||
|
||||
MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(
|
||||
CoroSplitPass(Level != OptimizationLevel::O0)));
|
||||
if (Phase != ThinOrFullLTOPhase::ThinLTOPreLink)
|
||||
MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(
|
||||
CoroSplitPass(Level != OptimizationLevel::O0)));
|
||||
|
||||
return MPM;
|
||||
}
|
||||
@ -1219,7 +1221,8 @@ PassBuilder::buildModuleSimplificationPipeline(OptimizationLevel Level,
|
||||
// and argument promotion.
|
||||
MPM.addPass(DeadArgumentEliminationPass());
|
||||
|
||||
MPM.addPass(CoroCleanupPass());
|
||||
if (Phase != ThinOrFullLTOPhase::ThinLTOPreLink)
|
||||
MPM.addPass(CoroCleanupPass());
|
||||
|
||||
// Optimize globals now that functions are fully simplified.
|
||||
MPM.addPass(GlobalOptPass());
|
||||
|
||||
@ -184,12 +184,10 @@
|
||||
; 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-EXT: Running pass: {{.*}}::Bye
|
||||
|
||||
@ -183,12 +183,10 @@
|
||||
; 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
|
||||
|
||||
@ -148,12 +148,10 @@
|
||||
; 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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user