From cab81dd03813ac6333ad7fc031d72b84341fe2b9 Mon Sep 17 00:00:00 2001 From: Egor Pasko Date: Fri, 31 May 2024 21:48:45 +0200 Subject: [PATCH] [EntryExitInstrumenter] Move passes out of clang into LLVM default pipelines (#92171) Move EntryExitInstrumenter(PostInlining=true) to as late as possible and EntryExitInstrumenter(PostInlining=false) to an early pre-inlining stage (but skip for ThinLTO post-link). This should fix the issues reported in https://github.com/rust-lang/rust/issues/92109 and https://github.com/llvm/llvm-project/issues/52853. These are caused by https://reviews.llvm.org/D97608. --- clang/lib/CodeGen/BackendUtil.cpp | 17 ---- .../CodeGen/X86/x86_64-instrument-functions.c | 39 +++------ clang/test/CodeGen/instrument-objc-method.m | 32 ++++--- clang/test/CodeGen/lto-newpm-pipeline.c | 6 +- clang/test/CodeGen/mcount-aix.c | 24 ++---- clang/test/CodeGen/mcount.c | 84 +++++++++---------- clang/test/Frontend/gnu-mcount.c | 64 +++++++------- llvm/include/llvm/InitializePasses.h | 1 + llvm/include/llvm/LinkAllPasses.h | 1 + llvm/include/llvm/Transforms/Utils.h | 9 ++ llvm/lib/CodeGen/TargetPassConfig.cpp | 3 + llvm/lib/Passes/PassBuilderPipelines.cpp | 6 ++ llvm/lib/Transforms/Scalar/Scalar.cpp | 1 + .../Utils/EntryExitInstrumenter.cpp | 35 ++++++++ llvm/test/CodeGen/AArch64/O0-pipeline.ll | 1 + llvm/test/CodeGen/AArch64/O3-pipeline.ll | 1 + llvm/test/CodeGen/AMDGPU/llc-pipeline.ll | 5 ++ llvm/test/CodeGen/ARM/O3-pipeline.ll | 1 + llvm/test/CodeGen/LoongArch/O0-pipeline.ll | 1 + llvm/test/CodeGen/LoongArch/opt-pipeline.ll | 1 + llvm/test/CodeGen/PowerPC/O0-pipeline.ll | 1 + llvm/test/CodeGen/PowerPC/O3-pipeline.ll | 1 + llvm/test/CodeGen/RISCV/O0-pipeline.ll | 1 + llvm/test/CodeGen/RISCV/O3-pipeline.ll | 1 + llvm/test/CodeGen/X86/O0-pipeline.ll | 1 + .../X86/instrument-function-inlined.ll | 27 ++++++ llvm/test/CodeGen/X86/opt-pipeline.ll | 1 + llvm/test/Other/new-pass-manager.ll | 5 +- llvm/test/Other/new-pm-O0-defaults.ll | 6 +- llvm/test/Other/new-pm-defaults.ll | 1 + .../Other/new-pm-thinlto-prelink-defaults.ll | 3 +- .../new-pm-thinlto-prelink-pgo-defaults.ll | 1 + ...w-pm-thinlto-prelink-samplepgo-defaults.ll | 1 + .../pre-inliner-instrumentation.ll | 46 ++++++++++ llvm/tools/llc/llc.cpp | 1 + llvm/tools/opt/optdriver.cpp | 1 + 36 files changed, 268 insertions(+), 162 deletions(-) create mode 100644 llvm/test/CodeGen/X86/instrument-function-inlined.ll create mode 100644 llvm/test/Transforms/EntryExitInstrumenter/pre-inliner-instrumentation.ll diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 90985c08fe7f81..b09680086248d0 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -85,7 +85,6 @@ #include "llvm/Transforms/Scalar/GVN.h" #include "llvm/Transforms/Scalar/JumpThreading.h" #include "llvm/Transforms/Utils/Debugify.h" -#include "llvm/Transforms/Utils/EntryExitInstrumenter.h" #include "llvm/Transforms/Utils/ModuleUtils.h" #include #include @@ -983,22 +982,6 @@ void EmitAssemblyHelper::RunOptimizationPipeline( /*DropTypeTests=*/true)); }); - if (CodeGenOpts.InstrumentFunctions || - CodeGenOpts.InstrumentFunctionEntryBare || - CodeGenOpts.InstrumentFunctionsAfterInlining || - CodeGenOpts.InstrumentForProfiling) { - PB.registerPipelineStartEPCallback( - [](ModulePassManager &MPM, OptimizationLevel Level) { - MPM.addPass(createModuleToFunctionPassAdaptor( - EntryExitInstrumenterPass(/*PostInlining=*/false))); - }); - PB.registerOptimizerLastEPCallback( - [](ModulePassManager &MPM, OptimizationLevel Level) { - MPM.addPass(createModuleToFunctionPassAdaptor( - EntryExitInstrumenterPass(/*PostInlining=*/true))); - }); - } - // Register callbacks to schedule sanitizer passes at the appropriate part // of the pipeline. if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds)) diff --git a/clang/test/CodeGen/X86/x86_64-instrument-functions.c b/clang/test/CodeGen/X86/x86_64-instrument-functions.c index 215e629a604f72..d71e839a61813f 100644 --- a/clang/test/CodeGen/X86/x86_64-instrument-functions.c +++ b/clang/test/CodeGen/X86/x86_64-instrument-functions.c @@ -1,37 +1,20 @@ // 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 -// CHECK: ret +// CHECK-LABEL: define {{.*}} @leaf(i32 noundef %x) #0 { } 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-LABEL: define {{.*}} @root(i32 noundef %x) #1 { +// NOINLINE-LABEL: define {{.*}} @root(i32 noundef %x) #1 { } + +// CHECK: attributes #0 = { {{.*}}"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 = { {{.*}}"instrument-function-entry-inlined"="__cyg_profile_func_enter" "instrument-function-exit-inlined"="__cyg_profile_func_exit" +// NOINLINE: attributes #1 = { {{.*}}"instrument-function-entry-inlined"="__cyg_profile_func_enter" "instrument-function-exit-inlined"="__cyg_profile_func_exit" diff --git a/clang/test/CodeGen/instrument-objc-method.m b/clang/test/CodeGen/instrument-objc-method.m index 7758e001e514fd..cfc0a0a98bec6b 100644 --- a/clang/test/CodeGen/instrument-objc-method.m +++ b/clang/test/CodeGen/instrument-objc-method.m @@ -1,34 +1,30 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -debug-info-kind=standalone -emit-llvm -o - %s -finstrument-functions | FileCheck %s -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -debug-info-kind=standalone -emit-llvm -o - %s -finstrument-function-entry-bare | FileCheck -check-prefix=BARE %s +// RUN: %clang_cc1 -disable-llvm-passes -triple x86_64-apple-darwin10 -debug-info-kind=standalone -emit-llvm -o - %s -finstrument-functions | FileCheck -check-prefix=PREINLINE %s +// RUN: %clang_cc1 -disable-llvm-passes -triple x86_64-apple-darwin10 -debug-info-kind=standalone -emit-llvm -o - %s -finstrument-function-entry-bare | FileCheck -check-prefix=BARE %s @interface ObjCClass @end @implementation ObjCClass -// CHECK: @"\01+[ObjCClass initialize]" -// CHECK: call void @__cyg_profile_func_enter -// CHECK: call void @__cyg_profile_func_exit -// BARE: @"\01+[ObjCClass initialize]" -// BARE: call void @__cyg_profile_func_enter +// PREINLINE: @"\01+[ObjCClass initialize]"{{\(.*\)}} #0 +// BARE: @"\01+[ObjCClass initialize]"{{\(.*\)}} #0 + (void)initialize { } -// CHECK: @"\01+[ObjCClass load]" -// CHECK-NOT: call void @__cyg_profile_func_enter -// BARE: @"\01+[ObjCClass load]" -// BARE-NOT: call void @__cyg_profile_func_enter +// PREINLINE: declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 +// BARE: @"\01+[ObjCClass load]"{{\(.*\)}} #2 + (void)load __attribute__((no_instrument_function)) { } -// CHECK: @"\01-[ObjCClass dealloc]" -// CHECK-NOT: call void @__cyg_profile_func_enter -// BARE: @"\01-[ObjCClass dealloc]" -// BARE-NOT: call void @__cyg_profile_func_enter +// PREINLINE: @"\01-[ObjCClass dealloc]"{{\(.*\)}} #2 +// BARE: @"\01-[ObjCClass dealloc]"{{\(.*\)}} #2 - (void)dealloc __attribute__((no_instrument_function)) { } -// CHECK: declare void @__cyg_profile_func_enter(ptr, ptr) -// CHECK: declare void @__cyg_profile_func_exit(ptr, ptr) -// BARE: declare void @__cyg_profile_func_enter_bare +// PREINLINE: attributes #0 = { {{.*}}"instrument-function-entry"="__cyg_profile_func_enter" +// PREINLINE-NOT: attributes #0 = { {{.*}}"instrument-function-entry"="__cyg_profile_func_enter_bare" +// PREINLINE-NOT: attributes #2 = { {{.*}}"__cyg_profile_func_enter" +// BARE: attributes #0 = { {{.*}}"instrument-function-entry-inlined"="__cyg_profile_func_enter_bare" +// BARE-NOT: attributes #0 = { {{.*}}"__cyg_profile_func_enter" +// BARE-NOT: attributes #2 = { {{.*}}"__cyg_profile_func_enter_bare" @end diff --git a/clang/test/CodeGen/lto-newpm-pipeline.c b/clang/test/CodeGen/lto-newpm-pipeline.c index f58757efbf686f..ea9784a76f9233 100644 --- a/clang/test/CodeGen/lto-newpm-pipeline.c +++ b/clang/test/CodeGen/lto-newpm-pipeline.c @@ -27,8 +27,9 @@ // CHECK-FULL-O0: Running pass: VerifierPass // CHECK-FULL-O0-NEXT: Running analysis: VerifierAnalysis -// CHECK-FULL-O0-NEXT: Running pass: AlwaysInlinerPass // CHECK-FULL-O0-NEXT: Running analysis: InnerAnalysisManagerProxy +// CHECK-FULL-O0-NEXT: Running pass: EntryExitInstrumenterPass +// CHECK-FULL-O0-NEXT: Running pass: AlwaysInlinerPass // CHECK-FULL-O0-NEXT: Running analysis: ProfileSummaryAnalysis // CHECK-FULL-O0-NEXT: Running pass: CoroConditionalWrapper // CHECK-FULL-O0-NEXT: Running pass: CanonicalizeAliasesPass @@ -40,8 +41,9 @@ // CHECK-THIN-O0: Running pass: VerifierPass // CHECK-THIN-O0-NEXT: Running analysis: VerifierAnalysis -// CHECK-THIN-O0-NEXT: Running pass: AlwaysInlinerPass // CHECK-THIN-O0-NEXT: Running analysis: InnerAnalysisManagerProxy +// CHECK-THIN-O0-NEXT: Running pass: EntryExitInstrumenterPass +// CHECK-THIN-O0-NEXT: Running pass: AlwaysInlinerPass // CHECK-THIN-O0-NEXT: Running analysis: ProfileSummaryAnalysis // CHECK-THIN-O0-NEXT: Running pass: CoroConditionalWrapper // CHECK-THIN-O0-NEXT: Running pass: CanonicalizeAliasesPass diff --git a/clang/test/CodeGen/mcount-aix.c b/clang/test/CodeGen/mcount-aix.c index 17ce0af476dbb5..275af35bcce206 100644 --- a/clang/test/CodeGen/mcount-aix.c +++ b/clang/test/CodeGen/mcount-aix.c @@ -1,25 +1,13 @@ -// RUN: %clang_cc1 -pg -triple powerpc-ibm-aix7.2.0.0 -emit-llvm %s -o - | FileCheck %s -// RUN: %clang_cc1 -pg -triple powerpc64-ibm-aix7.2.0.0 -emit-llvm %s -o - | FileCheck %s -check-prefix=CHECK64 +// RUN: %clang_cc1 -disable-llvm-passes -pg -triple powerpc-ibm-aix7.2.0.0 -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -disable-llvm-passes -pg -triple powerpc64-ibm-aix7.2.0.0 -emit-llvm %s -o - | FileCheck %s void foo() { +// CHECK: define void @foo() #0 { } void bar() { +// CHECK: define void @bar() #0 { foo(); } -// CHECK: @[[GLOB0:[0-9]+]] = internal global i32 0 -// CHECK: @[[GLOB1:[0-9]+]] = internal global i32 0 -// CHECK64: @[[GLOB0:[0-9]+]] = internal global i64 0 -// CHECK64: @[[GLOB1:[0-9]+]] = internal global i64 0 -// CHECK-LABEL: @foo( -// CHECK-NEXT: entry: -// CHECK-NEXT: call void @__mcount(ptr @[[GLOB0]]) -// CHECK64-LABEL: @foo( -// CHECK64-NEXT: entry: -// CHECK64-NEXT: call void @__mcount(ptr @[[GLOB0]]) -// CHECK-LABEL: @bar( -// CHECK-NEXT: entry: -// CHECK-NEXT: call void @__mcount(ptr @[[GLOB1]]) -// CHECK64-LABEL: @bar( -// CHECK64-NEXT: entry: -// CHECK64-NEXT: call void @__mcount(ptr @[[GLOB1]]) + +// CHECK: attributes #0 = { {{.*}}"instrument-function-entry-inlined"="__mcount" diff --git a/clang/test/CodeGen/mcount.c b/clang/test/CodeGen/mcount.c index bdd609c1dfc582..e5b842d6704501 100644 --- a/clang/test/CodeGen/mcount.c +++ b/clang/test/CodeGen/mcount.c @@ -1,60 +1,58 @@ -// RUN: %clang_cc1 -pg -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck %s -// RUN: %clang_cc1 -pg -triple i386-unknown-unknown -emit-llvm -O2 -o - %s | FileCheck %s -// RUN: %clang_cc1 -pg -triple powerpc-unknown-gnu-linux -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s -// RUN: %clang_cc1 -pg -triple powerpc64-unknown-gnu-linux -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s -// RUN: %clang_cc1 -pg -triple powerpc64le-unknown-gnu-linux -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s -// RUN: %clang_cc1 -pg -triple i386-netbsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-DOUBLE-PREFIXED,NO-MCOUNT1 %s -// RUN: %clang_cc1 -pg -triple x86_64-netbsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-DOUBLE-PREFIXED,NO-MCOUNT1 %s -// RUN: %clang_cc1 -pg -triple arm-netbsd-eabi -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-DOUBLE-PREFIXED,NO-MCOUNT1 %s -// RUN: %clang_cc1 -pg -triple aarch64-netbsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-DOUBLE-PREFIXED,NO-MCOUNT1 %s -// RUN: %clang_cc1 -pg -triple loongarch32 -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s -// RUN: %clang_cc1 -pg -triple loongarch64 -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s -// RUN: %clang_cc1 -pg -triple mips-netbsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-DOUBLE-PREFIXED,NO-MCOUNT1 %s -// RUN: %clang_cc1 -pg -triple mips-unknown-gnu-linux -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s -// RUN: %clang_cc1 -pg -triple mipsel-unknown-gnu-linux -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s -// RUN: %clang_cc1 -pg -triple mips64-unknown-gnu-linux -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s -// RUN: %clang_cc1 -pg -triple mips64el-unknown-gnu-linux -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s -// RUN: %clang_cc1 -pg -triple riscv32-elf -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s -// RUN: %clang_cc1 -pg -triple riscv64-elf -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s -// RUN: %clang_cc1 -pg -triple riscv32-linux -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s -// RUN: %clang_cc1 -pg -triple riscv64-linux -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s -// RUN: %clang_cc1 -pg -triple riscv64-freebsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s -// RUN: %clang_cc1 -pg -triple riscv64-freebsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s -// RUN: %clang_cc1 -pg -triple riscv64-openbsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s -// RUN: %clang_cc1 -pg -triple powerpc-netbsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-DOUBLE-PREFIXED,NO-MCOUNT1 %s -// RUN: %clang_cc1 -pg -triple powerpc64-netbsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-DOUBLE-PREFIXED,NO-MCOUNT1 %s -// RUN: %clang_cc1 -pg -triple powerpc64le-netbsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-DOUBLE-PREFIXED,NO-MCOUNT1 %s -// RUN: %clang_cc1 -pg -triple sparc-netbsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-DOUBLE-PREFIXED,NO-MCOUNT1 %s -// RUN: %clang_cc1 -pg -triple sparc64-netbsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-DOUBLE-PREFIXED,NO-MCOUNT1 %s -// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s -check-prefix=NO-MCOUNT +// RUN: %clang_cc1 -disable-llvm-passes -pg -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -disable-llvm-passes -pg -triple i386-unknown-unknown -emit-llvm -O2 -o - %s | FileCheck %s +// RUN: %clang_cc1 -disable-llvm-passes -pg -triple powerpc-unknown-gnu-linux -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -disable-llvm-passes -pg -triple powerpc64-unknown-gnu-linux -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -disable-llvm-passes -pg -triple powerpc64le-unknown-gnu-linux -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -disable-llvm-passes -pg -triple i386-netbsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-DOUBLE-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -disable-llvm-passes -pg -triple x86_64-netbsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-DOUBLE-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -disable-llvm-passes -pg -triple arm-netbsd-eabi -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-DOUBLE-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -disable-llvm-passes -pg -triple aarch64-netbsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-DOUBLE-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -disable-llvm-passes -pg -triple loongarch32 -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -disable-llvm-passes -pg -triple loongarch64 -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -disable-llvm-passes -pg -triple mips-netbsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-DOUBLE-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -disable-llvm-passes -pg -triple mips-unknown-gnu-linux -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -disable-llvm-passes -pg -triple mipsel-unknown-gnu-linux -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -disable-llvm-passes -pg -triple mips64-unknown-gnu-linux -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -disable-llvm-passes -pg -triple mips64el-unknown-gnu-linux -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -disable-llvm-passes -pg -triple riscv32-elf -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -disable-llvm-passes -pg -triple riscv64-elf -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -disable-llvm-passes -pg -triple riscv32-linux -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -disable-llvm-passes -pg -triple riscv64-linux -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -disable-llvm-passes -pg -triple riscv64-freebsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -disable-llvm-passes -pg -triple riscv64-freebsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -disable-llvm-passes -pg -triple riscv64-openbsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -disable-llvm-passes -pg -triple powerpc-netbsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-DOUBLE-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -disable-llvm-passes -pg -triple powerpc64-netbsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-DOUBLE-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -disable-llvm-passes -pg -triple powerpc64le-netbsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-DOUBLE-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -disable-llvm-passes -pg -triple sparc-netbsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-DOUBLE-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -disable-llvm-passes -pg -triple sparc64-netbsd -emit-llvm -o - %s | FileCheck -check-prefixes=CHECK-DOUBLE-PREFIXED,NO-MCOUNT1 %s +// RUN: %clang_cc1 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s -check-prefix=NO-MCOUNT int bar(void) { +// CHECK: define dso_local i32 @bar() #0 { return 0; } int foo(void) { +// CHECK: define dso_local i32 @foo() #0 { return bar(); } int __attribute__((no_instrument_function)) no_instrument(void) { +// CHECK: define dso_local i32 @no_instrument() #1 { return foo(); } int main(void) { +// CHECK: define dso_local i32 @main() #0 { return no_instrument(); } -// CHECK: call void @mcount -// CHECK: call void @mcount -// CHECK: call void @mcount -// CHECK-NOT: call void @mcount -// CHECK-PREFIXED: call void @_mcount -// CHECK-PREFIXED: call void @_mcount -// CHECK-PREFIXED: call void @_mcount -// CHECK-PREFIXED-NOT: call void @_mcount -// CHECK-DOUBLE-PREFIXED: call void @__mcount -// CHECK-DOUBLE-PREFIXED: call void @__mcount -// CHECK-DOUBLE-PREFIXED: call void @__mcount -// CHECK-DOUBLE-PREFIXED-NOT: call void @__mcount -// NO-MCOUNT-NOT: call void @{{.*}}mcount -// NO-MCOUNT1-NOT: call void @{{.*}}mcount +// CHECK: attributes #0 = { {{.*}} "instrument-function-entry-inlined"="mcount" +// CHECK-NOT: attributes #1 = { {{.*}}"mcount" +// CHECK-PREFIXED: attributes #0 = { {{.*}} "instrument-function-entry-inlined"="_mcount" +// CHECK-PREFIXED-NOT: attributes #1 = { {{.*}}"_mcount" +// CHECK-DOUBLE-PREFIXED: attributes #0 = { {{.*}} "instrument-function-entry-inlined"="__mcount" +// CHECK-DOUBLE-PREFIXED-NOT: attributes #1 = { {{.*}}"__mcount" +// NO-MCOUNT-NOT: attributes{{.*}}mcount +// NO-MCOUNT1-NOT: attributes{{.*}}mcount diff --git a/clang/test/Frontend/gnu-mcount.c b/clang/test/Frontend/gnu-mcount.c index a6ee4b274593e7..965c0010b549dd 100644 --- a/clang/test/Frontend/gnu-mcount.c +++ b/clang/test/Frontend/gnu-mcount.c @@ -1,30 +1,32 @@ // REQUIRES: arm-registered-target,aarch64-registered-target -// RUN: %clang -target armv7-unknown-none-eabi -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefixes=CHECK,UNSUPPORTED -// RUN: %clang -target armv7-unknown-none-eabi -pg -meabi gnu -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,UNSUPPORTED -// RUN: %clang --target=aarch64-unknown-none-gnu -pg -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,MCOUNT -// RUN: %clang -target armv7-unknown-linux-gnueabi -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM-EABI -// RUN: %clang -target armv7-unknown-linux-gnueabi -meabi gnu -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM-EABI-MEABI-GNU -// RUN: %clang --target=aarch64-unknown-linux -pg -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,UNDER -// RUN: %clang -target armv7-unknown-linux-gnueabihf -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM-EABI -// RUN: %clang -target armv7-unknown-linux-gnueabihf -meabi gnu -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM-EABI-MEABI-GNU -// RUN: %clang -target armv7-unknown-freebsd-gnueabihf -pg -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,UNDER_UNDER -// RUN: %clang -target armv7-unknown-freebsd-gnueabihf -meabi gnu -pg -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,UNDER_UNDER -// RUN: %clang --target=aarch64-unknown-freebsd -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM64-EABI-FREEBSD -// RUN: %clang -target armv7-unknown-openbsd-gnueabihf -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix UNDER_UNDER -// RUN: %clang -target armv7-unknown-openbsd-gnueabihf -meabi gnu -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix UNDER_UNDER -// RUN: %clang --target=aarch64-unknown-openbsd -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix UNDER_UNDER -// RUN: %clang -target armv7-unknown-netbsd-gnueabihf -pg -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,UNDER_UNDER -// RUN: %clang -target armv7-unknown-netbsd-gnueabihf -meabi gnu -pg -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,UNDER_UNDER -// RUN: %clang --target=aarch64-unknown-netbsd -pg -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,UNDER_UNDER -// RUN: %clang -target armv7-apple-ios -pg -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,UNSUPPORTED -// RUN: %clang -target armv7-apple-ios -pg -meabi gnu -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,UNSUPPORTED -// RUN: %clang -target arm64-apple-ios -pg -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,UNSUPPORTED -// RUN: %clang -target arm64-apple-ios -pg -meabi gnu -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,UNSUPPORTED -// RUN: %clang -target armv7-unknown-rtems-gnueabihf -pg -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,MCOUNT -// RUN: %clang -target armv7-unknown-rtems-gnueabihf -meabi gnu -pg -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,MCOUNT -// RUN: %clang --target=aarch64-unknown-rtems -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefixes=CHECK,MCOUNT -// RUN: %clang --target=aarch64-unknown-rtems -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefixes=CHECK,MCOUNT +// RUN: %clang -Xclang -disable-llvm-passes -target armv7-unknown-none-eabi -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefixes=CHECK,UNSUPPORTED +// RUN: %clang -Xclang -disable-llvm-passes -target armv7-unknown-none-eabi -pg -meabi gnu -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,UNSUPPORTED +// RUN: %clang -Xclang -disable-llvm-passes --target=aarch64-unknown-none-gnu -pg -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,MCOUNT +// RUN: %clang -Xclang -disable-llvm-passes -target armv7-unknown-linux-gnueabi -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM-EABI +// RUN: %clang -Xclang -disable-llvm-passes -target armv7-unknown-linux-gnueabi -meabi gnu -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM-EABI-MEABI-GNU +// RUN: %clang -Xclang -disable-llvm-passes --target=aarch64-unknown-linux -pg -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,UNDER +// RUN: %clang -Xclang -disable-llvm-passes -target armv7-unknown-linux-gnueabihf -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM-EABI +// RUN: %clang -Xclang -disable-llvm-passes -target armv7-unknown-linux-gnueabihf -meabi gnu -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM-EABI-MEABI-GNU +// RUN: %clang -Xclang -disable-llvm-passes -target armv7-unknown-freebsd-gnueabihf -pg -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,UNDER_UNDER +// RUN: %clang -Xclang -disable-llvm-passes -target armv7-unknown-freebsd-gnueabihf -meabi gnu -pg -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,UNDER_UNDER +// RUN: %clang -Xclang -disable-llvm-passes --target=aarch64-unknown-freebsd -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ARM64-EABI-FREEBSD +// RUN: %clang -Xclang -disable-llvm-passes -target armv7-unknown-openbsd-gnueabihf -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix UNDER_UNDER +// RUN: %clang -Xclang -disable-llvm-passes -target armv7-unknown-openbsd-gnueabihf -meabi gnu -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix UNDER_UNDER +// RUN: %clang -Xclang -disable-llvm-passes --target=aarch64-unknown-openbsd -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix UNDER_UNDER +// RUN: %clang -Xclang -disable-llvm-passes -target armv7-unknown-netbsd-gnueabihf -pg -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,UNDER_UNDER +// RUN: %clang -Xclang -disable-llvm-passes -target armv7-unknown-netbsd-gnueabihf -meabi gnu -pg -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,UNDER_UNDER +// RUN: %clang -Xclang -disable-llvm-passes --target=aarch64-unknown-netbsd -pg -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,UNDER_UNDER +// RUN: %clang -Xclang -disable-llvm-passes -target armv7-apple-ios -pg -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,UNSUPPORTED +// RUN: %clang -Xclang -disable-llvm-passes -target armv7-apple-ios -pg -meabi gnu -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,UNSUPPORTED +// RUN: %clang -Xclang -disable-llvm-passes -target arm64-apple-ios -pg -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,UNSUPPORTED +// RUN: %clang -Xclang -disable-llvm-passes -target arm64-apple-ios -pg -meabi gnu -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,UNSUPPORTED +// RUN: %clang -Xclang -disable-llvm-passes -target armv7-unknown-rtems-gnueabihf -pg -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,MCOUNT +// RUN: %clang -Xclang -disable-llvm-passes -target armv7-unknown-rtems-gnueabihf -meabi gnu -pg -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,MCOUNT +// RUN: %clang -Xclang -disable-llvm-passes --target=aarch64-unknown-rtems -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefixes=CHECK,MCOUNT +// RUN: %clang -Xclang -disable-llvm-passes --target=aarch64-unknown-rtems -pg -S -emit-llvm -o - %s | FileCheck %s -check-prefixes=CHECK,MCOUNT + +// Correct function name should be used for mcount instrumentation call. int f() { return 0; @@ -33,9 +35,9 @@ int f() { // CHECK-LABEL: f // TODO: add profiling support for arm-baremetal // UNSUPPORTED-NOT: call void -// CHECK-ARM-EABI: call void @"\01mcount"() -// MCOUNT: call void @mcount() -// UNDER: call void @"\01_mcount"() -// UNDER_UNDER: call void @__mcount() -// CHECK-ARM64-EABI-FREEBSD: call void @.mcount() -// CHECK-ARM-EABI-MEABI-GNU: call void @llvm.arm.gnu.eabi.mcount() +// CHECK-ARM-EABI: attributes #0 = {{.*}} "instrument-function-entry-inlined"="\01mcount" +// MCOUNT: attributes #0 = {{.*}} "instrument-function-entry-inlined"="mcount" +// UNDER: attributes #0 = {{.*}} "instrument-function-entry-inlined"="\01_mcount" +// UNDER_UNDER: attributes #0 = {{.*}} "instrument-function-entry-inlined"="__mcount" +// CHECK-ARM64-EABI-FREEBSD: attributes #0 = {{.*}} "instrument-function-entry-inlined"=".mcount" +// CHECK-ARM-EABI-MEABI-GNU: attributes #0 = {{.*}} "instrument-function-entry-inlined"="llvm.arm.gnu.eabi.mcount" diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index 9ba75d491c1c9c..c4c1825bbf09eb 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -230,6 +230,7 @@ void initializePostDomOnlyViewerWrapperPassPass(PassRegistry &); void initializePostDomPrinterWrapperPassPass(PassRegistry &); void initializePostDomViewerWrapperPassPass(PassRegistry &); void initializePostDominatorTreeWrapperPassPass(PassRegistry&); +void initializePostInlineEntryExitInstrumenterPass(PassRegistry&); void initializePostMachineSchedulerPass(PassRegistry&); void initializePostRAHazardRecognizerPass(PassRegistry&); void initializePostRAMachineSinkingPass(PassRegistry&); diff --git a/llvm/include/llvm/LinkAllPasses.h b/llvm/include/llvm/LinkAllPasses.h index 30e7c22f31460a..311d38e8a751f7 100644 --- a/llvm/include/llvm/LinkAllPasses.h +++ b/llvm/include/llvm/LinkAllPasses.h @@ -113,6 +113,7 @@ namespace { (void)llvm::createTLSVariableHoistPass(); (void) llvm::createConstantHoistingPass(); (void)llvm::createCodeGenPrepareLegacyPass(); + (void) llvm::createPostInlineEntryExitInstrumenterPass(); (void) llvm::createEarlyCSEPass(); (void) llvm::createGVNPass(); (void) llvm::createPostDomTree(); diff --git a/llvm/include/llvm/Transforms/Utils.h b/llvm/include/llvm/Transforms/Utils.h index c6a6a05f3fddb4..677cc3d128c3a3 100644 --- a/llvm/include/llvm/Transforms/Utils.h +++ b/llvm/include/llvm/Transforms/Utils.h @@ -36,6 +36,15 @@ extern char &LowerInvokePassID; FunctionPass *createLowerSwitchPass(); extern char &LowerSwitchID; +//===----------------------------------------------------------------------===// +// +// EntryExitInstrumenter pass - Instrument function entry/exit with calls to +// mcount(), @__cyg_profile_func_{enter,exit} and the like. There are two +// variants, intended to run pre- and post-inlining, respectively. Only the +// post-inlining variant is used with the legacy pass manager. +// +FunctionPass *createPostInlineEntryExitInstrumenterPass(); + //===----------------------------------------------------------------------===// // // BreakCriticalEdges - Break all of the critical edges in the CFG by inserting diff --git a/llvm/lib/CodeGen/TargetPassConfig.cpp b/llvm/lib/CodeGen/TargetPassConfig.cpp index 8832b51333d910..3658e8320a0ccd 100644 --- a/llvm/lib/CodeGen/TargetPassConfig.cpp +++ b/llvm/lib/CodeGen/TargetPassConfig.cpp @@ -871,6 +871,9 @@ void TargetPassConfig::addIRPasses() { // passes since it emits those kinds of intrinsics. addPass(createExpandVectorPredicationPass()); + // Instrument function entry after all inlining. + addPass(createPostInlineEntryExitInstrumenterPass()); + // Add scalarization of target's unsupported masked memory intrinsics pass. // the unsupported intrinsic will be replaced with a chain of basic blocks, // that stores/loads element one-by-one if the appropriate mask bit is set. diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp index 1892e16a06528c..926515c9508a97 100644 --- a/llvm/lib/Passes/PassBuilderPipelines.cpp +++ b/llvm/lib/Passes/PassBuilderPipelines.cpp @@ -128,6 +128,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" @@ -1069,6 +1070,7 @@ PassBuilder::buildModuleSimplificationPipeline(OptimizationLevel Level, MPM.addPass(CoroEarlyPass()); FunctionPassManager EarlyFPM; + EarlyFPM.addPass(EntryExitInstrumenterPass(/*PostInlining=*/false)); // Lower llvm.expect to metadata before attempting transforms. // Compare/branch metadata may alter the behavior of passes like // SimplifyCFG. @@ -2068,6 +2070,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) diff --git a/llvm/lib/Transforms/Scalar/Scalar.cpp b/llvm/lib/Transforms/Scalar/Scalar.cpp index 400b15284c1b83..cb1456b146325d 100644 --- a/llvm/lib/Transforms/Scalar/Scalar.cpp +++ b/llvm/lib/Transforms/Scalar/Scalar.cpp @@ -48,4 +48,5 @@ void llvm::initializeScalarOpts(PassRegistry &Registry) { initializeSpeculativeExecutionLegacyPassPass(Registry); initializeStraightLineStrengthReduceLegacyPassPass(Registry); initializePlaceBackedgeSafepointsLegacyPassPass(Registry); + initializePostInlineEntryExitInstrumenterPass(Registry); } diff --git a/llvm/lib/Transforms/Utils/EntryExitInstrumenter.cpp b/llvm/lib/Transforms/Utils/EntryExitInstrumenter.cpp index 59a7dd1a00ed48..d12c540f9a4d04 100644 --- a/llvm/lib/Transforms/Utils/EntryExitInstrumenter.cpp +++ b/llvm/lib/Transforms/Utils/EntryExitInstrumenter.cpp @@ -15,7 +15,10 @@ #include "llvm/IR/Intrinsics.h" #include "llvm/IR/Module.h" #include "llvm/IR/Type.h" +#include "llvm/InitializePasses.h" #include "llvm/TargetParser/Triple.h" +#include "llvm/Pass.h" +#include "llvm/Transforms/Utils.h" using namespace llvm; @@ -135,6 +138,38 @@ static bool runOnFunction(Function &F, bool PostInlining) { return Changed; } +namespace { +struct PostInlineEntryExitInstrumenter : public FunctionPass { + static char ID; + PostInlineEntryExitInstrumenter() : FunctionPass(ID) { + initializePostInlineEntryExitInstrumenterPass( + *PassRegistry::getPassRegistry()); + } + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addPreserved(); + AU.addPreserved(); + } + bool runOnFunction(Function &F) override { return ::runOnFunction(F, true); } +}; +char PostInlineEntryExitInstrumenter::ID = 0; +} + +INITIALIZE_PASS_BEGIN( + PostInlineEntryExitInstrumenter, "post-inline-ee-instrument", + "Instrument function entry/exit with calls to e.g. mcount() " + "(post inlining)", + false, false) +INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) +INITIALIZE_PASS_END( + PostInlineEntryExitInstrumenter, "post-inline-ee-instrument", + "Instrument function entry/exit with calls to e.g. mcount() " + "(post inlining)", + false, false) + +FunctionPass *llvm::createPostInlineEntryExitInstrumenterPass() { + return new PostInlineEntryExitInstrumenter(); +} + PreservedAnalyses llvm::EntryExitInstrumenterPass::run(Function &F, FunctionAnalysisManager &AM) { if (!runOnFunction(F, PostInlining)) diff --git a/llvm/test/CodeGen/AArch64/O0-pipeline.ll b/llvm/test/CodeGen/AArch64/O0-pipeline.ll index d1e38b85fa9c36..a0306b8e1e9244 100644 --- a/llvm/test/CodeGen/AArch64/O0-pipeline.ll +++ b/llvm/test/CodeGen/AArch64/O0-pipeline.ll @@ -24,6 +24,7 @@ ; CHECK-NEXT: Lower constant intrinsics ; CHECK-NEXT: Remove unreachable blocks from the CFG ; CHECK-NEXT: Expand vector predication intrinsics +; CHECK-NEXT: Instrument function entry/exit with calls to e.g. mcount() (post inlining) ; CHECK-NEXT: Scalarize Masked Memory Intrinsics ; CHECK-NEXT: Expand reduction intrinsics ; CHECK-NEXT: AArch64 Globals Tagging diff --git a/llvm/test/CodeGen/AArch64/O3-pipeline.ll b/llvm/test/CodeGen/AArch64/O3-pipeline.ll index d3c8e3b7e805c1..84e672d14d99d5 100644 --- a/llvm/test/CodeGen/AArch64/O3-pipeline.ll +++ b/llvm/test/CodeGen/AArch64/O3-pipeline.ll @@ -62,6 +62,7 @@ ; CHECK-NEXT: Replace intrinsics with calls to vector library ; CHECK-NEXT: Partially inline calls to library functions ; CHECK-NEXT: Expand vector predication intrinsics +; CHECK-NEXT: Instrument function entry/exit with calls to e.g. mcount() (post inlining) ; CHECK-NEXT: Scalarize Masked Memory Intrinsics ; CHECK-NEXT: Expand reduction intrinsics ; CHECK-NEXT: Natural Loop Information diff --git a/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll b/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll index 0ff5dd3680dfab..0db88d1c095d30 100644 --- a/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll +++ b/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll @@ -44,6 +44,7 @@ ; GCN-O0-NEXT: Lower constant intrinsics ; GCN-O0-NEXT: Remove unreachable blocks from the CFG ; GCN-O0-NEXT: Expand vector predication intrinsics +; GCN-O0-NEXT: Instrument function entry/exit with calls to e.g. mcount() (post inlining) ; GCN-O0-NEXT: Scalarize Masked Memory Intrinsics ; GCN-O0-NEXT: Expand reduction intrinsics ; GCN-O0-NEXT: CallGraph Construction @@ -225,6 +226,7 @@ ; GCN-O1-NEXT: Replace intrinsics with calls to vector library ; GCN-O1-NEXT: Partially inline calls to library functions ; GCN-O1-NEXT: Expand vector predication intrinsics +; GCN-O1-NEXT: Instrument function entry/exit with calls to e.g. mcount() (post inlining) ; GCN-O1-NEXT: Scalarize Masked Memory Intrinsics ; GCN-O1-NEXT: Expand reduction intrinsics ; GCN-O1-NEXT: Natural Loop Information @@ -513,6 +515,7 @@ ; GCN-O1-OPTS-NEXT: Replace intrinsics with calls to vector library ; GCN-O1-OPTS-NEXT: Partially inline calls to library functions ; GCN-O1-OPTS-NEXT: Expand vector predication intrinsics +; GCN-O1-OPTS-NEXT: Instrument function entry/exit with calls to e.g. mcount() (post inlining) ; GCN-O1-OPTS-NEXT: Scalarize Masked Memory Intrinsics ; GCN-O1-OPTS-NEXT: Expand reduction intrinsics ; GCN-O1-OPTS-NEXT: Natural Loop Information @@ -820,6 +823,7 @@ ; GCN-O2-NEXT: Replace intrinsics with calls to vector library ; GCN-O2-NEXT: Partially inline calls to library functions ; GCN-O2-NEXT: Expand vector predication intrinsics +; GCN-O2-NEXT: Instrument function entry/exit with calls to e.g. mcount() (post inlining) ; GCN-O2-NEXT: Scalarize Masked Memory Intrinsics ; GCN-O2-NEXT: Expand reduction intrinsics ; GCN-O2-NEXT: Natural Loop Information @@ -1135,6 +1139,7 @@ ; GCN-O3-NEXT: Replace intrinsics with calls to vector library ; GCN-O3-NEXT: Partially inline calls to library functions ; GCN-O3-NEXT: Expand vector predication intrinsics +; GCN-O3-NEXT: Instrument function entry/exit with calls to e.g. mcount() (post inlining) ; GCN-O3-NEXT: Scalarize Masked Memory Intrinsics ; GCN-O3-NEXT: Expand reduction intrinsics ; GCN-O3-NEXT: Natural Loop Information diff --git a/llvm/test/CodeGen/ARM/O3-pipeline.ll b/llvm/test/CodeGen/ARM/O3-pipeline.ll index 5914e98549fcc4..461920e1c5da14 100644 --- a/llvm/test/CodeGen/ARM/O3-pipeline.ll +++ b/llvm/test/CodeGen/ARM/O3-pipeline.ll @@ -40,6 +40,7 @@ ; CHECK-NEXT: Replace intrinsics with calls to vector library ; CHECK-NEXT: Partially inline calls to library functions ; CHECK-NEXT: Expand vector predication intrinsics +; CHECK-NEXT: Instrument function entry/exit with calls to e.g. mcount() (post inlining) ; CHECK-NEXT: Scalarize Masked Memory Intrinsics ; CHECK-NEXT: Expand reduction intrinsics ; CHECK-NEXT: Natural Loop Information diff --git a/llvm/test/CodeGen/LoongArch/O0-pipeline.ll b/llvm/test/CodeGen/LoongArch/O0-pipeline.ll index 38c3291b636776..13f774c96d5b1d 100644 --- a/llvm/test/CodeGen/LoongArch/O0-pipeline.ll +++ b/llvm/test/CodeGen/LoongArch/O0-pipeline.ll @@ -28,6 +28,7 @@ ; CHECK-NEXT: Lower constant intrinsics ; CHECK-NEXT: Remove unreachable blocks from the CFG ; CHECK-NEXT: Expand vector predication intrinsics +; CHECK-NEXT: Instrument function entry/exit with calls to e.g. mcount() (post inlining) ; CHECK-NEXT: Scalarize Masked Memory Intrinsics ; CHECK-NEXT: Expand reduction intrinsics ; CHECK-NEXT: Exception handling preparation diff --git a/llvm/test/CodeGen/LoongArch/opt-pipeline.ll b/llvm/test/CodeGen/LoongArch/opt-pipeline.ll index f976dd8f986868..615cb5700ebf07 100644 --- a/llvm/test/CodeGen/LoongArch/opt-pipeline.ll +++ b/llvm/test/CodeGen/LoongArch/opt-pipeline.ll @@ -63,6 +63,7 @@ ; LAXX-NEXT: Replace intrinsics with calls to vector library ; LAXX-NEXT: Partially inline calls to library functions ; LAXX-NEXT: Expand vector predication intrinsics +; LAXX-NEXT: Instrument function entry/exit with calls to e.g. mcount() (post inlining) ; LAXX-NEXT: Scalarize Masked Memory Intrinsics ; LAXX-NEXT: Expand reduction intrinsics ; LAXX-NEXT: Natural Loop Information diff --git a/llvm/test/CodeGen/PowerPC/O0-pipeline.ll b/llvm/test/CodeGen/PowerPC/O0-pipeline.ll index 56ed3ffe986428..cd37bee4592d62 100644 --- a/llvm/test/CodeGen/PowerPC/O0-pipeline.ll +++ b/llvm/test/CodeGen/PowerPC/O0-pipeline.ll @@ -27,6 +27,7 @@ ; CHECK-NEXT: Lower constant intrinsics ; CHECK-NEXT: Remove unreachable blocks from the CFG ; CHECK-NEXT: Expand vector predication intrinsics +; CHECK-NEXT: Instrument function entry/exit with calls to e.g. mcount() (post inlining) ; CHECK-NEXT: Scalarize Masked Memory Intrinsics ; CHECK-NEXT: Expand reduction intrinsics ; CHECK-NEXT: Exception handling preparation diff --git a/llvm/test/CodeGen/PowerPC/O3-pipeline.ll b/llvm/test/CodeGen/PowerPC/O3-pipeline.ll index f94f91b38fecc9..a564a5517f579a 100644 --- a/llvm/test/CodeGen/PowerPC/O3-pipeline.ll +++ b/llvm/test/CodeGen/PowerPC/O3-pipeline.ll @@ -64,6 +64,7 @@ ; CHECK-NEXT: Replace intrinsics with calls to vector library ; CHECK-NEXT: Partially inline calls to library functions ; CHECK-NEXT: Expand vector predication intrinsics +; CHECK-NEXT: Instrument function entry/exit with calls to e.g. mcount() (post inlining) ; CHECK-NEXT: Scalarize Masked Memory Intrinsics ; CHECK-NEXT: Expand reduction intrinsics ; CHECK-NEXT: Natural Loop Information diff --git a/llvm/test/CodeGen/RISCV/O0-pipeline.ll b/llvm/test/CodeGen/RISCV/O0-pipeline.ll index ef7a8f2c7bbee5..ec49ed302d49d1 100644 --- a/llvm/test/CodeGen/RISCV/O0-pipeline.ll +++ b/llvm/test/CodeGen/RISCV/O0-pipeline.ll @@ -28,6 +28,7 @@ ; CHECK-NEXT: Lower constant intrinsics ; CHECK-NEXT: Remove unreachable blocks from the CFG ; CHECK-NEXT: Expand vector predication intrinsics +; CHECK-NEXT: Instrument function entry/exit with calls to e.g. mcount() (post inlining) ; CHECK-NEXT: Scalarize Masked Memory Intrinsics ; CHECK-NEXT: Expand reduction intrinsics ; CHECK-NEXT: Exception handling preparation diff --git a/llvm/test/CodeGen/RISCV/O3-pipeline.ll b/llvm/test/CodeGen/RISCV/O3-pipeline.ll index 1d1c5942aa8e96..1eee62e883cf6d 100644 --- a/llvm/test/CodeGen/RISCV/O3-pipeline.ll +++ b/llvm/test/CodeGen/RISCV/O3-pipeline.ll @@ -64,6 +64,7 @@ ; CHECK-NEXT: Replace intrinsics with calls to vector library ; CHECK-NEXT: Partially inline calls to library functions ; CHECK-NEXT: Expand vector predication intrinsics +; CHECK-NEXT: Instrument function entry/exit with calls to e.g. mcount() (post inlining) ; CHECK-NEXT: Scalarize Masked Memory Intrinsics ; CHECK-NEXT: Expand reduction intrinsics ; CHECK-NEXT: Natural Loop Information diff --git a/llvm/test/CodeGen/X86/O0-pipeline.ll b/llvm/test/CodeGen/X86/O0-pipeline.ll index 11025b0e6bf221..40648adeb91cde 100644 --- a/llvm/test/CodeGen/X86/O0-pipeline.ll +++ b/llvm/test/CodeGen/X86/O0-pipeline.ll @@ -28,6 +28,7 @@ ; CHECK-NEXT: Lower constant intrinsics ; CHECK-NEXT: Remove unreachable blocks from the CFG ; CHECK-NEXT: Expand vector predication intrinsics +; CHECK-NEXT: Instrument function entry/exit with calls to e.g. mcount() (post inlining) ; CHECK-NEXT: Scalarize Masked Memory Intrinsics ; CHECK-NEXT: Expand reduction intrinsics ; CHECK-NEXT: Expand indirectbr instructions diff --git a/llvm/test/CodeGen/X86/instrument-function-inlined.ll b/llvm/test/CodeGen/X86/instrument-function-inlined.ll new file mode 100644 index 00000000000000..5255639a511b05 --- /dev/null +++ b/llvm/test/CodeGen/X86/instrument-function-inlined.ll @@ -0,0 +1,27 @@ +; RUN: llc -mtriple=x86_64-- -O0 < %s | FileCheck %s +; RUN: llc -mtriple=x86_64-- -O1 < %s | FileCheck %s +; RUN: llc -mtriple=x86_64-- -O2 < %s | FileCheck %s + +; The codegen should insert post-inlining instrumentation calls and should not +; insert pre-inlining instrumentation. + +; CHECK-NOT: callq __cyg_profile_func_enter + +define void @leaf_function() #0 { +; CHECK-LABEL: leaf_function: +; CHECK: callq __cyg_profile_func_enter_bare +; CHECK: callq __cyg_profile_func_exit + ret void +} + +define void @root_function() #0 { +entry: +; CHECK-LABEL: root_function: +; CHECK: callq __cyg_profile_func_enter_bare +; CHECK-NEXT: callq leaf_function +; CHECK: callq __cyg_profile_func_exit + call void @leaf_function() + ret void +} + +attributes #0 = { "instrument-function-entry"="__cyg_profile_func_enter" "instrument-function-entry-inlined"="__cyg_profile_func_enter_bare" "instrument-function-exit-inlined"="__cyg_profile_func_exit" } diff --git a/llvm/test/CodeGen/X86/opt-pipeline.ll b/llvm/test/CodeGen/X86/opt-pipeline.ll index 3f57a03decd02c..15c496bfb7f661 100644 --- a/llvm/test/CodeGen/X86/opt-pipeline.ll +++ b/llvm/test/CodeGen/X86/opt-pipeline.ll @@ -61,6 +61,7 @@ ; CHECK-NEXT: Replace intrinsics with calls to vector library ; CHECK-NEXT: Partially inline calls to library functions ; CHECK-NEXT: Expand vector predication intrinsics +; CHECK-NEXT: Instrument function entry/exit with calls to e.g. mcount() (post inlining) ; CHECK-NEXT: Scalarize Masked Memory Intrinsics ; CHECK-NEXT: Expand reduction intrinsics ; CHECK-NEXT: Natural Loop Information diff --git a/llvm/test/Other/new-pass-manager.ll b/llvm/test/Other/new-pass-manager.ll index 904307659ad1f6..db0af54fe4ae88 100644 --- a/llvm/test/Other/new-pass-manager.ll +++ b/llvm/test/Other/new-pass-manager.ll @@ -290,8 +290,9 @@ ; RUN: opt -disable-output -disable-verify -verify-analysis-invalidation=0 -debug-pass-manager \ ; RUN: -passes='default' %s 2>&1 \ ; RUN: | FileCheck %s --check-prefix=CHECK-O0 --check-prefix=%llvmcheckext -; CHECK-O0: Running pass: AlwaysInlinerPass -; CHECK-O0-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}> +; CHECK-O0: Running analysis: InnerAnalysisManagerProxy<{{.*}}> +; CHECK-O0-NEXT: Running pass: EntryExitInstrumenterPass +; CHECK-O0-NEXT: Running pass: AlwaysInlinerPass ; CHECK-O0-NEXT: Running analysis: ProfileSummaryAnalysis ; CHECK-EXT-NEXT: Running pass: {{.*}}Bye ; We don't have checks for CHECK-NOEXT here, but this simplifies the test, while diff --git a/llvm/test/Other/new-pm-O0-defaults.ll b/llvm/test/Other/new-pm-O0-defaults.ll index d7a4c70eb95cc8..e8131ac7fab45a 100644 --- a/llvm/test/Other/new-pm-O0-defaults.ll +++ b/llvm/test/Other/new-pm-O0-defaults.ll @@ -30,11 +30,13 @@ ; RUN: | FileCheck %s --check-prefixes=CHECK,CHECK-LTO ; CHECK-DIS: Running analysis: InnerAnalysisManagerProxy +; CHECK-DIS-NEXT: Running pass: EntryExitInstrumenterPass ; CHECK-DIS-NEXT: Running pass: AddDiscriminatorsPass ; CHECK-DIS-NEXT: Running pass: AlwaysInlinerPass ; CHECK-DIS-NEXT: Running analysis: ProfileSummaryAnalysis -; CHECK-DEFAULT: Running pass: AlwaysInlinerPass -; CHECK-DEFAULT-NEXT: Running analysis: InnerAnalysisManagerProxy +; CHECK-DEFAULT: Running analysis: InnerAnalysisManagerProxy +; CHECK-DEFAULT-NEXT: Running pass: EntryExitInstrumenterPass +; CHECK-DEFAULT-NEXT: Running pass: AlwaysInlinerPass ; CHECK-DEFAULT-NEXT: Running analysis: ProfileSummaryAnalysis ; CHECK-MATRIX: Running pass: LowerMatrixIntrinsicsPass ; CHECK-MATRIX-NEXT: Running analysis: TargetIRAnalysis diff --git a/llvm/test/Other/new-pm-defaults.ll b/llvm/test/Other/new-pm-defaults.ll index 51fb93daa4dfa6..489aed40c190b4 100644 --- a/llvm/test/Other/new-pm-defaults.ll +++ b/llvm/test/Other/new-pm-defaults.ll @@ -101,6 +101,7 @@ ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis ; CHECK-O-NEXT: Running pass: CoroEarlyPass +; CHECK-O-NEXT: Running pass: EntryExitInstrumenterPass ; CHECK-O-NEXT: Running pass: LowerExpectIntrinsicPass ; CHECK-O-NEXT: Running pass: SimplifyCFGPass ; CHECK-O-NEXT: Running analysis: TargetIRAnalysis diff --git a/llvm/test/Other/new-pm-thinlto-prelink-defaults.ll b/llvm/test/Other/new-pm-thinlto-prelink-defaults.ll index 6486639e07b49c..42ef49f8f7c7e4 100644 --- a/llvm/test/Other/new-pm-thinlto-prelink-defaults.ll +++ b/llvm/test/Other/new-pm-thinlto-prelink-defaults.ll @@ -61,7 +61,7 @@ ; Suppress FileCheck --allow-unused-prefixes=false diagnostics. ; CHECK-NOEXT: {{^}} -; CHECK-O: Running pass: Annotation2Metadata +; CHECK-O: Running pass: Annotation2MetadataPass ; CHECK-O-NEXT: Running pass: ForceFunctionAttrsPass ; CHECK-EP-PIPELINE-START-NEXT: Running pass: NoOpModulePass ; CHECK-DIS-NEXT: Running analysis: InnerAnalysisManagerProxy @@ -70,6 +70,7 @@ ; CHECK-O-NODIS-NEXT: Running analysis: InnerAnalysisManagerProxy ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis ; CHECK-O-NEXT: Running pass: CoroEarlyPass +; CHECK-O-NEXT: Running pass: EntryExitInstrumenterPass ; CHECK-O-NEXT: Running pass: LowerExpectIntrinsicPass ; CHECK-O-NEXT: Running pass: SimplifyCFGPass ; CHECK-O-NEXT: Running analysis: TargetIRAnalysis 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 09f9f0f48baddb..e74f88c1a3bf99 100644 --- a/llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll +++ b/llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll @@ -34,6 +34,7 @@ ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis ; CHECK-O-NEXT: Running pass: CoroEarlyPass +; CHECK-O-NEXT: Running pass: EntryExitInstrumenterPass ; CHECK-O-NEXT: Running pass: LowerExpectIntrinsicPass ; CHECK-O-NEXT: Running pass: SimplifyCFGPass ; CHECK-O-NEXT: Running analysis: TargetIRAnalysis 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 47bdbfd2d357d4..210a4ef1f76641 100644 --- a/llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll +++ b/llvm/test/Other/new-pm-thinlto-prelink-samplepgo-defaults.ll @@ -33,6 +33,7 @@ ; CHECK-O-NEXT: Running pass: InferFunctionAttrsPass ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis ; CHECK-O-NEXT: Running pass: CoroEarlyPass +; CHECK-O-NEXT: Running pass: EntryExitInstrumenterPass ; CHECK-O-NEXT: Running pass: LowerExpectIntrinsicPass ; CHECK-O-NEXT: Running pass: SimplifyCFGPass ; CHECK-O-NEXT: Running analysis: TargetIRAnalysis diff --git a/llvm/test/Transforms/EntryExitInstrumenter/pre-inliner-instrumentation.ll b/llvm/test/Transforms/EntryExitInstrumenter/pre-inliner-instrumentation.ll new file mode 100644 index 00000000000000..89e12a29712904 --- /dev/null +++ b/llvm/test/Transforms/EntryExitInstrumenter/pre-inliner-instrumentation.ll @@ -0,0 +1,46 @@ +; RUN: opt -passes="default" -S < %s | FileCheck -check-prefix=INSTRUMENT %s +; RUN: opt -passes="default" -S < %s | FileCheck -check-prefix=INSTRUMENT %s +; RUN: opt -passes="thinlto-pre-link" -S < %s | FileCheck -check-prefix=INSTRUMENT %s +; RUN: opt -passes="thinlto-pre-link" -S < %s | FileCheck -check-prefix=INSTRUMENT %s +; RUN: opt -passes="thinlto" -S < %s | FileCheck -check-prefix=NOINSTRUMENT %s +; RUN: opt -passes="thinlto" -S < %s | FileCheck -check-prefix=NOINSTRUMENT %s +; RUN: opt -passes="lto" -S < %s | FileCheck -check-prefix=NOINSTRUMENT %s +; RUN: opt -passes="lto" -S < %s | FileCheck -check-prefix=NOINSTRUMENT %s + +; Pre-inline instrumentation should be inserted, but not by LTO/ThinLTO passes. + +target triple = "x86_64-unknown-linux" + +define void @leaf_function() #0 { +entry: + ret void +; INSTRUMENT-LABEL: entry: +; INSTRUMENT-NEXT: %0 ={{.*}} call ptr @llvm.returnaddress(i32 0) +; INSTRUMENT-NEXT: {{.* call void @__cyg_profile_func_enter\(ptr( nonnull)? @leaf_function, ptr %0\)}} +; NOINSTRUMENT-NOT: {{.*}} call void @__cyg_profile_func_enter +; INSTRUMENT: {{.*}} call void @__cyg_profile_func_exit +; INSTRUMENT-NEXT: ret void +; NOINSTRUMENT-NOT: {{.*}} call void @__cyg_profile_func_exit +; NOINSTRUMENT-LABEL: entry: +; NOINSTRUMENT-NEXT: ret void +} + + +define void @root_function() #1 { +entry: + call void @leaf_function() + ret void +; INSTRUMENT-LABEL: entry: +; INSTRUMENT-NEXT: %0 ={{.*}} call ptr @llvm.returnaddress(i32 0) +; INSTRUMENT-NEXT: {{.*}} call void @__cyg_profile_func_enter(ptr{{( nonnull)?}} @root_function, ptr %0) +; INSTRUMENT: {{.*}} call void @__cyg_profile_func_enter +; INSTRUMENT: {{.*}} call void @__cyg_profile_func_exit +; INSTRUMENT: {{.*}} call void @__cyg_profile_func_exit +; INSTRUMENT-NEXT: ret void +; NOINSTRUMENT-LABEL: entry: +; NOINSTRUMENT: ret void +; NOINSTRUMENT-NOT: {{.*}} call void @__cyg_profile_func_exit +} + +attributes #0 = { alwaysinline "instrument-function-entry"="__cyg_profile_func_enter" "instrument-function-exit"="__cyg_profile_func_exit" } +attributes #1 = { "instrument-function-entry"="__cyg_profile_func_enter" "instrument-function-exit"="__cyg_profile_func_exit" } diff --git a/llvm/tools/llc/llc.cpp b/llvm/tools/llc/llc.cpp index b292f70ba89dee..e7bf192192b67f 100644 --- a/llvm/tools/llc/llc.cpp +++ b/llvm/tools/llc/llc.cpp @@ -335,6 +335,7 @@ int main(int argc, char **argv) { initializeCodeGen(*Registry); initializeLoopStrengthReducePass(*Registry); initializeLowerIntrinsicsPass(*Registry); + initializePostInlineEntryExitInstrumenterPass(*Registry); initializeUnreachableBlockElimLegacyPassPass(*Registry); initializeConstantHoistingLegacyPassPass(*Registry); initializeScalarOpts(*Registry); diff --git a/llvm/tools/opt/optdriver.cpp b/llvm/tools/opt/optdriver.cpp index 948148bb80498c..d322666b207d06 100644 --- a/llvm/tools/opt/optdriver.cpp +++ b/llvm/tools/opt/optdriver.cpp @@ -439,6 +439,7 @@ extern "C" int optMain( initializeIndirectBrExpandLegacyPassPass(Registry); initializeInterleavedLoadCombinePass(Registry); initializeInterleavedAccessPass(Registry); + initializePostInlineEntryExitInstrumenterPass(Registry); initializeUnreachableBlockElimLegacyPassPass(Registry); initializeExpandReductionsPass(Registry); initializeExpandVectorPredicationPass(Registry);