mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +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 DIEAbbrev;
|
||||
class GCMetadataPrinter;
|
||||
class GlobalIndirectSymbol;
|
||||
class GlobalValue;
|
||||
class GlobalVariable;
|
||||
class MachineBasicBlock;
|
||||
@ -546,6 +547,9 @@ private:
|
||||
void EmitXXStructorList(const DataLayout &DL, const Constant *List,
|
||||
bool isCtor);
|
||||
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)
|
||||
return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility,
|
||||
DLLStorageClass, TLM, UnnamedAddr);
|
||||
return ParseAlias(Name, NameLoc, Linkage, Visibility, DLLStorageClass, TLM,
|
||||
UnnamedAddr);
|
||||
|
||||
return parseIndirectSymbol(Name, NameLoc, Linkage, Visibility,
|
||||
DLLStorageClass, TLM, UnnamedAddr);
|
||||
}
|
||||
|
||||
/// ParseNamedGlobal:
|
||||
@ -533,8 +534,8 @@ bool LLParser::ParseNamedGlobal() {
|
||||
return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility,
|
||||
DLLStorageClass, TLM, UnnamedAddr);
|
||||
|
||||
return ParseAlias(Name, NameLoc, Linkage, Visibility, DLLStorageClass, TLM,
|
||||
UnnamedAddr);
|
||||
return parseIndirectSymbol(Name, NameLoc, Linkage, Visibility,
|
||||
DLLStorageClass, TLM, UnnamedAddr);
|
||||
}
|
||||
|
||||
bool LLParser::parseComdat() {
|
||||
@ -690,26 +691,31 @@ static bool isValidVisibilityForLinkage(unsigned V, unsigned L) {
|
||||
(GlobalValue::VisibilityTypes)V == GlobalValue::DefaultVisibility;
|
||||
}
|
||||
|
||||
/// ParseAlias:
|
||||
/// parseIndirectSymbol:
|
||||
/// ::= GlobalVar '=' OptionalLinkage OptionalVisibility
|
||||
/// OptionalDLLStorageClass OptionalThreadLocal
|
||||
/// OptionalUnnamedAddr 'alias' Aliasee
|
||||
/// OptionalUnnamedAddr 'alias' IndirectSymbol
|
||||
///
|
||||
/// Aliasee
|
||||
/// IndirectSymbol
|
||||
/// ::= TypeAndValue
|
||||
///
|
||||
/// Everything through OptionalUnnamedAddr has already been parsed.
|
||||
///
|
||||
bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc, unsigned L,
|
||||
unsigned Visibility, unsigned DLLStorageClass,
|
||||
GlobalVariable::ThreadLocalMode TLM,
|
||||
bool UnnamedAddr) {
|
||||
assert(Lex.getKind() == lltok::kw_alias);
|
||||
bool LLParser::parseIndirectSymbol(const std::string &Name, LocTy NameLoc,
|
||||
unsigned L, unsigned Visibility,
|
||||
unsigned DLLStorageClass,
|
||||
GlobalVariable::ThreadLocalMode TLM,
|
||||
bool UnnamedAddr) {
|
||||
bool IsAlias;
|
||||
if (Lex.getKind() == lltok::kw_alias)
|
||||
IsAlias = true;
|
||||
else
|
||||
llvm_unreachable("Not an alias!");
|
||||
Lex.Lex();
|
||||
|
||||
GlobalValue::LinkageTypes Linkage = (GlobalValue::LinkageTypes) L;
|
||||
|
||||
if(!GlobalAlias::isValidLinkage(Linkage))
|
||||
if(IsAlias && !GlobalAlias::isValidLinkage(Linkage))
|
||||
return Error(NameLoc, "invalid linkage type for alias");
|
||||
|
||||
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");
|
||||
unsigned AddrSpace = PTy->getAddressSpace();
|
||||
|
||||
if (Ty != PTy->getElementType())
|
||||
if (IsAlias && Ty != PTy->getElementType())
|
||||
return Error(
|
||||
ExplicitTypeLoc,
|
||||
"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;
|
||||
|
||||
// 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.
|
||||
std::unique_ptr<GlobalAlias> GA(
|
||||
GlobalAlias::create(Ty, AddrSpace, (GlobalValue::LinkageTypes)Linkage,
|
||||
Name, Aliasee, /*Parent*/ nullptr));
|
||||
std::unique_ptr<GlobalIndirectSymbol> GA;
|
||||
if (IsAlias)
|
||||
GA.reset(GlobalAlias::create(Ty, AddrSpace,
|
||||
(GlobalValue::LinkageTypes)Linkage, Name,
|
||||
Aliasee, /*Parent*/ nullptr));
|
||||
else
|
||||
llvm_unreachable("Not an alias!");
|
||||
GA->setThreadLocalMode(TLM);
|
||||
GA->setVisibility((GlobalValue::VisibilityTypes)Visibility);
|
||||
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.
|
||||
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!");
|
||||
|
||||
// The module owns this now
|
||||
|
@ -275,9 +275,11 @@ namespace llvm {
|
||||
bool HasLinkage, unsigned Visibility,
|
||||
unsigned DLLStorageClass,
|
||||
GlobalVariable::ThreadLocalMode TLM, bool UnnamedAddr);
|
||||
bool ParseAlias(const std::string &Name, LocTy Loc, unsigned Linkage,
|
||||
unsigned Visibility, unsigned DLLStorageClass,
|
||||
GlobalVariable::ThreadLocalMode TLM, bool UnnamedAddr);
|
||||
bool parseIndirectSymbol(const std::string &Name, LocTy Loc,
|
||||
unsigned Linkage, unsigned Visibility,
|
||||
unsigned DLLStorageClass,
|
||||
GlobalVariable::ThreadLocalMode TLM,
|
||||
bool UnnamedAddr);
|
||||
bool parseComdat();
|
||||
bool ParseStandaloneMetadata();
|
||||
bool ParseNamedMetadata();
|
||||
|
@ -163,7 +163,7 @@ class BitcodeReader : public GVMaterializer {
|
||||
SmallVector<Instruction *, 64> InstructionList;
|
||||
|
||||
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> > FunctionPrologues;
|
||||
std::vector<std::pair<Function*, unsigned> > FunctionPersonalityFns;
|
||||
@ -395,7 +395,7 @@ private:
|
||||
std::error_code rememberAndSkipMetadata();
|
||||
std::error_code parseFunctionBody(Function *F);
|
||||
std::error_code globalCleanup();
|
||||
std::error_code resolveGlobalAndAliasInits();
|
||||
std::error_code resolveGlobalAndIndirectSymbolInits();
|
||||
std::error_code parseMetadata(bool ModuleLevel = false);
|
||||
std::error_code parseMetadataStrings(ArrayRef<uint64_t> Record,
|
||||
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.
|
||||
std::error_code BitcodeReader::resolveGlobalAndAliasInits() {
|
||||
std::error_code BitcodeReader::resolveGlobalAndIndirectSymbolInits() {
|
||||
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> > FunctionPrologueWorklist;
|
||||
std::vector<std::pair<Function*, unsigned> > FunctionPersonalityFnWorklist;
|
||||
|
||||
GlobalInitWorklist.swap(GlobalInits);
|
||||
AliasInitWorklist.swap(AliasInits);
|
||||
IndirectSymbolInitWorklist.swap(IndirectSymbolInits);
|
||||
FunctionPrefixWorklist.swap(FunctionPrefixes);
|
||||
FunctionPrologueWorklist.swap(FunctionPrologues);
|
||||
FunctionPersonalityFnWorklist.swap(FunctionPersonalityFns);
|
||||
@ -2519,20 +2520,20 @@ std::error_code BitcodeReader::resolveGlobalAndAliasInits() {
|
||||
GlobalInitWorklist.pop_back();
|
||||
}
|
||||
|
||||
while (!AliasInitWorklist.empty()) {
|
||||
unsigned ValID = AliasInitWorklist.back().second;
|
||||
while (!IndirectSymbolInitWorklist.empty()) {
|
||||
unsigned ValID = IndirectSymbolInitWorklist.back().second;
|
||||
if (ValID >= ValueList.size()) {
|
||||
AliasInits.push_back(AliasInitWorklist.back());
|
||||
IndirectSymbolInits.push_back(IndirectSymbolInitWorklist.back());
|
||||
} else {
|
||||
Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID]);
|
||||
if (!C)
|
||||
return error("Expected a constant");
|
||||
GlobalAlias *Alias = AliasInitWorklist.back().first;
|
||||
if (C->getType() != Alias->getType())
|
||||
GlobalIndirectSymbol *GIS = IndirectSymbolInitWorklist.back().first;
|
||||
if (isa<GlobalAlias>(GIS) && C->getType() != GIS->getType())
|
||||
return error("Alias and aliasee types don't match");
|
||||
Alias->setAliasee(C);
|
||||
GIS->setIndirectSymbol(C);
|
||||
}
|
||||
AliasInitWorklist.pop_back();
|
||||
IndirectSymbolInitWorklist.pop_back();
|
||||
}
|
||||
|
||||
while (!FunctionPrefixWorklist.empty()) {
|
||||
@ -3157,8 +3158,8 @@ std::error_code BitcodeReader::rememberAndSkipFunctionBody() {
|
||||
|
||||
std::error_code BitcodeReader::globalCleanup() {
|
||||
// Patch the initializers for globals and aliases up.
|
||||
resolveGlobalAndAliasInits();
|
||||
if (!GlobalInits.empty() || !AliasInits.empty())
|
||||
resolveGlobalAndIndirectSymbolInits();
|
||||
if (!GlobalInits.empty() || !IndirectSymbolInits.empty())
|
||||
return error("Malformed global initializer set");
|
||||
|
||||
// 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
|
||||
// want lazy deserialization.
|
||||
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();
|
||||
}
|
||||
|
||||
@ -3325,7 +3327,7 @@ std::error_code BitcodeReader::parseModule(uint64_t ResumeBit,
|
||||
case bitc::CONSTANTS_BLOCK_ID:
|
||||
if (std::error_code EC = parseConstants())
|
||||
return EC;
|
||||
if (std::error_code EC = resolveGlobalAndAliasInits())
|
||||
if (std::error_code EC = resolveGlobalAndIndirectSymbolInits())
|
||||
return EC;
|
||||
break;
|
||||
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]
|
||||
case bitc::MODULE_CODE_ALIAS:
|
||||
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))
|
||||
return error("Invalid record");
|
||||
unsigned OpNum = 0;
|
||||
@ -3679,8 +3681,13 @@ std::error_code BitcodeReader::parseModule(uint64_t ResumeBit,
|
||||
|
||||
auto Val = 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);
|
||||
else
|
||||
llvm_unreachable("Not an alias!");
|
||||
// Old bitcode files didn't have visibility field.
|
||||
// Local linkage must have default visibility.
|
||||
if (OpNum != Record.size()) {
|
||||
@ -3698,7 +3705,7 @@ std::error_code BitcodeReader::parseModule(uint64_t ResumeBit,
|
||||
if (OpNum != Record.size())
|
||||
NewGA->setUnnamedAddr(Record[OpNum++]);
|
||||
ValueList.push_back(NewGA);
|
||||
AliasInits.push_back(std::make_pair(NewGA, Val));
|
||||
IndirectSymbolInits.push_back(std::make_pair(NewGA, Val));
|
||||
break;
|
||||
}
|
||||
/// MODULE_CODE_PURGEVALS: [numvals]
|
||||
|
@ -1060,6 +1060,49 @@ void AsmPrinter::emitGlobalGOTEquivs() {
|
||||
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) {
|
||||
// Set the MachineFunction to nullptr so that we can catch attempted
|
||||
// accesses to MF specific features at the module level and so that
|
||||
@ -1148,45 +1191,7 @@ bool AsmPrinter::doFinalization(Module &M) {
|
||||
}
|
||||
|
||||
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,
|
||||
// b must be printed before a.
|
||||
// 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);
|
||||
}
|
||||
for (const GlobalAlias *AncestorAlias : reverse(AliasStack))
|
||||
printAlias(*AncestorAlias);
|
||||
emitGlobalIndirectSymbol(M, *AncestorAlias);
|
||||
AliasStack.clear();
|
||||
}
|
||||
|
||||
|
@ -2047,7 +2047,7 @@ public:
|
||||
|
||||
void printTypeIdentities();
|
||||
void printGlobal(const GlobalVariable *GV);
|
||||
void printAlias(const GlobalAlias *GV);
|
||||
void printIndirectSymbol(const GlobalIndirectSymbol *GIS);
|
||||
void printComdat(const Comdat *C);
|
||||
void printFunction(const Function *F);
|
||||
void printArgument(const Argument *FA, AttributeSet Attrs, unsigned Idx);
|
||||
@ -2270,7 +2270,7 @@ void AssemblyWriter::printModule(const Module *M) {
|
||||
// Output all aliases.
|
||||
if (!M->alias_empty()) Out << "\n";
|
||||
for (const GlobalAlias &GA : M->aliases())
|
||||
printAlias(&GA);
|
||||
printIndirectSymbol(&GA);
|
||||
|
||||
// Output global use-lists.
|
||||
printUseLists(nullptr);
|
||||
@ -2451,36 +2451,39 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
|
||||
printInfoComment(*GV);
|
||||
}
|
||||
|
||||
void AssemblyWriter::printAlias(const GlobalAlias *GA) {
|
||||
if (GA->isMaterializable())
|
||||
void AssemblyWriter::printIndirectSymbol(const GlobalIndirectSymbol *GIS) {
|
||||
if (GIS->isMaterializable())
|
||||
Out << "; Materializable\n";
|
||||
|
||||
WriteAsOperandInternal(Out, GA, &TypePrinter, &Machine, GA->getParent());
|
||||
WriteAsOperandInternal(Out, GIS, &TypePrinter, &Machine, GIS->getParent());
|
||||
Out << " = ";
|
||||
|
||||
PrintLinkage(GA->getLinkage(), Out);
|
||||
PrintVisibility(GA->getVisibility(), Out);
|
||||
PrintDLLStorageClass(GA->getDLLStorageClass(), Out);
|
||||
PrintThreadLocalModel(GA->getThreadLocalMode(), Out);
|
||||
if (GA->hasUnnamedAddr())
|
||||
PrintLinkage(GIS->getLinkage(), Out);
|
||||
PrintVisibility(GIS->getVisibility(), Out);
|
||||
PrintDLLStorageClass(GIS->getDLLStorageClass(), Out);
|
||||
PrintThreadLocalModel(GIS->getThreadLocalMode(), Out);
|
||||
if (GIS->hasUnnamedAddr())
|
||||
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 << ", ";
|
||||
|
||||
const Constant *Aliasee = GA->getAliasee();
|
||||
const Constant *IS = GIS->getIndirectSymbol();
|
||||
|
||||
if (!Aliasee) {
|
||||
TypePrinter.print(GA->getType(), Out);
|
||||
if (!IS) {
|
||||
TypePrinter.print(GIS->getType(), Out);
|
||||
Out << " <<NULL ALIASEE>>";
|
||||
} else {
|
||||
writeOperand(Aliasee, !isa<ConstantExpr>(Aliasee));
|
||||
writeOperand(IS, !isa<ConstantExpr>(IS));
|
||||
}
|
||||
|
||||
printInfoComment(*GA);
|
||||
printInfoComment(*GIS);
|
||||
Out << '\n';
|
||||
}
|
||||
|
||||
@ -3348,7 +3351,7 @@ void Value::print(raw_ostream &ROS, ModuleSlotTracker &MST,
|
||||
else if (const Function *F = dyn_cast<Function>(GV))
|
||||
W.printFunction(F);
|
||||
else
|
||||
W.printAlias(cast<GlobalAlias>(GV));
|
||||
W.printIndirectSymbol(cast<GlobalIndirectSymbol>(GV));
|
||||
} else if (const MetadataAsValue *V = dyn_cast<MetadataAsValue>(this)) {
|
||||
V->getMetadata()->print(ROS, MST, getModuleFromVal(V));
|
||||
} 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))
|
||||
return F->empty() && !F->isMaterializable();
|
||||
|
||||
// Aliases are always definitions.
|
||||
assert(isa<GlobalAlias>(this));
|
||||
// Aliases and ifuncs are always definitions.
|
||||
assert(isa<GlobalIndirectSymbol>(this));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -205,9 +205,9 @@ void GlobalDCE::GlobalIsNeeded(GlobalValue *G) {
|
||||
// referenced by the initializer to the alive set.
|
||||
if (GV->hasInitializer())
|
||||
MarkUsedGlobalsAsNeeded(GV->getInitializer());
|
||||
} else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(G)) {
|
||||
// The target of a global alias is needed.
|
||||
MarkUsedGlobalsAsNeeded(GA->getAliasee());
|
||||
} else if (GlobalIndirectSymbol *GIS = dyn_cast<GlobalIndirectSymbol>(G)) {
|
||||
// The target of a global alias or ifunc is needed.
|
||||
MarkUsedGlobalsAsNeeded(GIS->getIndirectSymbol());
|
||||
} else {
|
||||
// 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
|
||||
|
Loading…
Reference in New Issue
Block a user