[llvm] r372020 - [PGO] Use linkonce_odr linkage for __profd_ variables in comdat groups

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 16 11:49:09 PDT 2019


Author: rnk
Date: Mon Sep 16 11:49:09 2019
New Revision: 372020

URL: http://llvm.org/viewvc/llvm-project?rev=372020&view=rev
Log:
[PGO] Use linkonce_odr linkage for __profd_ variables in comdat groups

This fixes relocations against __profd_ symbols in discarded sections,
which is PR41380.

In general, instrumentation happens very early, and optimization and
inlining happens afterwards. The counters for a function are calculated
early, and after inlining, counters for an inlined function may be
widely referenced by other functions.

For C++ inline functions of all kinds (linkonce_odr &
available_externally mainly), instr profiling wants to deduplicate these
__profc_ and __profd_ globals. Otherwise the binary would be quite
large.

I made __profd_ and __profc_ comdat in r355044, but I chose to make
__profd_ internal. At the time, I was only dealing with coverage, and in
that case, none of the instrumentation needs to reference __profd_.
However, if you use PGO, then instrumentation passes add calls to
__llvm_profile_instrument_range which reference __profd_ globals. The
solution is to make these globals externally visible by using
linkonce_odr linkage for data as was done for counters.

This is safe because PGO adds a CFG hash to the names of the data and
counter globals, so if different TUs have different globals, they will
get different data and counter arrays.

Reviewers: xur, hans

Differential Revision: https://reviews.llvm.org/D67579

Modified:
    llvm/trunk/lib/Transforms/Instrumentation/InstrProfiling.cpp
    llvm/trunk/test/Instrumentation/InstrProfiling/PR23499.ll
    llvm/trunk/test/Instrumentation/InstrProfiling/comdat.ll
    llvm/trunk/test/Instrumentation/InstrProfiling/linkage.ll

Modified: llvm/trunk/lib/Transforms/Instrumentation/InstrProfiling.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/InstrProfiling.cpp?rev=372020&r1=372019&r2=372020&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/InstrProfiling.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/InstrProfiling.cpp Mon Sep 16 11:49:09 2019
@@ -740,9 +740,8 @@ InstrProfiling::getOrCreateRegionCounter
     PD = It->second;
   }
 
-  // Match the linkage and visibility of the name global, except on COFF, where
-  // the linkage must be local and consequentially the visibility must be
-  // default.
+  // Match the linkage and visibility of the name global. COFF supports using
+  // comdats with internal symbols, so do that if we can.
   Function *Fn = Inc->getParent()->getParent();
   GlobalValue::LinkageTypes Linkage = NamePtr->getLinkage();
   GlobalValue::VisibilityTypes Visibility = NamePtr->getVisibility();
@@ -759,15 +758,16 @@ InstrProfiling::getOrCreateRegionCounter
   // of the parent function, that will result in relocations against discarded
   // sections.
   Comdat *Cmdt = nullptr;
-  GlobalValue::LinkageTypes CounterLinkage = Linkage;
   if (needsComdatForCounter(*Fn, *M)) {
     StringRef CmdtPrefix = getInstrProfComdatPrefix();
     if (TT.isOSBinFormatCOFF()) {
       // For COFF, the comdat group name must be the name of a symbol in the
       // group. Use the counter variable name, and upgrade its linkage to
-      // something externally visible, like linkonce_odr.
+      // something externally visible, like linkonce_odr. Use hidden visibility
+      // to imply that this is dso local.
       CmdtPrefix = getInstrProfCountersVarPrefix();
-      CounterLinkage = GlobalValue::LinkOnceODRLinkage;
+      Linkage = GlobalValue::LinkOnceODRLinkage;
+      Visibility = GlobalValue::HiddenVisibility;
     }
     Cmdt = M->getOrInsertComdat(getVarName(Inc, CmdtPrefix));
   }
@@ -786,7 +786,7 @@ InstrProfiling::getOrCreateRegionCounter
       getInstrProfSectionName(IPSK_cnts, TT.getObjectFormat()));
   CounterPtr->setAlignment(8);
   CounterPtr->setComdat(Cmdt);
-  CounterPtr->setLinkage(CounterLinkage);
+  CounterPtr->setLinkage(Linkage);
 
   auto *Int8PtrTy = Type::getInt8PtrTy(Ctx);
   // Allocate statically the array of pointers to value profile nodes for
@@ -841,6 +841,7 @@ InstrProfiling::getOrCreateRegionCounter
   Data->setSection(getInstrProfSectionName(IPSK_data, TT.getObjectFormat()));
   Data->setAlignment(INSTR_PROF_DATA_ALIGNMENT);
   Data->setComdat(Cmdt);
+  Data->setLinkage(Linkage);
 
   PD.RegionCounters = CounterPtr;
   PD.DataVar = Data;

Modified: llvm/trunk/test/Instrumentation/InstrProfiling/PR23499.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/InstrProfiling/PR23499.ll?rev=372020&r1=372019&r2=372020&view=diff
==============================================================================
--- llvm/trunk/test/Instrumentation/InstrProfiling/PR23499.ll (original)
+++ llvm/trunk/test/Instrumentation/InstrProfiling/PR23499.ll Mon Sep 16 11:49:09 2019
@@ -20,8 +20,8 @@ $_Z3barIvEvv = comdat any
 
 
 ; COFF-NOT: __profn__Z3barIvEvv
