From: Duncan P. N. Exon Smith Date: Thu, 20 Mar 2014 22:50:08 +0000 (+0000) Subject: PGO: Don't define instrumentation data available_externally X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=81e3346e95b2e3f65e894f5e31d1a8141a4bbace;p=clang PGO: Don't define instrumentation data available_externally Variables with available_externally linkage can be dropped at will. This causes link errors, since there are still references to the instrumentation! linkonce_odr is almost equivalent, so use that instead. As a drive-by fix (I don't have an Elf system, so I'm not sure how to write a testcase), use linkonce linkage for the instrumentation of extern_weak functions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@204408 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CodeGenPGO.cpp b/lib/CodeGen/CodeGenPGO.cpp index 0dfecfc36c..99109f42e4 100644 --- a/lib/CodeGen/CodeGenPGO.cpp +++ b/lib/CodeGen/CodeGenPGO.cpp @@ -824,7 +824,22 @@ void CodeGenPGO::assignRegionCounters(const Decl *D, llvm::Function *Fn) { if (!D) return; setFuncName(Fn); + + // Set the linkage for variables based on the function linkage. Usually, we + // want to match it, but available_externally and extern_weak both have the + // wrong semantics. VarLinkage = Fn->getLinkage(); + switch (VarLinkage) { + case llvm::GlobalValue::ExternalWeakLinkage: + VarLinkage = llvm::GlobalValue::LinkOnceAnyLinkage; + break; + case llvm::GlobalValue::AvailableExternallyLinkage: + VarLinkage = llvm::GlobalValue::LinkOnceODRLinkage; + break; + default: + break; + } + mapRegionCounters(D); if (InstrumentRegions) emitCounterVariables(); diff --git a/test/Profile/c-linkage-available_externally.c b/test/Profile/c-linkage-available_externally.c new file mode 100644 index 0000000000..cbdf306c82 --- /dev/null +++ b/test/Profile/c-linkage-available_externally.c @@ -0,0 +1,12 @@ +// Make sure instrementation data from available_externally functions doesn't +// get thrown out. +// RUN: %clang_cc1 -O2 -triple x86_64-apple-macosx10.9 -main-file-name c-linkage-available_externally.c %s -o - -emit-llvm -fprofile-instr-generate | FileCheck %s + +// CHECK: @__llvm_profile_counters_foo = linkonce_odr global [1 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8 +// CHECK: @__llvm_profile_name_foo = linkonce_odr constant [3 x i8] c"foo", section "__DATA,__llvm_prf_names", align 1 +// CHECK: @__llvm_profile_data_foo = linkonce_odr constant { i32, i32, i64, i8*, i64* } { i32 3, i32 1, i64 1, i8* getelementptr inbounds ([3 x i8]* @__llvm_profile_name_foo, i32 0, i32 0), i64* getelementptr inbounds ([1 x i64]* @__llvm_profile_counters_foo, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8 +inline int foo(void) { return 1; } + +int main(void) { + return foo(); +}