diff options
| author | Peter Collingbourne <peter@pcc.me.uk> | 2016-06-14 21:01:22 +0000 |
|---|---|---|
| committer | Peter Collingbourne <peter@pcc.me.uk> | 2016-06-14 21:01:22 +0000 |
| commit | 96efdd6107a06e762e2cd25eb41b053f946ac87a (patch) | |
| tree | 784c39f51cb5c4ec15071c7db559fb0b31e2f484 /llvm/lib | |
| parent | 1dc9fd3c4a260883b1559f7b92ad9156ecc2418c (diff) | |
| download | bcm5719-llvm-96efdd6107a06e762e2cd25eb41b053f946ac87a.tar.gz bcm5719-llvm-96efdd6107a06e762e2cd25eb41b053f946ac87a.zip | |
IR: Introduce local_unnamed_addr attribute.
If a local_unnamed_addr attribute is attached to a global, the address
is known to be insignificant within the module. It is distinct from the
existing unnamed_addr attribute in that it only describes a local property
of the module rather than a global property of the symbol.
This attribute is intended to be used by the code generator and LTO to allow
the linker to decide whether the global needs to be in the symbol table. It is
possible to exclude a global from the symbol table if three things are true:
- This attribute is present on every instance of the global (which means that
the normal rule that the global must have a unique address can be broken without
being observable by the program by performing comparisons against the global's
address)
- The global has linkonce_odr linkage (which means that each linkage unit must have
its own copy of the global if it requires one, and the copy in each linkage unit
must be the same)
- It is a constant or a function (which means that the program cannot observe that
the unique-address rule has been broken by writing to the global)
Although this attribute could in principle be computed from the module
contents, LTO clients (i.e. linkers) will normally need to be able to compute
this property as part of symbol resolution, and it would be inefficient to
materialize every module just to compute it.
See:
http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20160509/356401.html
http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20160516/356738.html
for earlier discussion.
Part of the fix for PR27553.
Differential Revision: http://reviews.llvm.org/D20348
llvm-svn: 272709
Diffstat (limited to 'llvm/lib')
31 files changed, 134 insertions, 91 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 43dcaec1373..a9fed16f8aa 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -2086,7 +2086,7 @@ computePointerICmp(const DataLayout &DL, const TargetLibraryInfo *TLI, return AI->getParent() && AI->getFunction() && AI->isStaticAlloca(); if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) return (GV->hasLocalLinkage() || GV->hasHiddenVisibility() || - GV->hasProtectedVisibility() || GV->hasUnnamedAddr()) && + GV->hasProtectedVisibility() || GV->hasGlobalUnnamedAddr()) && !GV->isThreadLocal(); if (const Argument *A = dyn_cast<Argument>(V)) return A->hasByValAttr(); diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp index 1ba698ebd61..a3d1346e7d2 100644 --- a/llvm/lib/AsmParser/LLLexer.cpp +++ b/llvm/lib/AsmParser/LLLexer.cpp @@ -513,6 +513,7 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(hidden); KEYWORD(protected); KEYWORD(unnamed_addr); + KEYWORD(local_unnamed_addr); KEYWORD(externally_initialized); KEYWORD(extern_weak); KEYWORD(external); diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index cc7b98fa56d..2725386f8da 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -429,6 +429,17 @@ bool LLParser::ParseGlobalType(bool &IsConstant) { return false; } +bool LLParser::ParseOptionalUnnamedAddr( + GlobalVariable::UnnamedAddr &UnnamedAddr) { + if (EatIfPresent(lltok::kw_unnamed_addr)) + UnnamedAddr = GlobalValue::UnnamedAddr::Global; + else if (EatIfPresent(lltok::kw_local_unnamed_addr)) + UnnamedAddr = GlobalValue::UnnamedAddr::Local; + else + UnnamedAddr = GlobalValue::UnnamedAddr::None; + return false; +} + /// ParseUnnamedGlobal: /// OptionalVisibility (ALIAS | IFUNC) ... /// OptionalLinkage OptionalVisibility OptionalDLLStorageClass @@ -455,9 +466,9 @@ bool LLParser::ParseUnnamedGlobal() { bool HasLinkage; unsigned Linkage, Visibility, DLLStorageClass; GlobalVariable::ThreadLocalMode TLM; - bool UnnamedAddr; + GlobalVariable::UnnamedAddr UnnamedAddr; if (ParseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass) || - ParseOptionalThreadLocal(TLM) || parseOptionalUnnamedAddr(UnnamedAddr)) + ParseOptionalThreadLocal(TLM) || ParseOptionalUnnamedAddr(UnnamedAddr)) return true; if (Lex.getKind() != lltok::kw_alias && Lex.getKind() != lltok::kw_ifunc) @@ -481,10 +492,10 @@ bool LLParser::ParseNamedGlobal() { bool HasLinkage; unsigned Linkage, Visibility, DLLStorageClass; GlobalVariable::ThreadLocalMode TLM; - bool UnnamedAddr; + GlobalVariable::UnnamedAddr UnnamedAddr; if (ParseToken(lltok::equal, "expected '=' in global variable") || ParseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass) || - ParseOptionalThreadLocal(TLM) || parseOptionalUnnamedAddr(UnnamedAddr)) + ParseOptionalThreadLocal(TLM) || ParseOptionalUnnamedAddr(UnnamedAddr)) return true; if (Lex.getKind() != lltok::kw_alias && Lex.getKind() != lltok::kw_ifunc) @@ -659,11 +670,10 @@ static bool isValidVisibilityForLinkage(unsigned V, unsigned L) { /// /// Everything through OptionalUnnamedAddr has already been parsed. /// -bool LLParser::parseIndirectSymbol(const std::string &Name, LocTy NameLoc, - unsigned L, unsigned Visibility, - unsigned DLLStorageClass, - GlobalVariable::ThreadLocalMode TLM, - bool UnnamedAddr) { +bool LLParser::parseIndirectSymbol( + const std::string &Name, LocTy NameLoc, unsigned L, unsigned Visibility, + unsigned DLLStorageClass, GlobalVariable::ThreadLocalMode TLM, + GlobalVariable::UnnamedAddr UnnamedAddr) { bool IsAlias; if (Lex.getKind() == lltok::kw_alias) IsAlias = true; @@ -799,7 +809,7 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, unsigned Linkage, bool HasLinkage, unsigned Visibility, unsigned DLLStorageClass, GlobalVariable::ThreadLocalMode TLM, - bool UnnamedAddr) { + GlobalVariable::UnnamedAddr UnnamedAddr) { if (!isValidVisibilityForLinkage(Visibility, Linkage)) return Error(NameLoc, "symbol with local linkage must have default visibility"); @@ -4580,7 +4590,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { std::string Section; unsigned Alignment; std::string GC; - bool UnnamedAddr; + GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::UnnamedAddr::None; LocTy UnnamedAddrLoc; Constant *Prefix = nullptr; Constant *Prologue = nullptr; @@ -4588,8 +4598,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { Comdat *C; if (ParseArgumentList(ArgList, isVarArg) || - ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr, - &UnnamedAddrLoc) || + ParseOptionalUnnamedAddr(UnnamedAddr) || ParseFnAttributeValuePairs(FuncAttrs, FwdRefAttrGrps, false, BuiltinLoc) || (EatIfPresent(lltok::kw_section) && diff --git a/llvm/lib/AsmParser/LLParser.h b/llvm/lib/AsmParser/LLParser.h index 7c32f2c7fac..479ff96bc8a 100644 --- a/llvm/lib/AsmParser/LLParser.h +++ b/llvm/lib/AsmParser/LLParser.h @@ -226,9 +226,7 @@ namespace llvm { bool ParseTLSModel(GlobalVariable::ThreadLocalMode &TLM); bool ParseOptionalThreadLocal(GlobalVariable::ThreadLocalMode &TLM); - bool parseOptionalUnnamedAddr(bool &UnnamedAddr) { - return ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr); - } + bool ParseOptionalUnnamedAddr(GlobalVariable::UnnamedAddr &UnnamedAddr); bool ParseOptionalAddrSpace(unsigned &AddrSpace); bool ParseOptionalParamAttrs(AttrBuilder &B); bool ParseOptionalReturnAttrs(AttrBuilder &B); @@ -275,12 +273,13 @@ namespace llvm { bool ParseGlobal(const std::string &Name, LocTy Loc, unsigned Linkage, bool HasLinkage, unsigned Visibility, unsigned DLLStorageClass, - GlobalVariable::ThreadLocalMode TLM, bool UnnamedAddr); + GlobalVariable::ThreadLocalMode TLM, + GlobalVariable::UnnamedAddr UnnamedAddr); bool parseIndirectSymbol(const std::string &Name, LocTy Loc, unsigned Linkage, unsigned Visibility, unsigned DLLStorageClass, GlobalVariable::ThreadLocalMode TLM, - bool UnnamedAddr); + GlobalVariable::UnnamedAddr UnnamedAddr); bool parseComdat(); bool ParseStandaloneMetadata(); bool ParseNamedMetadata(); diff --git a/llvm/lib/AsmParser/LLToken.h b/llvm/lib/AsmParser/LLToken.h index 85881d6f11b..be3697aefdd 100644 --- a/llvm/lib/AsmParser/LLToken.h +++ b/llvm/lib/AsmParser/LLToken.h @@ -60,6 +60,7 @@ enum Kind { kw_hidden, kw_protected, kw_unnamed_addr, + kw_local_unnamed_addr, kw_externally_initialized, kw_extern_weak, kw_external, diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 3bba0250af5..ac72f69c76e 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -773,6 +773,15 @@ static GlobalVariable::ThreadLocalMode getDecodedThreadLocalMode(unsigned Val) { } } +static GlobalVariable::UnnamedAddr getDecodedUnnamedAddrType(unsigned Val) { + switch (Val) { + default: // Map unknown to UnnamedAddr::None. + case 0: return GlobalVariable::UnnamedAddr::None; + case 1: return GlobalVariable::UnnamedAddr::Global; + case 2: return GlobalVariable::UnnamedAddr::Local; + } +} + static int getDecodedCastOpcode(unsigned Val) { switch (Val) { default: return -1; @@ -3791,9 +3800,9 @@ std::error_code BitcodeReader::parseModule(uint64_t ResumeBit, if (Record.size() > 7) TLM = getDecodedThreadLocalMode(Record[7]); - bool UnnamedAddr = false; + GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::UnnamedAddr::None; if (Record.size() > 8) - UnnamedAddr = Record[8]; + UnnamedAddr = getDecodedUnnamedAddrType(Record[8]); bool ExternallyInitialized = false; if (Record.size() > 9) @@ -3828,6 +3837,7 @@ std::error_code BitcodeReader::parseModule(uint64_t ResumeBit, } else if (hasImplicitComdat(RawLinkage)) { NewGV->setComdat(reinterpret_cast<Comdat *>(1)); } + break; } case bitc::MODULE_CODE_GLOBALVAR_ATTACHMENT: { @@ -3885,9 +3895,9 @@ std::error_code BitcodeReader::parseModule(uint64_t ResumeBit, return error("Invalid ID"); Func->setGC(GCTable[Record[8] - 1]); } - bool UnnamedAddr = false; + GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::UnnamedAddr::None; if (Record.size() > 9) - UnnamedAddr = Record[9]; + UnnamedAddr = getDecodedUnnamedAddrType(Record[9]); Func->setUnnamedAddr(UnnamedAddr); if (Record.size() > 10 && Record[10] != 0) FunctionPrologues.push_back(std::make_pair(Func, Record[10]-1)); @@ -3974,7 +3984,7 @@ std::error_code BitcodeReader::parseModule(uint64_t ResumeBit, if (OpNum != Record.size()) NewGA->setThreadLocalMode(getDecodedThreadLocalMode(Record[OpNum++])); if (OpNum != Record.size()) - NewGA->setUnnamedAddr(Record[OpNum++]); + NewGA->setUnnamedAddr(getDecodedUnnamedAddrType(Record[OpNum++])); ValueList.push_back(NewGA); IndirectSymbolInits.push_back(std::make_pair(NewGA, Val)); break; diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 06a4ef1892d..4699e7dac77 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -996,6 +996,15 @@ static unsigned getEncodedComdatSelectionKind(const Comdat &C) { llvm_unreachable("Invalid selection kind"); } +static unsigned getEncodedUnnamedAddr(const GlobalValue &GV) { + switch (GV.getUnnamedAddr()) { + case GlobalValue::UnnamedAddr::None: return 0; + case GlobalValue::UnnamedAddr::Local: return 2; + case GlobalValue::UnnamedAddr::Global: return 1; + } + llvm_unreachable("Invalid unnamed_addr"); +} + void ModuleBitcodeWriter::writeComdats() { SmallVector<unsigned, 64> Vals; for (const Comdat *C : VE.getComdats()) { @@ -1157,12 +1166,13 @@ void ModuleBitcodeWriter::writeModuleInfo() { Vals.push_back(GV.hasSection() ? SectionMap[GV.getSection()] : 0); if (GV.isThreadLocal() || GV.getVisibility() != GlobalValue::DefaultVisibility || - GV.hasUnnamedAddr() || GV.isExternallyInitialized() || + GV.getUnnamedAddr() != GlobalValue::UnnamedAddr::None || + GV.isExternallyInitialized() || GV.getDLLStorageClass() != GlobalValue::DefaultStorageClass || GV.hasComdat()) { Vals.push_back(getEncodedVisibility(GV)); Vals.push_back(getEncodedThreadLocalMode(GV)); - Vals.push_back(GV.hasUnnamedAddr()); + Vals.push_back(getEncodedUnnamedAddr(GV)); Vals.push_back(GV.isExternallyInitialized()); Vals.push_back(getEncodedDLLStorageClass(GV)); Vals.push_back(GV.hasComdat() ? VE.getComdatID(GV.getComdat()) : 0); @@ -1188,7 +1198,7 @@ void ModuleBitcodeWriter::writeModuleInfo() { Vals.push_back(F.hasSection() ? SectionMap[F.getSection()] : 0); Vals.push_back(getEncodedVisibility(F)); Vals.push_back(F.hasGC() ? GCMap[F.getGC()] : 0); - Vals.push_back(F.hasUnnamedAddr()); + Vals.push_back(getEncodedUnnamedAddr(F)); Vals.push_back(F.hasPrologueData() ? (VE.getValueID(F.getPrologueData()) + 1) : 0); Vals.push_back(getEncodedDLLStorageClass(F)); @@ -1205,7 +1215,8 @@ void ModuleBitcodeWriter::writeModuleInfo() { // Emit the alias information. for (const GlobalAlias &A : M.aliases()) { - // ALIAS: [alias type, aliasee val#, linkage, visibility] + // ALIAS: [alias type, aliasee val#, linkage, visibility, dllstorageclass, + // threadlocal, unnamed_addr] Vals.push_back(VE.getTypeID(A.getValueType())); Vals.push_back(A.getType()->getAddressSpace()); Vals.push_back(VE.getValueID(A.getAliasee())); @@ -1213,7 +1224,7 @@ void ModuleBitcodeWriter::writeModuleInfo() { Vals.push_back(getEncodedVisibility(A)); Vals.push_back(getEncodedDLLStorageClass(A)); Vals.push_back(getEncodedThreadLocalMode(A)); - Vals.push_back(A.hasUnnamedAddr()); + Vals.push_back(getEncodedUnnamedAddr(A)); unsigned AbbrevToUse = 0; Stream.EmitRecord(bitc::MODULE_CODE_ALIAS, Vals, AbbrevToUse); Vals.clear(); diff --git a/llvm/lib/CodeGen/Analysis.cpp b/llvm/lib/CodeGen/Analysis.cpp index ef405484e84..73bd3d29eae 100644 --- a/llvm/lib/CodeGen/Analysis.cpp +++ b/llvm/lib/CodeGen/Analysis.cpp @@ -623,7 +623,9 @@ bool llvm::canBeOmittedFromSymbolTable(const GlobalValue *GV) { if (!GV->hasLinkOnceODRLinkage()) return false; - if (GV->hasUnnamedAddr()) + // We assume that anyone who sets global unnamed_addr on a non-constant knows + // what they're doing. + if (GV->hasGlobalUnnamedAddr()) return true; // If it is a non constant variable, it needs to be uniqued across shared @@ -633,21 +635,7 @@ bool llvm::canBeOmittedFromSymbolTable(const GlobalValue *GV) { return false; } - // An alias can point to a variable. We could try to resolve the alias to - // decide, but for now just don't hide them. - if (isa<GlobalAlias>(GV)) - return false; - - // If we don't see every use, we have to be conservative and assume the value - // address is significant. - if (GV->getParent()->getMaterializer()) - return false; - - GlobalStatus GS; - if (GlobalStatus::analyzeGlobal(GV, GS)) - return false; - - return !GS.IsCompared; + return GV->hasAtLeastLocalUnnamedAddr(); } // FIXME: make this a proper option diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index d39881d9ce3..02640f55fa2 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1001,7 +1001,7 @@ static bool isGOTEquivalentCandidate(const GlobalVariable *GV, // Global GOT equivalents are unnamed private globals with a constant // pointer initializer to another global symbol. They must point to a // GlobalVariable or Function, i.e., as GlobalValue. - if (!GV->hasUnnamedAddr() || !GV->hasInitializer() || !GV->isConstant() || + if (!GV->hasGlobalUnnamedAddr() || !GV->hasInitializer() || !GV->isConstant() || !GV->isDiscardableIfUnused() || !dyn_cast<GlobalValue>(GV->getOperand(0))) return false; diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index f7ba62ff231..6d5dd5fa4d5 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -429,7 +429,7 @@ const MCExpr *TargetLoweringObjectFileELF::lowerRelativeReference( const TargetMachine &TM) const { // We may only use a PLT-relative relocation to refer to unnamed_addr // functions. - if (!LHS->hasUnnamedAddr() || !LHS->getValueType()->isFunctionTy()) + if (!LHS->hasGlobalUnnamedAddr() || !LHS->getValueType()->isFunctionTy()) return nullptr; // Basic sanity checks. diff --git a/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp b/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp index c7b97865ab7..6f7c29feef0 100644 --- a/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp +++ b/llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp @@ -144,7 +144,7 @@ static void raiseVisibilityOnValue(GlobalValue &V, GlobalRenamer &R) { V.setLinkage(GlobalValue::ExternalLinkage); V.setVisibility(GlobalValue::HiddenVisibility); } - V.setUnnamedAddr(false); + V.setUnnamedAddr(GlobalValue::UnnamedAddr::None); assert(!R.needsRenaming(V) && "Invalid global name."); } diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 24b92b8eb3c..0d488c27aa8 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -2426,6 +2426,17 @@ static void PrintThreadLocalModel(GlobalVariable::ThreadLocalMode TLM, } } +static StringRef getUnnamedAddrEncoding(GlobalVariable::UnnamedAddr UA) { + switch (UA) { + case GlobalVariable::UnnamedAddr::None: + return ""; + case GlobalVariable::UnnamedAddr::Local: + return "local_unnamed_addr"; + case GlobalVariable::UnnamedAddr::Global: + return "unnamed_addr"; + } +} + static void maybePrintComdat(formatted_raw_ostream &Out, const GlobalObject &GO) { const Comdat *C = GO.getComdat(); @@ -2458,8 +2469,9 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) { PrintVisibility(GV->getVisibility(), Out); PrintDLLStorageClass(GV->getDLLStorageClass(), Out); PrintThreadLocalModel(GV->getThreadLocalMode(), Out); - if (GV->hasUnnamedAddr()) - Out << "unnamed_addr "; + StringRef UA = getUnnamedAddrEncoding(GV->getUnnamedAddr()); + if (!UA.empty()) + Out << UA << ' '; if (unsigned AddressSpace = GV->getType()->getAddressSpace()) Out << "addrspace(" << AddressSpace << ") "; @@ -2499,8 +2511,9 @@ void AssemblyWriter::printIndirectSymbol(const GlobalIndirectSymbol *GIS) { PrintVisibility(GIS->getVisibility(), Out); PrintDLLStorageClass(GIS->getDLLStorageClass(), Out); PrintThreadLocalModel(GIS->getThreadLocalMode(), Out); - if (GIS->hasUnnamedAddr()) - Out << "unnamed_addr "; + StringRef UA = getUnnamedAddrEncoding(GIS->getUnnamedAddr()); + if (!UA.empty()) + Out << UA << ' '; if (isa<GlobalAlias>(GIS)) Out << "alias "; @@ -2656,8 +2669,9 @@ void AssemblyWriter::printFunction(const Function *F) { Out << "..."; // Output varargs portion of signature! } Out << ')'; - if (F->hasUnnamedAddr()) - Out << " unnamed_addr"; + StringRef UA = getUnnamedAddrEncoding(F->getUnnamedAddr()); + if (!UA.empty()) + Out << ' ' << UA; if (Attrs.hasAttributes(AttributeSet::FunctionIndex)) Out << " #" << Machine.getAttributeGroupSlot(Attrs.getFnAttributes()); if (F->hasSection()) { diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp index 380fca8c10f..b044781302c 100644 --- a/llvm/lib/IR/Core.cpp +++ b/llvm/lib/IR/Core.cpp @@ -1560,11 +1560,13 @@ void LLVMSetDLLStorageClass(LLVMValueRef Global, LLVMDLLStorageClass Class) { } LLVMBool LLVMHasUnnamedAddr(LLVMValueRef Global) { - return unwrap<GlobalValue>(Global)->hasUnnamedAddr(); + return unwrap<GlobalValue>(Global)->hasGlobalUnnamedAddr(); } void LLVMSetUnnamedAddr(LLVMValueRef Global, LLVMBool HasUnnamedAddr) { - unwrap<GlobalValue>(Global)->setUnnamedAddr(HasUnnamedAddr); + unwrap<GlobalValue>(Global)->setUnnamedAddr( + HasUnnamedAddr ? GlobalValue::UnnamedAddr::Global + : GlobalValue::UnnamedAddr::None); } /*--.. Operations on global variables, load and store instructions .........--*/ diff --git a/llvm/lib/IR/Globals.cpp b/llvm/lib/IR/Globals.cpp index d151b9c5dc2..c5e1b9b9fa0 100644 --- a/llvm/lib/IR/Globals.cpp +++ b/llvm/lib/IR/Globals.cpp @@ -51,7 +51,7 @@ Value *GlobalValue::handleOperandChangeImpl(Value *From, Value *To) { /// create a GlobalValue) from the GlobalValue Src to this one. void GlobalValue::copyAttributesFrom(const GlobalValue *Src) { setVisibility(Src->getVisibility()); - setUnnamedAddr(Src->hasUnnamedAddr()); + setUnnamedAddr(Src->getUnnamedAddr()); setDLLStorageClass(Src->getDLLStorageClass()); } diff --git a/llvm/lib/IR/IRBuilder.cpp b/llvm/lib/IR/IRBuilder.cpp index bc75de2693b..480e5e5d426 100644 --- a/llvm/lib/IR/IRBuilder.cpp +++ b/llvm/lib/IR/IRBuilder.cpp @@ -34,7 +34,7 @@ GlobalVariable *IRBuilderBase::CreateGlobalString(StringRef Str, StrConstant, Name, nullptr, GlobalVariable::NotThreadLocal, AddressSpace); - GV->setUnnamedAddr(true); + GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); return GV; } diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index 79c9f4d3a13..0395f5b36fe 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -1535,7 +1535,7 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs, if (Attrs.hasAttribute(AttributeSet::FunctionIndex, Attribute::JumpTable)) { const GlobalValue *GV = cast<GlobalValue>(V); - Assert(GV->hasUnnamedAddr(), + Assert(GV->hasGlobalUnnamedAddr(), "Attribute 'jumptable' requires 'unnamed_addr'", V); } diff --git a/llvm/lib/Linker/IRMover.cpp b/llvm/lib/Linker/IRMover.cpp index d2c6d78abe2..14b0a43030d 100644 --- a/llvm/lib/Linker/IRMover.cpp +++ b/llvm/lib/Linker/IRMover.cpp @@ -791,7 +791,7 @@ IRLinker::linkAppendingVarProto(GlobalVariable *DstGV, return stringErr( "Appending variables with different visibility need to be linked!"); - if (DstGV->hasUnnamedAddr() != SrcGV->hasUnnamedAddr()) + if (DstGV->hasGlobalUnnamedAddr() != SrcGV->hasGlobalUnnamedAddr()) return stringErr( "Appending variables with different unnamed_addr need to be linked!"); diff --git a/llvm/lib/Linker/LinkModules.cpp b/llvm/lib/Linker/LinkModules.cpp index ff36f90b53f..fae9c95ebe8 100644 --- a/llvm/lib/Linker/LinkModules.cpp +++ b/llvm/lib/Linker/LinkModules.cpp @@ -377,9 +377,10 @@ bool ModuleLinker::linkIfNeeded(GlobalValue &GV) { DGV->setVisibility(Visibility); GV.setVisibility(Visibility); - bool HasUnnamedAddr = GV.hasUnnamedAddr() && DGV->hasUnnamedAddr(); - DGV->setUnnamedAddr(HasUnnamedAddr); - GV.setUnnamedAddr(HasUnnamedAddr); + GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::getMinUnnamedAddr( + DGV->getUnnamedAddr(), GV.getUnnamedAddr()); + DGV->setUnnamedAddr(UnnamedAddr); + GV.setUnnamedAddr(UnnamedAddr); } // Don't want to append to global_ctors list, for example, when we diff --git a/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp b/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp index 5222bed0d25..17b45fa65f1 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp @@ -694,7 +694,7 @@ void AMDGPUPromoteAlloca::handleAlloca(AllocaInst &I) { nullptr, GlobalVariable::NotThreadLocal, AMDGPUAS::LOCAL_ADDRESS); - GV->setUnnamedAddr(true); + GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); GV->setAlignment(I.getAlignment()); Value *TCntY, *TCntZ; diff --git a/llvm/lib/Target/TargetLoweringObjectFile.cpp b/llvm/lib/Target/TargetLoweringObjectFile.cpp index b2b69025851..fd4936e1904 100644 --- a/llvm/lib/Target/TargetLoweringObjectFile.cpp +++ b/llvm/lib/Target/TargetLoweringObjectFile.cpp @@ -174,7 +174,7 @@ SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalValue *GV, // If the global is required to have a unique address, it can't be put // into a mergable section: just drop it into the general read-only // section instead. - if (!GVar->hasUnnamedAddr()) + if (!GVar->hasGlobalUnnamedAddr()) return SectionKind::getReadOnly(); // If initializer is a null-terminated string, put it in a "cstring" diff --git a/llvm/lib/Transforms/IPO/ConstantMerge.cpp b/llvm/lib/Transforms/IPO/ConstantMerge.cpp index 11f40e86460..65b042534f3 100644 --- a/llvm/lib/Transforms/IPO/ConstantMerge.cpp +++ b/llvm/lib/Transforms/IPO/ConstantMerge.cpp @@ -57,7 +57,7 @@ static bool IsBetterCanonical(const GlobalVariable &A, if (A.hasLocalLinkage() && !B.hasLocalLinkage()) return false; - return A.hasUnnamedAddr(); + return A.hasGlobalUnnamedAddr(); } static unsigned getAlignment(GlobalVariable *GV) { @@ -152,11 +152,11 @@ static bool mergeConstants(Module &M) { if (!Slot || Slot == GV) continue; - if (!Slot->hasUnnamedAddr() && !GV->hasUnnamedAddr()) + if (!Slot->hasGlobalUnnamedAddr() && !GV->hasGlobalUnnamedAddr()) continue; - if (!GV->hasUnnamedAddr()) - Slot->setUnnamedAddr(false); + if (!GV->hasGlobalUnnamedAddr()) + Slot->setUnnamedAddr(GlobalValue::UnnamedAddr::None); // Make all uses of the duplicate constant use the canonical version. Replacements.push_back(std::make_pair(GV, Slot)); diff --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp index e66ed8359ff..ded55dbb443 100644 --- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp +++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp @@ -1942,8 +1942,7 @@ static bool processInternalGlobal( static bool processGlobal(GlobalValue &GV, TargetLibraryInfo *TLI, function_ref<DominatorTree &(Function &)> LookupDomTree) { - // Do more involved optimizations if the global is internal. - if (!GV.hasLocalLinkage()) + if (GV.getName().startswith("llvm.")) return false; GlobalStatus GS; @@ -1952,12 +1951,20 @@ processGlobal(GlobalValue &GV, TargetLibraryInfo *TLI, return false; bool Changed = false; - if (!GS.IsCompared && !GV.hasUnnamedAddr()) { - GV.setUnnamedAddr(true); - NumUnnamed++; - Changed = true; + if (!GS.IsCompared && !GV.hasGlobalUnnamedAddr()) { + auto NewUnnamedAddr = GV.hasLocalLinkage() ? GlobalValue::UnnamedAddr::Global + : GlobalValue::UnnamedAddr::Local; + if (NewUnnamedAddr != GV.getUnnamedAddr()) { + GV.setUnnamedAddr(NewUnnamedAddr); + NumUnnamed++; + Changed = true; + } } + // Do more involved optimizations if the global is internal. + if (!GV.hasLocalLinkage()) + return Changed; + auto *GVar = dyn_cast<GlobalVariable>(&GV); if (!GVar) return Changed; diff --git a/llvm/lib/Transforms/IPO/MergeFunctions.cpp b/llvm/lib/Transforms/IPO/MergeFunctions.cpp index 27caa07c165..adf0d3f680b 100644 --- a/llvm/lib/Transforms/IPO/MergeFunctions.cpp +++ b/llvm/lib/Transforms/IPO/MergeFunctions.cpp @@ -1637,7 +1637,7 @@ void MergeFunctions::replaceDirectCallers(Function *Old, Function *New) { // Replace G with an alias to F if possible, or else a thunk to F. Deletes G. void MergeFunctions::writeThunkOrAlias(Function *F, Function *G) { - if (HasGlobalAliases && G->hasUnnamedAddr()) { + if (HasGlobalAliases && G->hasGlobalUnnamedAddr()) { if (G->hasExternalLinkage() || G->hasLocalLinkage() || G->hasWeakLinkage()) { writeAlias(F, G); diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp index 08f148139a2..16a55527c20 100644 --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -832,7 +832,7 @@ static GlobalVariable *createPrivateGlobalForString(Module &M, StringRef Str, GlobalVariable *GV = new GlobalVariable(M, StrConst->getType(), true, GlobalValue::PrivateLinkage, StrConst, kAsanGenPrefix); - if (AllowMerging) GV->setUnnamedAddr(true); + if (AllowMerging) GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); GV->setAlignment(1); // Strings may not be merged w/o setting align 1. return GV; } @@ -849,7 +849,7 @@ static GlobalVariable *createPrivateGlobalForSourceLoc(Module &M, auto GV = new GlobalVariable(M, LocStruct->getType(), true, GlobalValue::PrivateLinkage, LocStruct, kAsanGenPrefix); - GV->setUnnamedAddr(true); + GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); return GV; } diff --git a/llvm/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp index 40a9fce7b0b..eafab784e57 100644 --- a/llvm/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/EfficiencySanitizer.cpp @@ -137,7 +137,7 @@ static GlobalVariable *createPrivateGlobalForString(Module &M, StringRef Str, new GlobalVariable(M, StrConst->getType(), true, GlobalValue::PrivateLinkage, StrConst, ""); if (AllowMerging) - GV->setUnnamedAddr(true); + GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); GV->setAlignment(1); // Strings may not be merged w/o setting align 1. return GV; } diff --git a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp index 9b19833cb75..6b2df2a1d9d 100644 --- a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp +++ b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp @@ -691,7 +691,7 @@ bool GCOVProfiler::emitProfileArcs() { FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); Function *F = Function::Create(FTy, GlobalValue::InternalLinkage, "__llvm_gcov_init", M); - F->setUnnamedAddr(true); + F->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); F->setLinkage(GlobalValue::InternalLinkage); F->addFnAttr(Attribute::NoInline); if (Options.NoRedZone) @@ -766,7 +766,7 @@ GlobalVariable *GCOVProfiler::buildEdgeLookupTable( ConstantArray::get(EdgeTableTy, makeArrayRef(&EdgeTable[0],TableSize)), "__llvm_gcda_edge_table"); - EdgeTableGV->setUnnamedAddr(true); + EdgeTableGV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); return EdgeTableGV; } @@ -840,7 +840,7 @@ GlobalVariable *GCOVProfiler::getEdgeStateValue() { ConstantInt::get(Type::getInt32Ty(*Ctx), 0xffffffff), "__llvm_gcov_global_state_pred"); - GV->setUnnamedAddr(true); + GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); } return GV; } @@ -852,7 +852,7 @@ Function *GCOVProfiler::insertCounterWriteout( if (!WriteoutF) WriteoutF = Function::Create(WriteoutFTy, GlobalValue::InternalLinkage, "__llvm_gcov_writeout", M); - WriteoutF->setUnnamedAddr(true); + WriteoutF->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); WriteoutF->addFnAttr(Attribute::NoInline); if (Options.NoRedZone) WriteoutF->addFnAttr(Attribute::NoRedZone); @@ -912,7 +912,7 @@ Function *GCOVProfiler::insertCounterWriteout( void GCOVProfiler::insertIndirectCounterIncrement() { Function *Fn = cast<Function>(GCOVProfiler::getIncrementIndirectCounterFunc()); - Fn->setUnnamedAddr(true); + Fn->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); Fn->setLinkage(GlobalValue::InternalLinkage); Fn->addFnAttr(Attribute::NoInline); if (Options.NoRedZone) @@ -969,7 +969,7 @@ insertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> > CountersBySP) { "__llvm_gcov_flush", M); else FlushF->setLinkage(GlobalValue::InternalLinkage); - FlushF->setUnnamedAddr(true); + FlushF->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); FlushF->addFnAttr(Attribute::NoInline); if (Options.NoRedZone) FlushF->addFnAttr(Attribute::NoRedZone); diff --git a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp index 7bb3bdc1137..a3fc16c9a9f 100644 --- a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp +++ b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp @@ -506,7 +506,7 @@ void InstrProfiling::emitRegistration() { auto *RegisterFTy = FunctionType::get(VoidTy, false); auto *RegisterF = Function::Create(RegisterFTy, GlobalValue::InternalLinkage, getInstrProfRegFuncsName(), M); - RegisterF->setUnnamedAddr(true); + RegisterF->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); if (Options.NoRedZone) RegisterF->addFnAttr(Attribute::NoRedZone); auto *RuntimeRegisterTy = FunctionType::get(VoidTy, VoidPtrTy, false); @@ -606,7 +606,7 @@ void InstrProfiling::emitInitialization() { auto *F = Function::Create(FunctionType::get(VoidTy, false), GlobalValue::InternalLinkage, getInstrProfInitFuncName(), M); - F->setUnnamedAddr(true); + F->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); F->addFnAttr(Attribute::NoInline); if (Options.NoRedZone) F->addFnAttr(Attribute::NoRedZone); diff --git a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp index d99d4b6e596..f923673484f 100644 --- a/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp +++ b/llvm/lib/Transforms/Scalar/LoopIdiomRecognize.cpp @@ -777,7 +777,7 @@ bool LoopIdiomRecognize::processLoopStridedStore( GlobalVariable *GV = new GlobalVariable(*M, PatternValue->getType(), true, GlobalValue::PrivateLinkage, PatternValue, ".memset_pattern"); - GV->setUnnamedAddr(true); // Ok to merge these. + GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); // Ok to merge these. GV->setAlignment(16); Value *PatternPtr = ConstantExpr::getBitCast(GV, Int8PtrTy); NewCall = Builder.CreateCall(MSP, {BasePtr, PatternPtr, NumBytes}); diff --git a/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp b/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp index 92e7fbc7e69..fcb25baf321 100644 --- a/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp +++ b/llvm/lib/Transforms/Utils/FunctionImportUtils.cpp @@ -64,7 +64,7 @@ bool FunctionImportGlobalProcessing::doPromoteLocalToGlobal( // of the module and recorded in the summary index for use when importing // from that module. auto *GVar = dyn_cast<GlobalVariable>(SGV); - if (GVar && GVar->isConstant() && GVar->hasUnnamedAddr()) + if (GVar && GVar->isConstant() && GVar->hasGlobalUnnamedAddr()) return false; if (GVar && GVar->hasSection()) diff --git a/llvm/lib/Transforms/Utils/GlobalStatus.cpp b/llvm/lib/Transforms/Utils/GlobalStatus.cpp index 8be42aed972..266be41fbea 100644 --- a/llvm/lib/Transforms/Utils/GlobalStatus.cpp +++ b/llvm/lib/Transforms/Utils/GlobalStatus.cpp @@ -105,7 +105,7 @@ static bool analyzeGlobalAux(const Value *V, GlobalStatus &GS, } } - if (StoredVal == GV->getInitializer()) { + if (GV->hasInitializer() && StoredVal == GV->getInitializer()) { if (GS.StoredType < GlobalStatus::InitializerStored) GS.StoredType = GlobalStatus::InitializerStored; } else if (isa<LoadInst>(StoredVal) && diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index ec2c1af97ea..8f35f887c0b 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -4540,7 +4540,7 @@ SwitchLookupTable::SwitchLookupTable( Array = new GlobalVariable(M, ArrayTy, /*constant=*/true, GlobalVariable::PrivateLinkage, Initializer, "switch.table"); - Array->setUnnamedAddr(true); + Array->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); Kind = ArrayKind; } |