-; COFF: @__profc__Z3barIvEvv = linkonce_odr dso_local global [1 x i64] zeroinitializer, section "{{.*}}prfc$M", comdat, align 8
-; COFF: @__profd__Z3barIvEvv = internal global { i64, i64, i64*, i8*, i8*, i32, [2 x i16] } { i64 4947693190065689389, i64 0, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc__Z3barIvEvv, i32 0, i32 0), i8*{{.*}}, i8* null, i32 1, [2 x i16] zeroinitializer }, section "{{.*}}prfd{{.*}}", comdat($__profc__Z3barIvEvv), align 8
+; COFF: @__profc__Z3barIvEvv = linkonce_odr hidden global [1 x i64] zeroinitializer, section "{{.*}}prfc$M", comdat, align 8
+; COFF: @__profd__Z3barIvEvv = linkonce_odr hidden global { i64, i64, i64*, i8*, i8*, i32, [2 x i16] } { i64 4947693190065689389, i64 0, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__profc__Z3barIvEvv, i32 0, i32 0), i8*{{.*}}, i8* null, i32 1, [2 x i16] zeroinitializer }, section "{{.*}}prfd{{.*}}", comdat($__profc__Z3barIvEvv), align 8
 
 
 declare void @llvm.instrprof.increment(i8*, i64, i32, i32) #1

Modified: llvm/trunk/test/Instrumentation/InstrProfiling/comdat.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/InstrProfiling/comdat.ll?rev=372020&r1=372019&r2=372020&view=diff
==============================================================================
--- llvm/trunk/test/Instrumentation/InstrProfiling/comdat.ll (original)
+++ llvm/trunk/test/Instrumentation/InstrProfiling/comdat.ll Mon Sep 16 11:49:09 2019
@@ -17,8 +17,8 @@ $foo_inline = comdat any
 
 ; ELF: @__profc_foo_inline = linkonce_odr hidden global{{.*}}, section "__llvm_prf_cnts", comdat($__profv_foo_inline), align 8
 ; ELF: @__profd_foo_inline = linkonce_odr hidden global{{.*}}, section "__llvm_prf_data", comdat($__profv_foo_inline), align 8
-; COFF: @__profc_foo_inline = linkonce_odr dso_local global{{.*}}, section ".lprfc$M", comdat, align 8
-; COFF: @__profd_foo_inline = internal global{{.*}}, section ".lprfd$M", comdat($__profc_foo_inline), align 8
+; COFF: @__profc_foo_inline = linkonce_odr hidden global{{.*}}, section ".lprfc$M", comdat, align 8
+; COFF: @__profd_foo_inline = linkonce_odr hidden global{{.*}}, section ".lprfd$M", comdat($__profc_foo_inline), align 8
 define weak_odr void @foo_inline() comdat {
   call void @llvm.instrprof.increment(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @__profn_foo_inline, i32 0, i32 0), i64 0, i32 1, i32 0)
   ret void
@@ -30,8 +30,8 @@ $foo_extern = comdat any
 
 ; ELF: @__profc_foo_extern = linkonce_odr hidden global{{.*}}, section "__llvm_prf_cnts", comdat($__profv_foo_extern)
 ; ELF: @__profd_foo_extern = linkonce_odr hidden global{{.*}}, section "__llvm_prf_data", comdat($__profv_foo_extern)
-; COFF: @__profc_foo_extern = linkonce_odr dso_local global{{.*}}, section ".lprfc$M", comdat, align 8
-; COFF: @__profd_foo_extern = internal global{{.*}}, section ".lprfd$M", comdat($__profc_foo_extern), align 8
+; COFF: @__profc_foo_extern = linkonce_odr hidden global{{.*}}, section ".lprfc$M", comdat, align 8
+; COFF: @__profd_foo_extern = linkonce_odr hidden global{{.*}}, section ".lprfd$M", comdat($__profc_foo_extern), align 8
 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

Modified: llvm/trunk/test/Instrumentation/InstrProfiling/linkage.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/InstrProfiling/linkage.ll?rev=372020&r1=372019&r2=372020&view=diff
==============================================================================
--- llvm/trunk/test/Instrumentation/InstrProfiling/linkage.ll (original)
+++ llvm/trunk/test/Instrumentation/InstrProfiling/linkage.ll Mon Sep 16 11:49:09 2019
@@ -57,8 +57,8 @@ define linkonce_odr void @foo_inline() {
 ; LINUX: @__profd_foo_extern = linkonce_odr hidden global {{.*}}section "__llvm_prf_data", comdat($__profv_foo_extern), align 8
 ; MACHO: @__profc_foo_extern = linkonce_odr hidden global
 ; MACHO: @__profd_foo_extern = linkonce_odr hidden global
-; COFF: @__profc_foo_extern = linkonce_odr dso_local global {{.*}}section ".lprfc$M", comdat, align 8
-; COFF: @__profd_foo_extern = internal global {{.*}}section ".lprfd$M", comdat($__profc_foo_extern), align 8
+; COFF: @__profc_foo_extern = linkonce_odr hidden global {{.*}}section ".lprfc$M", comdat, align 8
+; COFF: @__profd_foo_extern = linkonce_odr hidden global {{.*}}section ".lprfd$M", comdat($__profc_foo_extern), align 8
 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




More information about the llvm-commits mailing list