diff --git a/llvm/include/llvm/Transforms/Instrumentation.h b/llvm/include/llvm/Transforms/Instrumentation.h index 3035cdeeacf68..bb1a0d446aa2a 100644 --- a/llvm/include/llvm/Transforms/Instrumentation.h +++ b/llvm/include/llvm/Transforms/Instrumentation.h @@ -49,6 +49,11 @@ GlobalVariable *createPrivateGlobalForString(Module &M, StringRef Str, // Returns nullptr on failure. Comdat *getOrCreateFunctionComdat(Function &F, Triple &T); +// Place global in a large section for x86-64 ELF binaries to mitigate +// relocation overflow pressure. This can be be used for metadata globals that +// aren't directly accessed by code, which has no performance impact. +void setGlobalVariableLargeSection(Triple &TargetTriple, GlobalVariable &GV); + // Insert GCOV profiling instrumentation struct GCOVOptions { static GCOVOptions getDefault(); diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp index 3a3b41f5dc87d..b175e6f93f3e8 100644 --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -2146,9 +2146,7 @@ ModuleAddressSanitizer::CreateMetadataGlobal(Module &M, Constant *Initializer, Metadata->setSection(getGlobalMetadataSection()); // Place metadata in a large section for x86-64 ELF binaries to mitigate // relocation pressure. - if (TargetTriple.getArch() == Triple::x86_64 && - TargetTriple.getObjectFormat() == Triple::ELF) - Metadata->setCodeModel(CodeModel::Large); + setGlobalVariableLargeSection(TargetTriple, *Metadata); return Metadata; } diff --git a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp index 10258e2546791..d3282779d9f5f 100644 --- a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp +++ b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp @@ -49,6 +49,7 @@ #include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/TargetParser/Triple.h" +#include "llvm/Transforms/Instrumentation.h" #include "llvm/Transforms/Instrumentation/PGOInstrumentation.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/ModuleUtils.h" @@ -1294,6 +1295,7 @@ void InstrProfiling::createDataVariable(InstrProfCntrInstBase *Inc) { *M, ValuesTy, false, Linkage, Constant::getNullValue(ValuesTy), getVarName(Inc, getInstrProfValuesVarPrefix(), Renamed)); ValuesVar->setVisibility(Visibility); + setGlobalVariableLargeSection(TT, *ValuesVar); ValuesVar->setSection( getInstrProfSectionName(IPSK_vals, TT.getObjectFormat())); ValuesVar->setAlignment(Align(8)); @@ -1422,6 +1424,7 @@ void InstrProfiling::emitVNodes() { auto *VNodesVar = new GlobalVariable( *M, VNodesTy, false, GlobalValue::PrivateLinkage, Constant::getNullValue(VNodesTy), getInstrProfVNodesVarName()); + setGlobalVariableLargeSection(TT, *VNodesVar); VNodesVar->setSection( getInstrProfSectionName(IPSK_vnodes, TT.getObjectFormat())); VNodesVar->setAlignment(M->getDataLayout().getABITypeAlign(VNodesTy)); @@ -1449,6 +1452,7 @@ void InstrProfiling::emitNameData() { GlobalValue::PrivateLinkage, NamesVal, getInstrProfNamesVarName()); NamesSize = CompressedNameStr.size(); + setGlobalVariableLargeSection(TT, *NamesVar); NamesVar->setSection( getInstrProfSectionName(IPSK_name, TT.getObjectFormat())); // On COFF, it's important to reduce the alignment down to 1 to prevent the diff --git a/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp b/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp index 806afc8fcdf7c..199afbe966dde 100644 --- a/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp +++ b/llvm/lib/Transforms/Instrumentation/Instrumentation.cpp @@ -85,3 +85,10 @@ Comdat *llvm::getOrCreateFunctionComdat(Function &F, Triple &T) { return C; } +void llvm::setGlobalVariableLargeSection(Triple &TargetTriple, + GlobalVariable &GV) { + if (TargetTriple.getArch() == Triple::x86_64 && + TargetTriple.getObjectFormat() == Triple::ELF) { + GV.setCodeModel(CodeModel::Large); + } +} diff --git a/llvm/test/Instrumentation/InstrProfiling/icall-comdat.ll b/llvm/test/Instrumentation/InstrProfiling/icall-comdat.ll index c90f37c820895..9fbff456ff50b 100644 --- a/llvm/test/Instrumentation/InstrProfiling/icall-comdat.ll +++ b/llvm/test/Instrumentation/InstrProfiling/icall-comdat.ll @@ -1,5 +1,4 @@ ;; Check that static counters are allocated for value profiler - ; RUN: opt < %s -mtriple=x86_64-unknown-linux -passes=instrprof -vp-static-alloc=true -S | FileCheck %s --check-prefix=STATIC ; RUN: opt < %s -mtriple=powerpc-unknown-linux -passes=instrprof -vp-static-alloc=true -S | FileCheck %s --check-prefix=STATIC ; RUN: opt < %s -mtriple=sparc-unknown-linux -passes=instrprof -vp-static-alloc=true -S | FileCheck %s --check-prefix=STATIC @@ -16,6 +15,10 @@ ; RUN: opt %s -mtriple=powerpc64-ibm-aix -passes=instrprof -S | FileCheck %s --check-prefix=ALIGN ; RUN: opt %s -mtriple=x86_64-unknown-linux -passes=instrprof -S | FileCheck %s --check-prefix=ALIGN +;; Check that globals have the proper code model. +; RUN: opt %s -mtriple=x86_64-unknown-linux -passes=instrprof -S | FileCheck %s --check-prefixes=CODEMODEL,CODEMODEL-X8664 +; RUN: opt %s -mtriple=powerpc-unknown-linux -passes=instrprof -S | FileCheck %s --check-prefixes=CODEMODEL,CODEMODEL-PPC + @__profn_foo = private constant [3 x i8] c"foo" @__profn_bar = private constant [3 x i8] c"bar" @@ -46,8 +49,8 @@ declare void @llvm.instrprof.value.profile(ptr, i64, i64, i32, i32) #0 attributes #0 = { nounwind } -; STATIC: @__profvp_foo = private global [1 x i64] zeroinitializer, section "{{[^"]+}}", comdat($__profc_foo) -; STATIC: @__profvp_bar = private global [1 x i64] zeroinitializer, section "{{[^"]+}}", comdat($__profc_bar) +; STATIC: @__profvp_foo = private global [1 x i64] zeroinitializer, section "{{[^"]+}}",{{.*}} comdat($__profc_foo) +; STATIC: @__profvp_bar = private global [1 x i64] zeroinitializer, section "{{[^"]+}}",{{.*}} comdat($__profc_bar) ; STATIC: @__llvm_prf_vnodes ; DYN-NOT: @__profvp_foo @@ -73,5 +76,26 @@ attributes #0 = { nounwind } ; ALIGN: @__profc_bar = private global {{.*}} section "__llvm_prf_cnts",{{.*}} align 8 ; ALIGN: @__profvp_bar = private global {{.*}} section "__llvm_prf_vals",{{.*}} align 8 ; ALIGN: @__profd_bar = private global {{.*}} section "__llvm_prf_data",{{.*}} align 8 -; ALIGN: @__llvm_prf_vnodes = private global {{.*}} section "__llvm_prf_vnds", align 8 -; ALIGN: @__llvm_prf_nm = private constant {{.*}} section "__llvm_prf_names", align 1 +; ALIGN: @__llvm_prf_vnodes = private global {{.*}} section "__llvm_prf_vnds",{{.*}} align 8 +; ALIGN: @__llvm_prf_nm = private constant {{.*}} section "__llvm_prf_names",{{.*}} align 1 + +; CODEMODEL: @__profc_foo = +; CODEMODEL-NOT: code_model "large" +; CODEMODEL: @__profvp_foo = +; CODEMODEL-X8664-SAME: code_model "large" +; CODEMODEL-PPC-NOT: code_model +; CODEMODEL: @__profd_foo = +; CODEMODEL-NOT: code_model "large" +; CODEMODEL: @__profc_bar = +; CODEMODEL-NOT: code_model "large" +; CODEMODEL: @__profvp_bar = +; CODEMODEL-X8664-SAME: code_model "large" +; CODEMODEL-PPC-NOT: code_model +; CODEMODEL: @__profd_bar = +; CODEMODEL-NOT: code_model "large" +; CODEMODEL: @__llvm_prf_vnodes = +; CODEMODEL-X8664-SAME: code_model "large" +; CODEMODEL-PPC-NOT: code_model +; CODEMODEL: @__llvm_prf_nm = +; CODEMODEL-X8664-SAME: code_model "large" +; CODEMODEL-PPC-NOT: code_model