-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[EntryExitInstrumenter] Move passes out of clang into LLVM default pipelines #92171
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 11 commits
df3f8df
3ea4de1
c3d3637
5d46226
5cabc69
e9c64d5
d095f41
e5da299
1a4e5fb
ee48568
fd92b90
b65cec9
9996036
1abdb86
27359fe
bee1fb2
e3f2097
3579930
9270233
34658c6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,27 @@ | ||
// REQUIRES: x86-registered-target | ||
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -finstrument-functions -O0 -o - -emit-llvm %s | FileCheck %s | ||
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -finstrument-functions -O2 -o - -emit-llvm %s | FileCheck %s | ||
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -finstrument-functions-after-inlining -O2 -o - -emit-llvm %s | FileCheck -check-prefix=NOINLINE %s | ||
// RUN: %clang_cc1 -disable-llvm-passes -triple x86_64-unknown-unknown -finstrument-functions -O0 -o - -emit-llvm %s | FileCheck %s | ||
// RUN: %clang_cc1 -disable-llvm-passes -triple x86_64-unknown-unknown -finstrument-functions -O2 -o - -emit-llvm %s | FileCheck %s | ||
// RUN: %clang_cc1 -disable-llvm-passes -triple x86_64-unknown-unknown -finstrument-functions-after-inlining -O2 -o - -emit-llvm %s | FileCheck -check-prefix=NOINLINE %s | ||
|
||
__attribute__((always_inline)) int leaf(int x) { | ||
return x; | ||
// CHECK-LABEL: define {{.*}} @leaf | ||
// CHECK: call void @__cyg_profile_func_enter | ||
// CHECK-NOT: cyg_profile | ||
// CHECK: call void @__cyg_profile_func_exit | ||
// CHECK-NOT: cyg_profile | ||
pasko marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// CHECK: ret | ||
} | ||
|
||
int root(int x) { | ||
return leaf(x); | ||
// CHECK-LABEL: define {{.*}} @root | ||
// CHECK: call void @__cyg_profile_func_enter | ||
// CHECK-NOT: cyg_profile | ||
|
||
// Inlined from leaf(): | ||
// CHECK: call void @__cyg_profile_func_enter | ||
// CHECK-NOT: cyg_profile | ||
// CHECK: call void @__cyg_profile_func_exit | ||
// CHECK-NOT: cyg_profile | ||
|
||
// CHECK: call void @__cyg_profile_func_exit | ||
// CHECK: ret | ||
|
||
// NOINLINE-LABEL: define {{.*}} @root | ||
// NOINLINE: call void @__cyg_profile_func_enter | ||
// NOINLINE-NOT: cyg_profile | ||
// NOINLINE: call void @__cyg_profile_func_exit | ||
// NOINLINE-NOT: cyg_profile | ||
// NOINLINE: ret | ||
} | ||
|
||
// CHECK: attributes #0 = { alwaysinline {{.*}} "instrument-function-entry"="__cyg_profile_func_enter" "instrument-function-exit"="__cyg_profile_func_exit" | ||
// CHECK: attributes #1 = { {{.*}} "instrument-function-entry"="__cyg_profile_func_enter" "instrument-function-exit"="__cyg_profile_func_exit" | ||
// NOINLINE: attributes #0 = { alwaysinline {{.*}} "instrument-function-entry-inlined"="__cyg_profile_func_enter" "instrument-function-exit-inlined"="__cyg_profile_func_exit" | ||
pasko marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// NOINLINE: attributes #1 = { {{.*}} "instrument-function-entry-inlined"="__cyg_profile_func_enter" "instrument-function-exit-inlined"="__cyg_profile_func_exit" |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -127,6 +127,7 @@ | |
#include "llvm/Transforms/Utils/AssumeBundleBuilder.h" | ||
#include "llvm/Transforms/Utils/CanonicalizeAliases.h" | ||
#include "llvm/Transforms/Utils/CountVisits.h" | ||
#include "llvm/Transforms/Utils/EntryExitInstrumenter.h" | ||
#include "llvm/Transforms/Utils/InjectTLIMappings.h" | ||
#include "llvm/Transforms/Utils/LibCallsShrinkWrap.h" | ||
#include "llvm/Transforms/Utils/Mem2Reg.h" | ||
|
@@ -395,6 +396,11 @@ static bool isLTOPreLink(ThinOrFullLTOPhase Phase) { | |
Phase == ThinOrFullLTOPhase::FullLTOPreLink; | ||
} | ||
|
||
static bool isLTOPostLink(ThinOrFullLTOPhase Phase) { | ||
return Phase == ThinOrFullLTOPhase::ThinLTOPostLink || | ||
Phase == ThinOrFullLTOPhase::FullLTOPostLink; | ||
} | ||
|
||
// TODO: Investigate the cost/benefit of tail call elimination on debugging. | ||
FunctionPassManager | ||
PassBuilder::buildO1FunctionSimplificationPipeline(OptimizationLevel Level, | ||
|
@@ -1030,6 +1036,12 @@ PassBuilder::buildModuleSimplificationPipeline(OptimizationLevel Level, | |
Phase != ThinOrFullLTOPhase::ThinLTOPostLink) | ||
MPM.addPass(SampleProfileProbePass(TM)); | ||
|
||
// Instrument function entry and exit before all inlining. | ||
if (!isLTOPostLink(Phase)) { | ||
MPM.addPass(createModuleToFunctionPassAdaptor( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. actually is it possible to add this into sorry for suggesting this so late, since it'll require updating all the pipeline tests... but first check that none of the other tests fail There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tried this, and all non-pipeline tests pass. Though in my local FDO+ThinLTO reproducer I saw this causes This behaviour surprised me. The bare instrumentation does not move with the change. Is removing the module to function pass adaptor making something easier to inline later on? I'd like to investigate, but I am afraid I'll need some clues :) The change:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the check for I'm not sure why you're seeing that behavior if we're only running the post-inline instrumenter once in the codegen pipeline There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if you have a small local repro, you can pass There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Removed. Indeed there is an assertion for this a few lines prior.
Apparently I made a mistake when building the reproducer. When checking today I saw everything working as expected, i.e. <=1 bare hooks inserted per function in the final DSO. Sorry for the noise. |
||
EntryExitInstrumenterPass(/*PostInlining=*/false))); | ||
} | ||
|
||
bool HasSampleProfile = PGOOpt && (PGOOpt->Action == PGOOptions::SampleUse); | ||
|
||
// In ThinLTO mode, when flattened profile is used, all the available | ||
|
@@ -2048,6 +2060,10 @@ ModulePassManager PassBuilder::buildO0DefaultPipeline(OptimizationLevel Level, | |
/*IsCS=*/false, PGOOpt->AtomicCounterUpdate, PGOOpt->ProfileFile, | ||
PGOOpt->ProfileRemappingFile, PGOOpt->FS); | ||
|
||
// Instrument function entry and exit before all inlining. | ||
MPM.addPass(createModuleToFunctionPassAdaptor( | ||
EntryExitInstrumenterPass(/*PostInlining=*/false))); | ||
|
||
invokePipelineStartEPCallbacks(MPM, Level); | ||
|
||
if (PGOOpt && PGOOpt->DebugInfoForProfiling) | ||
|
Uh oh!
There was an error while loading. Please reload this page.