[PATCH] D34134: [InstrProf] Don't take the address of available_externally functions
Vedant Kumar via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 12 19:32:38 PDT 2017
vsk created this revision.
Doing so breaks compilation of the following C program
(under -fprofile-instr-generate):
__attribute__((always_inline)) inline int foo() { return 0; }
int main() { return foo(); }
At link time, we fail because taking the address of an
available_externally function creates an undefined external reference,
which the TU cannot provide.
Emitting the function definition into the object file at all appears to
be a violation of the langref: "Globals with 'available_externally'
linkage are never emitted into the object file corresponding to the LLVM
module."
I noticed that the profd metadata is actually constant data when they do
not contain function addresses, so I've made llvm treat them as
constants in this change when appropriate.
Note: This change shouldn't regress value profiling performance, since
(afaik) indirect callees are usually not marked 'always_inline'.
Testing: check-llvm, check-profile
https://reviews.llvm.org/D34134
Files:
lib/Transforms/Instrumentation/InstrProfiling.cpp
test/Instrumentation/InstrProfiling/linkage.ll
test/Transforms/PGOProfile/comdat_internal.ll
Index: test/Transforms/PGOProfile/comdat_internal.ll
===================================================================
--- test/Transforms/PGOProfile/comdat_internal.ll
+++ test/Transforms/PGOProfile/comdat_internal.ll
@@ -14,7 +14,7 @@
; CHECK: @__llvm_profile_raw_version = constant i64 {{[0-9]+}}, comdat
; CHECK-NOT: __profn__stdin__foo
; CHECK: @__profc__stdin__foo.[[FOO_HASH]] = private global [1 x i64] zeroinitializer, section "__llvm_prf_cnts", comdat($__profv__stdin__foo.[[FOO_HASH]]), align 8
-; CHECK: @__profd__stdin__foo.[[FOO_HASH]] = private global { i64, i64, i64*, i8*, i8*, i32, [2 x i16] } { i64 -5640069336071256030, i64 [[FOO_HASH]], i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc__stdin__foo.[[FOO_HASH]], i32 0, i32 0), i8* null
+; CHECK: @__profd__stdin__foo.[[FOO_HASH]] = private constant { i64, i64, i64*, i8*, i8*, i32, [2 x i16] } { i64 -5640069336071256030, i64 [[FOO_HASH]], i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc__stdin__foo.[[FOO_HASH]], i32 0, i32 0), i8* null
; CHECK-NOT: bitcast (i32 ()* @foo to i8*)
; CHECK-SAME: , i8* null, i32 1, [2 x i16] zeroinitializer }, section "__llvm_prf_data", comdat($__profv__stdin__foo.[[FOO_HASH]]), align 8
; CHECK: @__llvm_prf_nm
Index: test/Instrumentation/InstrProfiling/linkage.ll
===================================================================
--- test/Instrumentation/InstrProfiling/linkage.ll
+++ test/Instrumentation/InstrProfiling/linkage.ll
@@ -28,7 +28,7 @@
}
; COMMON: @"__profc_linkage.ll:foo_internal" = internal global
-; COMMON: @"__profd_linkage.ll:foo_internal" = internal global
+; COMMON: @"__profd_linkage.ll:foo_internal" = internal constant
define internal void @foo_internal() {
call void @llvm.instrprof.increment(i8* getelementptr inbounds ([23 x i8], [23 x i8]* @"__profn_linkage.ll:foo_internal", i32 0, i32 0), i64 0, i32 1, i32 0)
ret void
@@ -42,9 +42,9 @@
}
; LINUX: @__profc_foo_extern = linkonce_odr hidden global {{.*}}section "__llvm_prf_cnts", comdat($__profv_foo_extern), align 8
-; LINUX: @__profd_foo_extern = linkonce_odr hidden global {{.*}}section "__llvm_prf_data", comdat($__profv_foo_extern), align 8
+; LINUX: @__profd_foo_extern = linkonce_odr hidden constant {{.*}}section "__llvm_prf_data", comdat($__profv_foo_extern), align 8
; OTHER: @__profc_foo_extern = linkonce_odr hidden global
-; OTHER: @__profd_foo_extern = linkonce_odr hidden global
+; OTHER: @__profd_foo_extern = linkonce_odr hidden constant
define available_externally void @foo_extern() {
call void @llvm.instrprof.increment(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @__profn_foo_extern, i32 0, i32 0), i64 0, i32 1, i32 0)
ret void
Index: lib/Transforms/Instrumentation/InstrProfiling.cpp
===================================================================
--- lib/Transforms/Instrumentation/InstrProfiling.cpp
+++ lib/Transforms/Instrumentation/InstrProfiling.cpp
@@ -343,8 +343,9 @@
static inline bool shouldRecordFunctionAddr(Function *F) {
// Check the linkage
- if (!F->hasLinkOnceLinkage() && !F->hasLocalLinkage() &&
- !F->hasAvailableExternallyLinkage())
+ if (F->hasAvailableExternallyLinkage())
+ return false;
+ if (!F->hasLinkOnceLinkage() && !F->hasLocalLinkage())
return true;
// Prohibit function address recording if the function is both internal and
// COMDAT. This avoids the profile data variable referencing internal symbols
@@ -470,9 +471,10 @@
#define INSTR_PROF_DATA(Type, LLVMType, Name, Init) Init,
#include "llvm/ProfileData/InstrProfData.inc"
};
- auto *Data = new GlobalVariable(*M, DataTy, false, NamePtr->getLinkage(),
- ConstantStruct::get(DataTy, DataVals),
- getVarName(Inc, getInstrProfDataVarPrefix()));
+ auto *Data = new GlobalVariable(
+ *M, DataTy, /*isConstant=*/isa<ConstantPointerNull>(FunctionAddr),
+ NamePtr->getLinkage(), ConstantStruct::get(DataTy, DataVals),
+ getVarName(Inc, getInstrProfDataVarPrefix()));
Data->setVisibility(NamePtr->getVisibility());
Data->setSection(getInstrProfSectionName(IPSK_data, TT.getObjectFormat()));
Data->setAlignment(INSTR_PROF_DATA_ALIGNMENT);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D34134.102290.patch
Type: text/x-patch
Size: 4219 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170613/4053eb01/attachment.bin>
More information about the llvm-commits
mailing list