Put profile variables of COMDAT functions to it's own COMDAT group.
authorWei Mi <wmi@google.com>
Wed, 23 Sep 2015 22:40:45 +0000 (22:40 +0000)
committerWei Mi <wmi@google.com>
Wed, 23 Sep 2015 22:40:45 +0000 (22:40 +0000)
In -fprofile-instr-generate compilation, to remove the redundant profile
variables for the COMDAT functions, these variables are placed in the same
COMDAT group as its associated function. This way when the COMDAT function
is not picked by the linker, those profile variables will also not be
output in the final binary. This may cause warning when mix link objects
built w and wo -fprofile-instr-generate.

This patch puts the profile variables for COMDAT functions to its own COMDAT
group to avoid the problem.

Patch by xur.
Differential Revision: http://reviews.llvm.org/D12248

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@248440 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Instrumentation/InstrProfiling.cpp
test/Instrumentation/InstrProfiling/PR23499.ll

index 712bf8edc7ead8157ea4830fac9bd660963a0545..8ecfda64f1df7923f711debae9e3a6fb45b23ac9 100644 (file)
@@ -196,13 +196,17 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
   if (It != RegionCounters.end())
     return It->second;
 
-  // Move the name variable to the right section. Make sure it is placed in the
-  // same comdat as its associated function. Otherwise, we may get multiple
-  // counters for the same function in certain cases.
+  // Move the name variable to the right section. Place them in a COMDAT group
+  // if the associated function is a COMDAT. This will make sure that
+  // only one copy of counters of the COMDAT function will be emitted after
+  // linking.
   Function *Fn = Inc->getParent()->getParent();
+  Comdat *ProfileVarsComdat = nullptr;
+  if (Fn->hasComdat())
+    ProfileVarsComdat = M->getOrInsertComdat(StringRef(getVarName(Inc, "vars")));
   Name->setSection(getNameSection());
   Name->setAlignment(1);
-  Name->setComdat(Fn->getComdat());
+  Name->setComdat(ProfileVarsComdat);
 
   uint64_t NumCounters = Inc->getNumCounters()->getZExtValue();
   LLVMContext &Ctx = M->getContext();
@@ -215,7 +219,7 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
   Counters->setVisibility(Name->getVisibility());
   Counters->setSection(getCountersSection());
   Counters->setAlignment(8);
-  Counters->setComdat(Fn->getComdat());
+  Counters->setComdat(ProfileVarsComdat);
 
   RegionCounters[Inc->getName()] = Counters;
 
@@ -240,7 +244,7 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
   Data->setVisibility(Name->getVisibility());
   Data->setSection(getDataSection());
   Data->setAlignment(8);
-  Data->setComdat(Fn->getComdat());
+  Data->setComdat(ProfileVarsComdat);
 
   // Mark the data variable as used so that it isn't stripped out.
   UsedVars.push_back(Data);
index 5aae735120bee1beb944a3de3b9b4f8ac1975ce1..8988a9aa3bea202966a5a74ab8518bd268488d99 100644 (file)
@@ -8,9 +8,9 @@ $_Z3barIvEvv = comdat any
 
 @__llvm_profile_name__Z3barIvEvv = linkonce_odr hidden constant [11 x i8] c"_Z3barIvEvv", align 1
 
-; CHECK: @__llvm_profile_name__Z3barIvEvv = linkonce_odr hidden constant [11 x i8] c"_Z3barIvEvv", section "{{.*}}__llvm_prf_names", comdat($_Z3barIvEvv), align 1
-; CHECK: @__llvm_profile_counters__Z3barIvEvv = linkonce_odr hidden global [1 x i64] zeroinitializer, section "{{.*}}__llvm_prf_cnts", comdat($_Z3barIvEvv), align 8
-; CHECK: @__llvm_profile_data__Z3barIvEvv = linkonce_odr hidden constant { i32, i32, i64, i8*, i64* } { i32 11, i32 1, i64 0, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @__llvm_profile_name__Z3barIvEvv, i32 0, i32 0), i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__llvm_profile_counters__Z3barIvEvv, i32 0, i32 0) }, section "{{.*}}__llvm_prf_data", comdat($_Z3barIvEvv), align 8
+; CHECK: @__llvm_profile_name__Z3barIvEvv = linkonce_odr hidden constant [11 x i8] c"_Z3barIvEvv", section "{{.*}}__llvm_prf_names", comdat($__llvm_profile_vars__Z3barIvEvv), align 1
+; CHECK: @__llvm_profile_counters__Z3barIvEvv = linkonce_odr hidden global [1 x i64] zeroinitializer, section "{{.*}}__llvm_prf_cnts", comdat($__llvm_profile_vars__Z3barIvEvv), align 8
+; CHECK: @__llvm_profile_data__Z3barIvEvv = linkonce_odr hidden constant { i32, i32, i64, i8*, i64* } { i32 11, i32 1, i64 0, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @__llvm_profile_name__Z3barIvEvv, i32 0, i32 0), i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__llvm_profile_counters__Z3barIvEvv, i32 0, i32 0) }, section "{{.*}}__llvm_prf_data", comdat($__llvm_profile_vars__Z3barIvEvv), align 8
 
 declare void @llvm.instrprof.increment(i8*, i64, i32, i32) #1