summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2018-02-07 22:15:33 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2018-02-07 22:15:33 +0000
commit699f5d6bbc43fbd62e60f913379565bd86c6df8c (patch)
treed960a41f09b97d96b0eea7e8c5b7881b8bfa24a5 /clang/lib
parent9bc04e98c5bd429cd49790ebf0a799c6a71427c5 (diff)
downloadbcm5719-llvm-699f5d6bbc43fbd62e60f913379565bd86c6df8c.tar.gz
bcm5719-llvm-699f5d6bbc43fbd62e60f913379565bd86c6df8c.zip
Recommit r324107 again.
The difference from the previous try is that we no longer directly access function declarations from position independent executables. It should work, but currently doesn't with some linkers. It now includes a fix to not mark available_externally definitions as dso_local. Original message: Start setting dso_local in clang. This starts adding dso_local to clang. The hope is to eventually have TargetMachine::shouldAssumeDsoLocal go away. My objective for now is to move enough of it to clang to remove the need for the TargetMachine one to handle PIE copy relocations and -fno-plt. With that it should then be easy to implement a -fno-copy-reloc in clang. This patch just adds the cases where we assume a symbol to be local based on the file being compiled for an executable or a shared library. llvm-svn: 324535
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/CGDecl.cpp3
-rw-r--r--clang/lib/CodeGen/CGVTT.cpp2
-rw-r--r--clang/lib/CodeGen/CGVTables.cpp4
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp67
-rw-r--r--clang/lib/CodeGen/CodeGenModule.h4
-rw-r--r--clang/lib/CodeGen/ItaniumCXXABI.cpp8
6 files changed, 77 insertions, 11 deletions
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index e3e4098e7cc..7c05a0dee38 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -240,7 +240,7 @@ llvm::Constant *CodeGenModule::getOrCreateStaticVarDecl(
getModule(), LTy, Ty.isConstant(getContext()), Linkage, Init, Name,
nullptr, llvm::GlobalVariable::NotThreadLocal, TargetAS);
GV->setAlignment(getContext().getDeclAlign(&D).getQuantity());
- setGlobalVisibility(GV, &D);
+ setGVProperties(GV, &D);
if (supportsCOMDAT() && GV->isWeakForLinker())
GV->setComdat(TheModule.getOrInsertComdat(GV->getName()));
@@ -344,6 +344,7 @@ CodeGenFunction::AddInitializerToStaticVarDecl(const VarDecl &D,
OldGV->getThreadLocalMode(),
CGM.getContext().getTargetAddressSpace(D.getType()));
GV->setVisibility(OldGV->getVisibility());
+ GV->setDSOLocal(OldGV->isDSOLocal());
GV->setComdat(OldGV->getComdat());
// Steal the name of the old global
diff --git a/clang/lib/CodeGen/CGVTT.cpp b/clang/lib/CodeGen/CGVTT.cpp
index 92fd93b5ca3..41c8c943f54 100644
--- a/clang/lib/CodeGen/CGVTT.cpp
+++ b/clang/lib/CodeGen/CGVTT.cpp
@@ -100,7 +100,7 @@ CodeGenVTables::EmitVTTDefinition(llvm::GlobalVariable *VTT,
VTT->setComdat(CGM.getModule().getOrInsertComdat(VTT->getName()));
// Set the right visibility.
- CGM.setGlobalVisibility(VTT, RD);
+ CGM.setGVProperties(VTT, RD);
}
llvm::GlobalVariable *CodeGenVTables::GetAddrOfVTT(const CXXRecordDecl *RD) {
diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp
index 67388ee208d..7a5c6cfe655 100644
--- a/clang/lib/CodeGen/CGVTables.cpp
+++ b/clang/lib/CodeGen/CGVTables.cpp
@@ -51,7 +51,7 @@ llvm::Constant *CodeGenModule::GetAddrOfThunk(GlobalDecl GD,
static void setThunkVisibility(CodeGenModule &CGM, const CXXMethodDecl *MD,
const ThunkInfo &Thunk, llvm::Function *Fn) {
- CGM.setGlobalVisibility(Fn, MD);
+ CGM.setGVProperties(Fn, MD);
}
static void setThunkProperties(CodeGenModule &CGM, const ThunkInfo &Thunk,
@@ -730,7 +730,7 @@ CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD,
// Create the variable that will hold the construction vtable.
llvm::GlobalVariable *VTable =
CGM.CreateOrReplaceCXXRuntimeVariable(Name, VTType, Linkage);
- CGM.setGlobalVisibility(VTable, RD);
+ CGM.setGVProperties(VTable, RD);
// V-tables are always unnamed_addr.
VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index b3974b6de4b..7fa4fddc79e 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -715,6 +715,63 @@ void CodeGenModule::setGlobalVisibility(llvm::GlobalValue *GV,
GV->setVisibility(GetLLVMVisibility(LV.getVisibility()));
}
+static bool shouldAssumeDSOLocal(const CodeGenModule &CGM,
+ llvm::GlobalValue *GV, const NamedDecl *D) {
+ const llvm::Triple &TT = CGM.getTriple();
+ // Only handle ELF for now.
+ if (!TT.isOSBinFormatELF())
+ return false;
+
+ // If this is not an executable, don't assume anything is local.
+ const auto &CGOpts = CGM.getCodeGenOpts();
+ llvm::Reloc::Model RM = CGOpts.RelocationModel;
+ const auto &LOpts = CGM.getLangOpts();
+ if (RM != llvm::Reloc::Static && !LOpts.PIE)
+ return false;
+
+ // A definition cannot be preempted from an executable.
+ if (!GV->isDeclarationForLinker())
+ return true;
+
+ // Most PIC code sequences that assume that a symbol is local cannot produce a
+ // 0 if it turns out the symbol is undefined. While this is ABI and relocation
+ // depended, it seems worth it to handle it here.
+ if (RM == llvm::Reloc::PIC_ && GV->hasExternalWeakLinkage())
+ return false;
+
+ // PPC has no copy relocations and cannot use a plt entry as a symbol address.
+ llvm::Triple::ArchType Arch = TT.getArch();
+ if (Arch == llvm::Triple::ppc || Arch == llvm::Triple::ppc64 ||
+ Arch == llvm::Triple::ppc64le)
+ return false;
+
+ // If we can use copy relocations we can assume it is local.
+ if (isa<VarDecl>(D) &&
+ (RM == llvm::Reloc::Static || CGOpts.PIECopyRelocations))
+ return true;
+
+ // If we can use a plt entry as the symbol address we can assume it
+ // is local.
+ // FIXME: This should work for PIE, but the gold linker doesn't support it.
+ if (isa<FunctionDecl>(D) && !CGOpts.NoPLT && RM == llvm::Reloc::Static)
+ return true;
+
+ // Otherwise don't assue it is local.
+ return false;
+}
+
+void CodeGenModule::setDSOLocal(llvm::GlobalValue *GV,
+ const NamedDecl *D) const {
+ if (shouldAssumeDSOLocal(*this, GV, D))
+ GV->setDSOLocal(true);
+}
+
+void CodeGenModule::setGVProperties(llvm::GlobalValue *GV,
+ const NamedDecl *D) const {
+ setGlobalVisibility(GV, D);
+ setDSOLocal(GV, D);
+}
+
static llvm::GlobalVariable::ThreadLocalMode GetLLVMTLSModel(StringRef S) {
return llvm::StringSwitch<llvm::GlobalVariable::ThreadLocalMode>(S)
.Case("global-dynamic", llvm::GlobalVariable::GeneralDynamicTLSModel)
@@ -1172,7 +1229,7 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
void CodeGenModule::SetCommonAttributes(const Decl *D,
llvm::GlobalValue *GV) {
if (const auto *ND = dyn_cast_or_null<NamedDecl>(D))
- setGlobalVisibility(GV, ND);
+ setGVProperties(GV, ND);
else
GV->setVisibility(llvm::GlobalValue::DefaultVisibility);
@@ -1312,7 +1369,7 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F,
// overridden by a definition.
setLinkageForGV(F, FD);
- setGlobalVisibility(F, FD);
+ setGVProperties(F, FD);
if (FD->getAttr<PragmaClangTextSectionAttr>()) {
F->addFnAttr("implicit-section-name");
@@ -2639,7 +2696,7 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName,
GV->setAlignment(getContext().getDeclAlign(D).getQuantity());
setLinkageForGV(GV, D);
- setGlobalVisibility(GV, D);
+ setGVProperties(GV, D);
if (D->getTLSKind()) {
if (D->getTLSKind() == VarDecl::TLS_Dynamic)
@@ -3458,7 +3515,7 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD,
setFunctionDLLStorageClass(GD, Fn);
// FIXME: this is redundant with part of setFunctionDefinitionAttributes
- setGlobalVisibility(Fn, D);
+ setGVProperties(Fn, D);
MaybeHandleStaticInExternC(D, Fn);
@@ -4054,7 +4111,7 @@ ConstantAddress CodeGenModule::GetAddrOfGlobalTemporary(
getModule(), Type, Constant, Linkage, InitialValue, Name.c_str(),
/*InsertBefore=*/nullptr, llvm::GlobalVariable::NotThreadLocal, TargetAS);
if (emitter) emitter->finalize(GV);
- setGlobalVisibility(GV, VD);
+ setGVProperties(GV, VD);
GV->setAlignment(Align.getQuantity());
if (supportsCOMDAT() && GV->isWeakForLinker())
GV->setComdat(TheModule.getOrInsertComdat(GV->getName()));
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index 33ec27ff175..30ce47b5d7d 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -721,6 +721,10 @@ public:
/// Set the visibility for the given LLVM GlobalValue.
void setGlobalVisibility(llvm::GlobalValue *GV, const NamedDecl *D) const;
+ void setDSOLocal(llvm::GlobalValue *GV, const NamedDecl *D) const;
+
+ void setGVProperties(llvm::GlobalValue *GV, const NamedDecl *D) const;
+
/// Set the TLS mode for the given LLVM GlobalValue for the thread-local
/// variable declaration D.
void setTLSMode(llvm::GlobalValue *GV, const VarDecl &D) const;
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 3661c0bdb02..bbb323e4f29 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -1531,7 +1531,7 @@ void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
VTable->setComdat(CGM.getModule().getOrInsertComdat(VTable->getName()));
// Set the right visibility.
- CGM.setGlobalVisibility(VTable, RD);
+ CGM.setGVProperties(VTable, RD);
// Use pointer alignment for the vtable. Otherwise we would align them based
// on the size of the initializer which doesn't make sense as only single
@@ -1641,7 +1641,7 @@ llvm::GlobalVariable *ItaniumCXXABI::getAddrOfVTable(const CXXRecordDecl *RD,
VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
Name, VTableType, llvm::GlobalValue::ExternalLinkage);
VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
- CGM.setGlobalVisibility(VTable, RD);
+ CGM.setGVProperties(VTable, RD);
if (RD->hasAttr<DLLImportAttr>())
VTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
@@ -2052,6 +2052,7 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
false, var->getLinkage(),
llvm::ConstantInt::get(guardTy, 0),
guardName.str());
+ guard->setDSOLocal(var->isDSOLocal());
guard->setVisibility(var->getVisibility());
// If the variable is thread-local, so is its guard variable.
guard->setThreadLocalMode(var->getThreadLocalMode());
@@ -3212,7 +3213,10 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty, bool Force,
llvmVisibility = CodeGenModule::GetLLVMVisibility(Ty->getVisibility());
TypeName->setVisibility(llvmVisibility);
+ CGM.setDSOLocal(TypeName, Ty->getAsCXXRecordDecl());
+
GV->setVisibility(llvmVisibility);
+ CGM.setDSOLocal(GV, Ty->getAsCXXRecordDecl());
if (CGM.getTriple().isWindowsItaniumEnvironment()) {
auto RD = Ty->getAsCXXRecordDecl();
OpenPOWER on IntegriCloud