mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 03:33:20 +01:00
[IFUNC] Use GlobalIndirectSymbol when aliases and ifuncs have something similar
Second part extracted from http://reviews.llvm.org/D15525 Use GlobalIndirectSymbol in all cases when aliases and ifuncs have something in common. Differential Revision: http://reviews.llvm.org/D18754 llvm-svn: 265382
This commit is contained in:
parent
159be8f3fc
commit
4f1426bbd4
@ -34,6 +34,7 @@ class ConstantArray;
|
|||||||
class DIE;
|
class DIE;
|
||||||
class DIEAbbrev;
|
class DIEAbbrev;
|
||||||
class GCMetadataPrinter;
|
class GCMetadataPrinter;
|
||||||
|
class GlobalIndirectSymbol;
|
||||||
class GlobalValue;
|
class GlobalValue;
|
||||||
class GlobalVariable;
|
class GlobalVariable;
|
||||||
class MachineBasicBlock;
|
class MachineBasicBlock;
|
||||||
@ -546,6 +547,9 @@ private:
|
|||||||
void EmitXXStructorList(const DataLayout &DL, const Constant *List,
|
void EmitXXStructorList(const DataLayout &DL, const Constant *List,
|
||||||
bool isCtor);
|
bool isCtor);
|
||||||
GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy &C);
|
GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy &C);
|
||||||
|
/// Emit GlobalAlias or GlobalIFunc.
|
||||||
|
void emitGlobalIndirectSymbol(Module &M,
|
||||||
|
const GlobalIndirectSymbol& GIS);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -503,8 +503,9 @@ bool LLParser::ParseUnnamedGlobal() {
|
|||||||
if (Lex.getKind() != lltok::kw_alias)
|
if (Lex.getKind() != lltok::kw_alias)
|
||||||
return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility,
|
return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility,
|
||||||
DLLStorageClass, TLM, UnnamedAddr);
|
DLLStorageClass, TLM, UnnamedAddr);
|
||||||
return ParseAlias(Name, NameLoc, Linkage, Visibility, DLLStorageClass, TLM,
|
|
||||||
UnnamedAddr);
|
return parseIndirectSymbol(Name, NameLoc, Linkage, Visibility,
|
||||||
|
DLLStorageClass, TLM, UnnamedAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseNamedGlobal:
|
/// ParseNamedGlobal:
|
||||||
@ -533,8 +534,8 @@ bool LLParser::ParseNamedGlobal() {
|
|||||||
return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility,
|
return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility,
|
||||||
DLLStorageClass, TLM, UnnamedAddr);
|
DLLStorageClass, TLM, UnnamedAddr);
|
||||||
|
|
||||||
return ParseAlias(Name, NameLoc, Linkage, Visibility, DLLStorageClass, TLM,
|
return parseIndirectSymbol(Name, NameLoc, Linkage, Visibility,
|
||||||
UnnamedAddr);
|
DLLStorageClass, TLM, UnnamedAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LLParser::parseComdat() {
|
bool LLParser::parseComdat() {
|
||||||
@ -690,26 +691,31 @@ static bool isValidVisibilityForLinkage(unsigned V, unsigned L) {
|
|||||||
(GlobalValue::VisibilityTypes)V == GlobalValue::DefaultVisibility;
|
(GlobalValue::VisibilityTypes)V == GlobalValue::DefaultVisibility;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseAlias:
|
/// parseIndirectSymbol:
|
||||||
/// ::= GlobalVar '=' OptionalLinkage OptionalVisibility
|
/// ::= GlobalVar '=' OptionalLinkage OptionalVisibility
|
||||||
/// OptionalDLLStorageClass OptionalThreadLocal
|
/// OptionalDLLStorageClass OptionalThreadLocal
|
||||||
/// OptionalUnnamedAddr 'alias' Aliasee
|
/// OptionalUnnamedAddr 'alias' IndirectSymbol
|
||||||
///
|
///
|
||||||
/// Aliasee
|
/// IndirectSymbol
|
||||||
/// ::= TypeAndValue
|
/// ::= TypeAndValue
|
||||||
///
|
///
|
||||||
/// Everything through OptionalUnnamedAddr has already been parsed.
|
/// Everything through OptionalUnnamedAddr has already been parsed.
|
||||||
///
|
///
|
||||||
bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, unsigned L,
|
bool LLParser::parseIndirectSymbol(const std::string &Name, LocTy NameLoc,
|
||||||
unsigned Visibility, unsigned DLLStorageClass,
|
unsigned L, unsigned Visibility,
|
||||||
GlobalVariable::ThreadLocalMode TLM,
|
unsigned DLLStorageClass,
|
||||||
bool UnnamedAddr) {
|
GlobalVariable::ThreadLocalMode TLM,
|
||||||
assert(Lex.getKind() == lltok::kw_alias);
|
bool UnnamedAddr) {
|
||||||
|
bool IsAlias;
|
||||||
|
if (Lex.getKind() == lltok::kw_alias)
|
||||||
|
IsAlias = true;
|
||||||
|
else
|
||||||
|
llvm_unreachable("Not an alias!");
|
||||||
Lex.Lex();
|
Lex.Lex();
|
||||||
|
|
||||||
GlobalValue::LinkageTypes Linkage = (GlobalValue::LinkageTypes) L;
|
GlobalValue::LinkageTypes Linkage = (GlobalValue::LinkageTypes) L;
|
||||||
|
|
||||||
if(!GlobalAlias::isValidLinkage(Linkage))
|
if(IsAlias && !GlobalAlias::isValidLinkage(Linkage))
|
||||||
return Error(NameLoc, "invalid linkage type for alias");
|
return Error(NameLoc, "invalid linkage type for alias");
|
||||||
|
|
||||||
if (!isValidVisibilityForLinkage(Visibility, L))
|
if (!isValidVisibilityForLinkage(Visibility, L))
|
||||||
@ -746,11 +752,16 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, unsigned L,
|
|||||||
return Error(AliaseeLoc, "An alias must have pointer type");
|
return Error(AliaseeLoc, "An alias must have pointer type");
|
||||||
unsigned AddrSpace = PTy->getAddressSpace();
|
unsigned AddrSpace = PTy->getAddressSpace();
|
||||||
|
|
||||||
if (Ty != PTy->getElementType())
|
if (IsAlias && Ty != PTy->getElementType())
|
||||||
return Error(
|
return Error(
|
||||||
ExplicitTypeLoc,
|
ExplicitTypeLoc,
|
||||||
"explicit pointee type doesn't match operand's pointee type");
|
"explicit pointee type doesn't match operand's pointee type");
|
||||||
|
|
||||||
|
if (!IsAlias && !PTy->getElementType()->isFunctionTy())
|
||||||
|
return Error(
|
||||||
|
ExplicitTypeLoc,
|
||||||
|
"explicit pointee type should be a function type");
|
||||||
|
|
||||||
GlobalValue *GVal = nullptr;
|
GlobalValue *GVal = nullptr;
|
||||||
|
|
||||||
// See if the alias was forward referenced, if so, prepare to replace the
|
// See if the alias was forward referenced, if so, prepare to replace the
|
||||||
@ -770,9 +781,13 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, unsigned L,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Okay, create the alias but do not insert it into the module yet.
|
// Okay, create the alias but do not insert it into the module yet.
|
||||||
std::unique_ptr<GlobalAlias> GA(
|
std::unique_ptr<GlobalIndirectSymbol> GA;
|
||||||
GlobalAlias::create(Ty, AddrSpace, (GlobalValue::LinkageTypes)Linkage,
|
if (IsAlias)
|
||||||
Name, Aliasee, /*Parent*/ nullptr));
|
GA.reset(GlobalAlias::create(Ty, AddrSpace,
|
||||||
|
(GlobalValue::LinkageTypes)Linkage, Name,
|
||||||
|
Aliasee, /*Parent*/ nullptr));
|
||||||
|
else
|
||||||
|
llvm_unreachable("Not an alias!");
|
||||||
GA->setThreadLocalMode(TLM);
|
GA->setThreadLocalMode(TLM);
|
||||||
GA->setVisibility((GlobalValue::VisibilityTypes)Visibility);
|
GA->setVisibility((GlobalValue::VisibilityTypes)Visibility);
|
||||||
GA->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass);
|
GA->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass);
|
||||||
@ -795,7 +810,10 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, unsigned L,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Insert into the module, we know its name won't collide now.
|
// Insert into the module, we know its name won't collide now.
|
||||||
M->getAliasList().push_back(GA.get());
|
if (IsAlias)
|
||||||
|
M->getAliasList().push_back(cast<GlobalAlias>(GA.get()));
|
||||||
|
else
|
||||||
|
llvm_unreachable("Not an alias!");
|
||||||
assert(GA->getName() == Name && "Should not be a name conflict!");
|
assert(GA->getName() == Name && "Should not be a name conflict!");
|
||||||
|
|
||||||
// The module owns this now
|
// The module owns this now
|
||||||
|
@ -275,9 +275,11 @@ namespace llvm {
|
|||||||
bool HasLinkage, unsigned Visibility,
|
bool HasLinkage, unsigned Visibility,
|
||||||
unsigned DLLStorageClass,
|
unsigned DLLStorageClass,
|
||||||
GlobalVariable::ThreadLocalMode TLM, bool UnnamedAddr);
|
GlobalVariable::ThreadLocalMode TLM, bool UnnamedAddr);
|
||||||
bool ParseAlias(const std::string &Name, LocTy Loc, unsigned Linkage,
|
bool parseIndirectSymbol(const std::string &Name, LocTy Loc,
|
||||||
unsigned Visibility, unsigned DLLStorageClass,
|
unsigned Linkage, unsigned Visibility,
|
||||||
GlobalVariable::ThreadLocalMode TLM, bool UnnamedAddr);
|
unsigned DLLStorageClass,
|
||||||
|
GlobalVariable::ThreadLocalMode TLM,
|
||||||
|
bool UnnamedAddr);
|
||||||
bool parseComdat();
|
bool parseComdat();
|
||||||
bool ParseStandaloneMetadata();
|
bool ParseStandaloneMetadata();
|
||||||
bool ParseNamedMetadata();
|
bool ParseNamedMetadata();
|
||||||
|
@ -163,7 +163,7 @@ class BitcodeReader : public GVMaterializer {
|
|||||||
SmallVector<Instruction *, 64> InstructionList;
|
SmallVector<Instruction *, 64> InstructionList;
|
||||||
|
|
||||||
std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
|
std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
|
||||||
std::vector<std::pair<GlobalAlias*, unsigned> > AliasInits;
|
std::vector<std::pair<GlobalIndirectSymbol*, unsigned> > IndirectSymbolInits;
|
||||||
std::vector<std::pair<Function*, unsigned> > FunctionPrefixes;
|
std::vector<std::pair<Function*, unsigned> > FunctionPrefixes;
|
||||||
std::vector<std::pair<Function*, unsigned> > FunctionPrologues;
|
std::vector<std::pair<Function*, unsigned> > FunctionPrologues;
|
||||||
std::vector<std::pair<Function*, unsigned> > FunctionPersonalityFns;
|
std::vector<std::pair<Function*, unsigned> > FunctionPersonalityFns;
|
||||||
@ -395,7 +395,7 @@ private:
|
|||||||
std::error_code rememberAndSkipMetadata();
|
std::error_code rememberAndSkipMetadata();
|
||||||
std::error_code parseFunctionBody(Function *F);
|
std::error_code parseFunctionBody(Function *F);
|
||||||
std::error_code globalCleanup();
|
std::error_code globalCleanup();
|
||||||
std::error_code resolveGlobalAndAliasInits();
|
std::error_code resolveGlobalAndIndirectSymbolInits();
|
||||||
std::error_code parseMetadata(bool ModuleLevel = false);
|
std::error_code parseMetadata(bool ModuleLevel = false);
|
||||||
std::error_code parseMetadataStrings(ArrayRef<uint64_t> Record,
|
std::error_code parseMetadataStrings(ArrayRef<uint64_t> Record,
|
||||||
StringRef Blob,
|
StringRef Blob,
|
||||||
@ -2492,15 +2492,16 @@ uint64_t BitcodeReader::decodeSignRotatedValue(uint64_t V) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Resolve all of the initializers for global values and aliases that we can.
|
/// Resolve all of the initializers for global values and aliases that we can.
|
||||||
std::error_code BitcodeReader::resolveGlobalAndAliasInits() {
|
std::error_code BitcodeReader::resolveGlobalAndIndirectSymbolInits() {
|
||||||
std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInitWorklist;
|
std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInitWorklist;
|
||||||
std::vector<std::pair<GlobalAlias*, unsigned> > AliasInitWorklist;
|
std::vector<std::pair<GlobalIndirectSymbol*, unsigned> >
|
||||||
|
IndirectSymbolInitWorklist;
|
||||||
std::vector<std::pair<Function*, unsigned> > FunctionPrefixWorklist;
|
std::vector<std::pair<Function*, unsigned> > FunctionPrefixWorklist;
|
||||||
std::vector<std::pair<Function*, unsigned> > FunctionPrologueWorklist;
|
std::vector<std::pair<Function*, unsigned> > FunctionPrologueWorklist;
|
||||||
std::vector<std::pair<Function*, unsigned> > FunctionPersonalityFnWorklist;
|
std::vector<std::pair<Function*, unsigned> > FunctionPersonalityFnWorklist;
|
||||||
|
|
||||||
GlobalInitWorklist.swap(GlobalInits);
|
GlobalInitWorklist.swap(GlobalInits);
|
||||||
AliasInitWorklist.swap(AliasInits);
|
IndirectSymbolInitWorklist.swap(IndirectSymbolInits);
|
||||||
FunctionPrefixWorklist.swap(FunctionPrefixes);
|
FunctionPrefixWorklist.swap(FunctionPrefixes);
|
||||||
FunctionPrologueWorklist.swap(FunctionPrologues);
|
FunctionPrologueWorklist.swap(FunctionPrologues);
|
||||||
FunctionPersonalityFnWorklist.swap(FunctionPersonalityFns);
|
FunctionPersonalityFnWorklist.swap(FunctionPersonalityFns);
|
||||||
@ -2519,20 +2520,20 @@ std::error_code BitcodeReader::resolveGlobalAndAliasInits() {
|
|||||||
GlobalInitWorklist.pop_back();
|
GlobalInitWorklist.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!AliasInitWorklist.empty()) {
|
while (!IndirectSymbolInitWorklist.empty()) {
|
||||||
unsigned ValID = AliasInitWorklist.back().second;
|
unsigned ValID = IndirectSymbolInitWorklist.back().second;
|
||||||
if (ValID >= ValueList.size()) {
|
if (ValID >= ValueList.size()) {
|
||||||
AliasInits.push_back(AliasInitWorklist.back());
|
IndirectSymbolInits.push_back(IndirectSymbolInitWorklist.back());
|
||||||
} else {
|
} else {
|
||||||
Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID]);
|
Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID]);
|
||||||
if (!C)
|
if (!C)
|
||||||
return error("Expected a constant");
|
return error("Expected a constant");
|
||||||
GlobalAlias *Alias = AliasInitWorklist.back().first;
|
GlobalIndirectSymbol *GIS = IndirectSymbolInitWorklist.back().first;
|
||||||
if (C->getType() != Alias->getType())
|
if (isa<GlobalAlias>(GIS) && C->getType() != GIS->getType())
|
||||||
return error("Alias and aliasee types don't match");
|
return error("Alias and aliasee types don't match");
|
||||||
Alias->setAliasee(C);
|
GIS->setIndirectSymbol(C);
|
||||||
}
|
}
|
||||||
AliasInitWorklist.pop_back();
|
IndirectSymbolInitWorklist.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!FunctionPrefixWorklist.empty()) {
|
while (!FunctionPrefixWorklist.empty()) {
|
||||||
@ -3157,8 +3158,8 @@ std::error_code BitcodeReader::rememberAndSkipFunctionBody() {
|
|||||||
|
|
||||||
std::error_code BitcodeReader::globalCleanup() {
|
std::error_code BitcodeReader::globalCleanup() {
|
||||||
// Patch the initializers for globals and aliases up.
|
// Patch the initializers for globals and aliases up.
|
||||||
resolveGlobalAndAliasInits();
|
resolveGlobalAndIndirectSymbolInits();
|
||||||
if (!GlobalInits.empty() || !AliasInits.empty())
|
if (!GlobalInits.empty() || !IndirectSymbolInits.empty())
|
||||||
return error("Malformed global initializer set");
|
return error("Malformed global initializer set");
|
||||||
|
|
||||||
// Look for intrinsic functions which need to be upgraded at some point
|
// Look for intrinsic functions which need to be upgraded at some point
|
||||||
@ -3175,7 +3176,8 @@ std::error_code BitcodeReader::globalCleanup() {
|
|||||||
// Force deallocation of memory for these vectors to favor the client that
|
// Force deallocation of memory for these vectors to favor the client that
|
||||||
// want lazy deserialization.
|
// want lazy deserialization.
|
||||||
std::vector<std::pair<GlobalVariable*, unsigned> >().swap(GlobalInits);
|
std::vector<std::pair<GlobalVariable*, unsigned> >().swap(GlobalInits);
|
||||||
std::vector<std::pair<GlobalAlias*, unsigned> >().swap(AliasInits);
|
std::vector<std::pair<GlobalIndirectSymbol*, unsigned> >().swap(
|
||||||
|
IndirectSymbolInits);
|
||||||
return std::error_code();
|
return std::error_code();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3325,7 +3327,7 @@ std::error_code BitcodeReader::parseModule(uint64_t ResumeBit,
|
|||||||
case bitc::CONSTANTS_BLOCK_ID:
|
case bitc::CONSTANTS_BLOCK_ID:
|
||||||
if (std::error_code EC = parseConstants())
|
if (std::error_code EC = parseConstants())
|
||||||
return EC;
|
return EC;
|
||||||
if (std::error_code EC = resolveGlobalAndAliasInits())
|
if (std::error_code EC = resolveGlobalAndIndirectSymbolInits())
|
||||||
return EC;
|
return EC;
|
||||||
break;
|
break;
|
||||||
case bitc::METADATA_BLOCK_ID:
|
case bitc::METADATA_BLOCK_ID:
|
||||||
@ -3658,7 +3660,7 @@ std::error_code BitcodeReader::parseModule(uint64_t ResumeBit,
|
|||||||
// ALIAS: [alias type, addrspace, aliasee val#, linkage, visibility, dllstorageclass]
|
// ALIAS: [alias type, addrspace, aliasee val#, linkage, visibility, dllstorageclass]
|
||||||
case bitc::MODULE_CODE_ALIAS:
|
case bitc::MODULE_CODE_ALIAS:
|
||||||
case bitc::MODULE_CODE_ALIAS_OLD: {
|
case bitc::MODULE_CODE_ALIAS_OLD: {
|
||||||
bool NewRecord = BitCode == bitc::MODULE_CODE_ALIAS;
|
bool NewRecord = BitCode != bitc::MODULE_CODE_ALIAS_OLD;
|
||||||
if (Record.size() < (3 + (unsigned)NewRecord))
|
if (Record.size() < (3 + (unsigned)NewRecord))
|
||||||
return error("Invalid record");
|
return error("Invalid record");
|
||||||
unsigned OpNum = 0;
|
unsigned OpNum = 0;
|
||||||
@ -3679,8 +3681,13 @@ std::error_code BitcodeReader::parseModule(uint64_t ResumeBit,
|
|||||||
|
|
||||||
auto Val = Record[OpNum++];
|
auto Val = Record[OpNum++];
|
||||||
auto Linkage = Record[OpNum++];
|
auto Linkage = Record[OpNum++];
|
||||||
auto *NewGA = GlobalAlias::create(
|
GlobalIndirectSymbol *NewGA;
|
||||||
|
if (BitCode == bitc::MODULE_CODE_ALIAS ||
|
||||||
|
BitCode == bitc::MODULE_CODE_ALIAS_OLD)
|
||||||
|
NewGA = GlobalAlias::create(
|
||||||
Ty, AddrSpace, getDecodedLinkage(Linkage), "", TheModule);
|
Ty, AddrSpace, getDecodedLinkage(Linkage), "", TheModule);
|
||||||
|
else
|
||||||
|
llvm_unreachable("Not an alias!");
|
||||||
// Old bitcode files didn't have visibility field.
|
// Old bitcode files didn't have visibility field.
|
||||||
// Local linkage must have default visibility.
|
// Local linkage must have default visibility.
|
||||||
if (OpNum != Record.size()) {
|
if (OpNum != Record.size()) {
|
||||||
@ -3698,7 +3705,7 @@ std::error_code BitcodeReader::parseModule(uint64_t ResumeBit,
|
|||||||
if (OpNum != Record.size())
|
if (OpNum != Record.size())
|
||||||
NewGA->setUnnamedAddr(Record[OpNum++]);
|
NewGA->setUnnamedAddr(Record[OpNum++]);
|
||||||
ValueList.push_back(NewGA);
|
ValueList.push_back(NewGA);
|
||||||
AliasInits.push_back(std::make_pair(NewGA, Val));
|
IndirectSymbolInits.push_back(std::make_pair(NewGA, Val));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/// MODULE_CODE_PURGEVALS: [numvals]
|
/// MODULE_CODE_PURGEVALS: [numvals]
|
||||||
|
@ -1060,6 +1060,49 @@ void AsmPrinter::emitGlobalGOTEquivs() {
|
|||||||
EmitGlobalVariable(GV);
|
EmitGlobalVariable(GV);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AsmPrinter::emitGlobalIndirectSymbol(Module &M,
|
||||||
|
const GlobalIndirectSymbol& GIS) {
|
||||||
|
MCSymbol *Name = getSymbol(&GIS);
|
||||||
|
|
||||||
|
if (GIS.hasExternalLinkage() || !MAI->getWeakRefDirective())
|
||||||
|
OutStreamer->EmitSymbolAttribute(Name, MCSA_Global);
|
||||||
|
else if (GIS.hasWeakLinkage() || GIS.hasLinkOnceLinkage())
|
||||||
|
OutStreamer->EmitSymbolAttribute(Name, MCSA_WeakReference);
|
||||||
|
else
|
||||||
|
assert(GIS.hasLocalLinkage() && "Invalid alias linkage");
|
||||||
|
|
||||||
|
// Set the symbol type to function if the alias has a function type.
|
||||||
|
// This affects codegen when the aliasee is not a function.
|
||||||
|
if (GIS.getType()->getPointerElementType()->isFunctionTy())
|
||||||
|
OutStreamer->EmitSymbolAttribute(Name, MCSA_ELF_TypeFunction);
|
||||||
|
|
||||||
|
EmitVisibility(Name, GIS.getVisibility());
|
||||||
|
|
||||||
|
const MCExpr *Expr = lowerConstant(GIS.getIndirectSymbol());
|
||||||
|
|
||||||
|
if (isa<GlobalAlias>(&GIS) && MAI->hasAltEntry() && isa<MCBinaryExpr>(Expr))
|
||||||
|
OutStreamer->EmitSymbolAttribute(Name, MCSA_AltEntry);
|
||||||
|
|
||||||
|
// Emit the directives as assignments aka .set:
|
||||||
|
OutStreamer->EmitAssignment(Name, Expr);
|
||||||
|
|
||||||
|
if (auto *GA = dyn_cast<GlobalAlias>(&GIS)) {
|
||||||
|
// If the aliasee does not correspond to a symbol in the output, i.e. the
|
||||||
|
// alias is not of an object or the aliased object is private, then set the
|
||||||
|
// size of the alias symbol from the type of the alias. We don't do this in
|
||||||
|
// other situations as the alias and aliasee having differing types but same
|
||||||
|
// size may be intentional.
|
||||||
|
const GlobalObject *BaseObject = GA->getBaseObject();
|
||||||
|
if (MAI->hasDotTypeDotSizeDirective() && GA->getValueType()->isSized() &&
|
||||||
|
(!BaseObject || BaseObject->hasPrivateLinkage())) {
|
||||||
|
const DataLayout &DL = M.getDataLayout();
|
||||||
|
uint64_t Size = DL.getTypeAllocSize(GA->getValueType());
|
||||||
|
OutStreamer->emitELFSize(cast<MCSymbolELF>(Name),
|
||||||
|
MCConstantExpr::create(Size, OutContext));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool AsmPrinter::doFinalization(Module &M) {
|
bool AsmPrinter::doFinalization(Module &M) {
|
||||||
// Set the MachineFunction to nullptr so that we can catch attempted
|
// Set the MachineFunction to nullptr so that we can catch attempted
|
||||||
// accesses to MF specific features at the module level and so that
|
// accesses to MF specific features at the module level and so that
|
||||||
@ -1148,45 +1191,7 @@ bool AsmPrinter::doFinalization(Module &M) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
OutStreamer->AddBlankLine();
|
OutStreamer->AddBlankLine();
|
||||||
const auto printAlias = [this, &M](const GlobalAlias &Alias) {
|
|
||||||
MCSymbol *Name = getSymbol(&Alias);
|
|
||||||
|
|
||||||
if (Alias.hasExternalLinkage() || !MAI->getWeakRefDirective())
|
|
||||||
OutStreamer->EmitSymbolAttribute(Name, MCSA_Global);
|
|
||||||
else if (Alias.hasWeakLinkage() || Alias.hasLinkOnceLinkage())
|
|
||||||
OutStreamer->EmitSymbolAttribute(Name, MCSA_WeakReference);
|
|
||||||
else
|
|
||||||
assert(Alias.hasLocalLinkage() && "Invalid alias linkage");
|
|
||||||
|
|
||||||
// Set the symbol type to function if the alias has a function type.
|
|
||||||
// This affects codegen when the aliasee is not a function.
|
|
||||||
if (Alias.getType()->getPointerElementType()->isFunctionTy())
|
|
||||||
OutStreamer->EmitSymbolAttribute(Name, MCSA_ELF_TypeFunction);
|
|
||||||
|
|
||||||
EmitVisibility(Name, Alias.getVisibility());
|
|
||||||
|
|
||||||
const MCExpr *Expr = lowerConstant(Alias.getAliasee());
|
|
||||||
|
|
||||||
if (MAI->hasAltEntry() && isa<MCBinaryExpr>(Expr))
|
|
||||||
OutStreamer->EmitSymbolAttribute(Name, MCSA_AltEntry);
|
|
||||||
|
|
||||||
// Emit the directives as assignments aka .set:
|
|
||||||
OutStreamer->EmitAssignment(Name, Expr);
|
|
||||||
|
|
||||||
// If the aliasee does not correspond to a symbol in the output, i.e. the
|
|
||||||
// alias is not of an object or the aliased object is private, then set the
|
|
||||||
// size of the alias symbol from the type of the alias. We don't do this in
|
|
||||||
// other situations as the alias and aliasee having differing types but same
|
|
||||||
// size may be intentional.
|
|
||||||
const GlobalObject *BaseObject = Alias.getBaseObject();
|
|
||||||
if (MAI->hasDotTypeDotSizeDirective() && Alias.getValueType()->isSized() &&
|
|
||||||
(!BaseObject || BaseObject->hasPrivateLinkage())) {
|
|
||||||
const DataLayout &DL = M.getDataLayout();
|
|
||||||
uint64_t Size = DL.getTypeAllocSize(Alias.getValueType());
|
|
||||||
OutStreamer->emitELFSize(cast<MCSymbolELF>(Name),
|
|
||||||
MCConstantExpr::create(Size, OutContext));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// Print aliases in topological order, that is, for each alias a = b,
|
// Print aliases in topological order, that is, for each alias a = b,
|
||||||
// b must be printed before a.
|
// b must be printed before a.
|
||||||
// This is because on some targets (e.g. PowerPC) linker expects aliases in
|
// This is because on some targets (e.g. PowerPC) linker expects aliases in
|
||||||
@ -1201,7 +1206,7 @@ bool AsmPrinter::doFinalization(Module &M) {
|
|||||||
AliasStack.push_back(Cur);
|
AliasStack.push_back(Cur);
|
||||||
}
|
}
|
||||||
for (const GlobalAlias *AncestorAlias : reverse(AliasStack))
|
for (const GlobalAlias *AncestorAlias : reverse(AliasStack))
|
||||||
printAlias(*AncestorAlias);
|
emitGlobalIndirectSymbol(M, *AncestorAlias);
|
||||||
AliasStack.clear();
|
AliasStack.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2047,7 +2047,7 @@ public:
|
|||||||
|
|
||||||
void printTypeIdentities();
|
void printTypeIdentities();
|
||||||
void printGlobal(const GlobalVariable *GV);
|
void printGlobal(const GlobalVariable *GV);
|
||||||
void printAlias(const GlobalAlias *GV);
|
void printIndirectSymbol(const GlobalIndirectSymbol *GIS);
|
||||||
void printComdat(const Comdat *C);
|
void printComdat(const Comdat *C);
|
||||||
void printFunction(const Function *F);
|
void printFunction(const Function *F);
|
||||||
void printArgument(const Argument *FA, AttributeSet Attrs, unsigned Idx);
|
void printArgument(const Argument *FA, AttributeSet Attrs, unsigned Idx);
|
||||||
@ -2270,7 +2270,7 @@ void AssemblyWriter::printModule(const Module *M) {
|
|||||||
// Output all aliases.
|
// Output all aliases.
|
||||||
if (!M->alias_empty()) Out << "\n";
|
if (!M->alias_empty()) Out << "\n";
|
||||||
for (const GlobalAlias &GA : M->aliases())
|
for (const GlobalAlias &GA : M->aliases())
|
||||||
printAlias(&GA);
|
printIndirectSymbol(&GA);
|
||||||
|
|
||||||
// Output global use-lists.
|
// Output global use-lists.
|
||||||
printUseLists(nullptr);
|
printUseLists(nullptr);
|
||||||
@ -2451,36 +2451,39 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
|
|||||||
printInfoComment(*GV);
|
printInfoComment(*GV);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssemblyWriter::printAlias(const GlobalAlias *GA) {
|
void AssemblyWriter::printIndirectSymbol(const GlobalIndirectSymbol *GIS) {
|
||||||
if (GA->isMaterializable())
|
if (GIS->isMaterializable())
|
||||||
Out << "; Materializable\n";
|
Out << "; Materializable\n";
|
||||||
|
|
||||||
WriteAsOperandInternal(Out, GA, &TypePrinter, &Machine, GA->getParent());
|
WriteAsOperandInternal(Out, GIS, &TypePrinter, &Machine, GIS->getParent());
|
||||||
Out << " = ";
|
Out << " = ";
|
||||||
|
|
||||||
PrintLinkage(GA->getLinkage(), Out);
|
PrintLinkage(GIS->getLinkage(), Out);
|
||||||
PrintVisibility(GA->getVisibility(), Out);
|
PrintVisibility(GIS->getVisibility(), Out);
|
||||||
PrintDLLStorageClass(GA->getDLLStorageClass(), Out);
|
PrintDLLStorageClass(GIS->getDLLStorageClass(), Out);
|
||||||
PrintThreadLocalModel(GA->getThreadLocalMode(), Out);
|
PrintThreadLocalModel(GIS->getThreadLocalMode(), Out);
|
||||||
if (GA->hasUnnamedAddr())
|
if (GIS->hasUnnamedAddr())
|
||||||
Out << "unnamed_addr ";
|
Out << "unnamed_addr ";
|
||||||
|
|
||||||
Out << "alias ";
|
if (isa<GlobalAlias>(GIS))
|
||||||
|
Out << "alias ";
|
||||||
|
else
|
||||||
|
llvm_unreachable("Not an alias!");
|
||||||
|
|
||||||
TypePrinter.print(GA->getValueType(), Out);
|
TypePrinter.print(GIS->getValueType(), Out);
|
||||||
|
|
||||||
Out << ", ";
|
Out << ", ";
|
||||||
|
|
||||||
const Constant *Aliasee = GA->getAliasee();
|
const Constant *IS = GIS->getIndirectSymbol();
|
||||||
|
|
||||||
if (!Aliasee) {
|
if (!IS) {
|
||||||
TypePrinter.print(GA->getType(), Out);
|
TypePrinter.print(GIS->getType(), Out);
|
||||||
Out << " <<NULL ALIASEE>>";
|
Out << " <<NULL ALIASEE>>";
|
||||||
} else {
|
} else {
|
||||||
writeOperand(Aliasee, !isa<ConstantExpr>(Aliasee));
|
writeOperand(IS, !isa<ConstantExpr>(IS));
|
||||||
}
|
}
|
||||||
|
|
||||||
printInfoComment(*GA);
|
printInfoComment(*GIS);
|
||||||
Out << '\n';
|
Out << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3348,7 +3351,7 @@ void Value::print(raw_ostream &ROS, ModuleSlotTracker &MST,
|
|||||||
else if (const Function *F = dyn_cast<Function>(GV))
|
else if (const Function *F = dyn_cast<Function>(GV))
|
||||||
W.printFunction(F);
|
W.printFunction(F);
|
||||||
else
|
else
|
||||||
W.printAlias(cast<GlobalAlias>(GV));
|
W.printIndirectSymbol(cast<GlobalIndirectSymbol>(GV));
|
||||||
} else if (const MetadataAsValue *V = dyn_cast<MetadataAsValue>(this)) {
|
} else if (const MetadataAsValue *V = dyn_cast<MetadataAsValue>(this)) {
|
||||||
V->getMetadata()->print(ROS, MST, getModuleFromVal(V));
|
V->getMetadata()->print(ROS, MST, getModuleFromVal(V));
|
||||||
} else if (const Constant *C = dyn_cast<Constant>(this)) {
|
} else if (const Constant *C = dyn_cast<Constant>(this)) {
|
||||||
|
@ -159,8 +159,8 @@ bool GlobalValue::isDeclaration() const {
|
|||||||
if (const Function *F = dyn_cast<Function>(this))
|
if (const Function *F = dyn_cast<Function>(this))
|
||||||
return F->empty() && !F->isMaterializable();
|
return F->empty() && !F->isMaterializable();
|
||||||
|
|
||||||
// Aliases are always definitions.
|
// Aliases and ifuncs are always definitions.
|
||||||
assert(isa<GlobalAlias>(this));
|
assert(isa<GlobalIndirectSymbol>(this));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,9 +205,9 @@ void GlobalDCE::GlobalIsNeeded(GlobalValue *G) {
|
|||||||
// referenced by the initializer to the alive set.
|
// referenced by the initializer to the alive set.
|
||||||
if (GV->hasInitializer())
|
if (GV->hasInitializer())
|
||||||
MarkUsedGlobalsAsNeeded(GV->getInitializer());
|
MarkUsedGlobalsAsNeeded(GV->getInitializer());
|
||||||
} else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(G)) {
|
} else if (GlobalIndirectSymbol *GIS = dyn_cast<GlobalIndirectSymbol>(G)) {
|
||||||
// The target of a global alias is needed.
|
// The target of a global alias or ifunc is needed.
|
||||||
MarkUsedGlobalsAsNeeded(GA->getAliasee());
|
MarkUsedGlobalsAsNeeded(GIS->getIndirectSymbol());
|
||||||
} else {
|
} else {
|
||||||
// Otherwise this must be a function object. We have to scan the body of
|
// Otherwise this must be a function object. We have to scan the body of
|
||||||
// the function looking for constants and global values which are used as
|
// the function looking for constants and global values which are used as
|
||||||
|
Loading…
Reference in New Issue
Block a user