diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2018-02-02 17:17:39 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2018-02-02 17:17:39 +0000 |
commit | 7e34a308ff8d9270d2654ce0e8ed9e1600676afb (patch) | |
tree | 927ab52990faf9c3743ace3cfdd9582c9e150dca /clang/lib/CodeGen | |
parent | e538fc74d4c0d30f8c652c3f4e46375339e9d27b (diff) | |
download | bcm5719-llvm-7e34a308ff8d9270d2654ce0e8ed9e1600676afb.tar.gz bcm5719-llvm-7e34a308ff8d9270d2654ce0e8ed9e1600676afb.zip |
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: 324107
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGDecl.cpp | 3 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGVTT.cpp | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGVTables.cpp | 4 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 67 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 6 | ||||
-rw-r--r-- | clang/lib/CodeGen/ItaniumCXXABI.cpp | 8 |
6 files changed, 79 insertions, 11 deletions
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 04585a8afbb..5de8691bddb 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, ForDefinition); + setGVProperties(GV, &D, ForDefinition); 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 78928d04220..85e5298eebe 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, ForDefinition); + CGM.setGVProperties(VTT, RD, ForDefinition); } llvm::GlobalVariable *CodeGenVTables::GetAddrOfVTT(const CXXRecordDecl *RD) { diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp index 2d9bf3bce92..a3336d90f42 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, ForDefinition); + CGM.setGVProperties(Fn, MD, ForDefinition); } 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, ForDefinition); + CGM.setGVProperties(VTable, RD, ForDefinition); // 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 760327deb17..12af14b77d3 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -717,6 +717,63 @@ void CodeGenModule::setGlobalVisibility(llvm::GlobalValue *GV, GV->setVisibility(GetLLVMVisibility(LV.getVisibility())); } +static bool shouldAssumeDSOLocal(const CodeGenModule &CGM, + llvm::GlobalValue *GV, const NamedDecl *D, + ForDefinition_t IsForDefinition) { + 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 (IsForDefinition) + 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. + if (isa<FunctionDecl>(D) && !CGOpts.NoPLT) + return true; + + // Otherwise don't assue it is local. + return false; +} + +void CodeGenModule::setDSOLocal(llvm::GlobalValue *GV, const NamedDecl *D, + ForDefinition_t IsForDefinition) const { + if (shouldAssumeDSOLocal(*this, GV, D, IsForDefinition)) + GV->setDSOLocal(true); +} + +void CodeGenModule::setGVProperties(llvm::GlobalValue *GV, const NamedDecl *D, + ForDefinition_t IsForDefinition) const { + setGlobalVisibility(GV, D, IsForDefinition); + setDSOLocal(GV, D, IsForDefinition); +} + static llvm::GlobalVariable::ThreadLocalMode GetLLVMTLSModel(StringRef S) { return llvm::StringSwitch<llvm::GlobalVariable::ThreadLocalMode>(S) .Case("global-dynamic", llvm::GlobalVariable::GeneralDynamicTLSModel) @@ -1174,7 +1231,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, ForDefinition); + setGVProperties(GV, ND, ForDefinition); else GV->setVisibility(llvm::GlobalValue::DefaultVisibility); @@ -1316,7 +1373,7 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F, // overridden by a definition. setLinkageForGV(F, FD); - setGlobalVisibility(F, FD, NotForDefinition); + setGVProperties(F, FD, NotForDefinition); if (FD->getAttr<PragmaClangTextSectionAttr>()) { F->addFnAttr("implicit-section-name"); @@ -2638,7 +2695,7 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName, GV->setAlignment(getContext().getDeclAlign(D).getQuantity()); setLinkageForGV(GV, D); - setGlobalVisibility(GV, D, NotForDefinition); + setGVProperties(GV, D, NotForDefinition); if (D->getTLSKind()) { if (D->getTLSKind() == VarDecl::TLS_Dynamic) @@ -3457,7 +3514,7 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD, setFunctionDLLStorageClass(GD, Fn); // FIXME: this is redundant with part of setFunctionDefinitionAttributes - setGlobalVisibility(Fn, D, ForDefinition); + setGVProperties(Fn, D, ForDefinition); MaybeHandleStaticInExternC(D, Fn); @@ -4053,7 +4110,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, ForDefinition); + setGVProperties(GV, VD, ForDefinition); 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 42e9e1be316..3ae041e8d5e 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -722,6 +722,12 @@ public: void setGlobalVisibility(llvm::GlobalValue *GV, const NamedDecl *D, ForDefinition_t IsForDefinition) const; + void setDSOLocal(llvm::GlobalValue *GV, const NamedDecl *D, + ForDefinition_t IsForDefinition) const; + + void setGVProperties(llvm::GlobalValue *GV, const NamedDecl *D, + ForDefinition_t IsForDefinition) 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 8fd0839487d..3ccdf85fa0d 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, ForDefinition); + CGM.setGVProperties(VTable, RD, ForDefinition); // 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, NotForDefinition); + CGM.setGVProperties(VTable, RD, NotForDefinition); 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(), ForDefinition); + GV->setVisibility(llvmVisibility); + CGM.setDSOLocal(GV, Ty->getAsCXXRecordDecl(), ForDefinition); if (CGM.getTriple().isWindowsItaniumEnvironment()) { auto RD = Ty->getAsCXXRecordDecl(); |