Skip to content

Commit 9a041a7

Browse files
committedFeb 28, 2018
[InstrProfiling] Emit the runtime hook when no counters are lowered
The API verification tool tapi has difficulty processing frameworks which enable code coverage, but which have no code. The profile lowering pass does not emit the runtime hook in this case because no counters are lowered. While the hook is not needed for program correctness (the profile runtime doesn't have to be linked in), it's needed to allow tapi to validate the exported symbol set of instrumented binaries. It was not possible to add a workaround in tapi for empty binaries due to an architectural issue: tapi generates its expected symbol set before it inspects a binary. Changing that model has a higher cost than simply forcing llvm to always emit the runtime hook. rdar://36076904 Differential Revision: https://reviews.llvm.org/D43794 llvm-svn: 326350
1 parent 18a7c51 commit 9a041a7

File tree

5 files changed

+28
-23
lines changed

5 files changed

+28
-23
lines changed
 

‎llvm/include/llvm/Transforms/InstrProfiling.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,8 @@ class InstrProfiling : public PassInfoMixin<InstrProfiling> {
109109
void emitRegistration();
110110

111111
/// Emit the necessary plumbing to pull in the runtime initialization.
112-
void emitRuntimeHook();
112+
/// Returns true if a change was made.
113+
bool emitRuntimeHook();
113114

114115
/// Add uses of our data variables and runtime hook.
115116
void emitUses();

‎llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -448,14 +448,6 @@ static bool containsProfilingIntrinsics(Module &M) {
448448
}
449449

450450
bool InstrProfiling::run(Module &M, const TargetLibraryInfo &TLI) {
451-
// Improve compile time by avoiding linear scans when there is no work.
452-
GlobalVariable *CoverageNamesVar =
453-
M.getNamedGlobal(getCoverageUnusedNamesVarName());
454-
if (!containsProfilingIntrinsics(M) && !CoverageNamesVar)
455-
return false;
456-
457-
bool MadeChange = false;
458-
459451
this->M = &M;
460452
this->TLI = &TLI;
461453
NamesVar = nullptr;
@@ -466,6 +458,15 @@ bool InstrProfiling::run(Module &M, const TargetLibraryInfo &TLI) {
466458
MemOPSizeRangeLast);
467459
TT = Triple(M.getTargetTriple());
468460

461+
// Emit the runtime hook even if no counters are present.
462+
bool MadeChange = emitRuntimeHook();
463+
464+
// Improve compile time by avoiding linear scans when there is no work.
465+
GlobalVariable *CoverageNamesVar =
466+
M.getNamedGlobal(getCoverageUnusedNamesVarName());
467+
if (!containsProfilingIntrinsics(M) && !CoverageNamesVar)
468+
return MadeChange;
469+
469470
// We did not know how many value sites there would be inside
470471
// the instrumented function. This is counting the number of instrumented
471472
// target value sites to enter it as field in the profile data variable.
@@ -498,7 +499,6 @@ bool InstrProfiling::run(Module &M, const TargetLibraryInfo &TLI) {
498499
emitVNodes();
499500
emitNameData();
500501
emitRegistration();
501-
emitRuntimeHook();
502502
emitUses();
503503
emitInitialization();
504504
return true;
@@ -914,15 +914,15 @@ void InstrProfiling::emitRegistration() {
914914
IRB.CreateRetVoid();
915915
}
916916

917-
void InstrProfiling::emitRuntimeHook() {
917+
bool InstrProfiling::emitRuntimeHook() {
918918
// We expect the linker to be invoked with -u<hook_var> flag for linux,
919919
// for which case there is no need to emit the user function.
920920
if (Triple(M->getTargetTriple()).isOSLinux())
921-
return;
921+
return false;
922922

923923
// If the module's provided its own runtime, we don't need to do anything.
924924
if (M->getGlobalVariable(getInstrProfRuntimeHookVarName()))
925-
return;
925+
return false;
926926

927927
// Declare an external variable that will pull in the runtime initialization.
928928
auto *Int32Ty = Type::getInt32Ty(M->getContext());
@@ -947,6 +947,7 @@ void InstrProfiling::emitRuntimeHook() {
947947

948948
// Mark the user variable as used so that it isn't stripped out.
949949
UsedVars.push_back(User);
950+
return true;
950951
}
951952

952953
void InstrProfiling::emitUses() {

‎llvm/test/Instrumentation/InstrProfiling/linkage.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
; RUN: opt < %s -mtriple=x86_64-pc-win32-coff -instrprof -S | FileCheck %s --check-prefix=COFF
88
; RUN: opt < %s -mtriple=x86_64-pc-win32-coff -passes=instrprof -S | FileCheck %s --check-prefix=COFF
99

10+
; OTHER: @__llvm_profile_runtime = external global i32
11+
; LINUX-NOT: @__llvm_profile_runtime = external global i32
12+
1013
@__profn_foo = hidden constant [3 x i8] c"foo"
1114
@__profn_foo_weak = weak hidden constant [8 x i8] c"foo_weak"
1215
@"__profn_linkage.ll:foo_internal" = internal constant [23 x i8] c"linkage.ll:foo_internal"
@@ -52,9 +55,6 @@ define available_externally void @foo_extern() {
5255

5356
declare void @llvm.instrprof.increment(i8*, i64, i32, i32)
5457

55-
; OTHER: @__llvm_profile_runtime = external global i32
56-
; LINUX-NOT: @__llvm_profile_runtime = external global i32
57-
5858
; OTHER: define linkonce_odr hidden i32 @__llvm_profile_runtime_user() {{.*}} {
5959
; OTHER: %[[REG:.*]] = load i32, i32* @__llvm_profile_runtime
6060
; OTHER: ret i32 %[[REG]]

‎llvm/test/Instrumentation/InstrProfiling/no-counters.ll

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
;; No instrumentation should be emitted if there are no counter increments.
1+
;; Emit the runtime hook even if there are no counter increments.
22

3-
; RUN: opt < %s -instrprof -S | FileCheck %s
4-
; RUN: opt < %s -passes=instrprof -S | FileCheck %s
5-
; CHECK-NOT: @__profc
6-
; CHECK-NOT: @__profd
7-
; CHECK-NOT: @__llvm_profile_runtime
3+
; RUN: opt < %s -mtriple=x86_64-apple-macosx10.10.0 -instrprof -S | FileCheck %s -check-prefixes=ALL,DARWIN
4+
; RUN: opt < %s -mtriple=x86_64-apple-macosx10.10.0 -passes=instrprof -S | FileCheck %s -check-prefixes=ALL,DARWIN
5+
; RUN: opt < %s -mtriple=x86_64-linux-unknown -passes=instrprof -S | FileCheck %s -check-prefixes=ALL,LINUX
6+
; ALL-NOT: @__profc
7+
; ALL-NOT: @__profd
8+
; DARWIN: @__llvm_profile_runtime
9+
; LINUX-NOT: @__llvm_profile_runtime
810

911
define void @foo() {
1012
ret void

‎llvm/test/Instrumentation/InstrProfiling/profiling.ll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
target triple = "x86_64-apple-macosx10.10.0"
55

6+
; CHECK: @__llvm_profile_runtime = external global i32
7+
68
@__profn_foo = hidden constant [3 x i8] c"foo"
79
; CHECK-NOT: __profn_foo
810
@__profn_bar = hidden constant [4 x i8] c"bar\00"
@@ -35,5 +37,4 @@ define void @baz() {
3537

3638
declare void @llvm.instrprof.increment(i8*, i64, i32, i32)
3739

38-
; CHECK: @__llvm_profile_runtime = external global i32
3940
; CHECK: @llvm.used = appending global {{.*}} @__profd_foo {{.*}} @__profd_bar {{.*}} @__profd_baz {{.*}} section "llvm.metadata"

0 commit comments

Comments
 (0)
Please sign in to comment.