1
0
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:
Dmitry Polukhin 2016-04-05 08:47:51 +00:00
parent 159be8f3fc
commit 4f1426bbd4
8 changed files with 141 additions and 102 deletions

View File

@ -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);
}; };
} }

View File

@ -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

View File

@ -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();

View File

@ -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]

View File

@ -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();
} }

View File

@ -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)) {

View File

@ -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;
} }

View File

@ -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