summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/IR/GlobalAlias.h4
-rw-r--r--llvm/include/llvm/IR/GlobalIFunc.h4
-rw-r--r--llvm/include/llvm/IR/GlobalIndirectSymbol.h4
-rw-r--r--llvm/include/llvm/Transforms/Utils/ValueMapper.h9
-rw-r--r--llvm/lib/Linker/IRMover.cpp98
-rw-r--r--llvm/lib/Transforms/Utils/ValueMapper.cpp43
-rw-r--r--llvm/test/LTO/Resolution/X86/Inputs/ifunc2.ll6
-rw-r--r--llvm/test/LTO/Resolution/X86/ifunc2.ll19
8 files changed, 111 insertions, 76 deletions
diff --git a/llvm/include/llvm/IR/GlobalAlias.h b/llvm/include/llvm/IR/GlobalAlias.h
index 3cd40570130..f2d9b9676ec 100644
--- a/llvm/include/llvm/IR/GlobalAlias.h
+++ b/llvm/include/llvm/IR/GlobalAlias.h
@@ -58,10 +58,6 @@ public:
// Linkage, Type, Parent and AddressSpace taken from the Aliasee.
static GlobalAlias *create(const Twine &Name, GlobalValue *Aliasee);
- void copyAttributesFrom(const GlobalValue *Src) {
- GlobalValue::copyAttributesFrom(Src);
- }
-
/// removeFromParent - This method unlinks 'this' from the containing module,
/// but does not delete it.
///
diff --git a/llvm/include/llvm/IR/GlobalIFunc.h b/llvm/include/llvm/IR/GlobalIFunc.h
index bc0d3c053cc..0fdae917878 100644
--- a/llvm/include/llvm/IR/GlobalIFunc.h
+++ b/llvm/include/llvm/IR/GlobalIFunc.h
@@ -46,10 +46,6 @@ public:
LinkageTypes Linkage, const Twine &Name,
Constant *Resolver, Module *Parent);
- void copyAttributesFrom(const GlobalIFunc *Src) {
- GlobalValue::copyAttributesFrom(Src);
- }
-
/// This method unlinks 'this' from the containing module, but does not
/// delete it.
void removeFromParent();
diff --git a/llvm/include/llvm/IR/GlobalIndirectSymbol.h b/llvm/include/llvm/IR/GlobalIndirectSymbol.h
index 678c038d88e..d996237aa3e 100644
--- a/llvm/include/llvm/IR/GlobalIndirectSymbol.h
+++ b/llvm/include/llvm/IR/GlobalIndirectSymbol.h
@@ -42,6 +42,10 @@ public:
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
+ void copyAttributesFrom(const GlobalValue *Src) {
+ GlobalValue::copyAttributesFrom(Src);
+ }
+
/// These methods set and retrieve indirect symbol.
void setIndirectSymbol(Constant *Symbol) {
setOperand(0, Symbol);
diff --git a/llvm/include/llvm/Transforms/Utils/ValueMapper.h b/llvm/include/llvm/Transforms/Utils/ValueMapper.h
index 1952a210291..ff5bfc60958 100644
--- a/llvm/include/llvm/Transforms/Utils/ValueMapper.h
+++ b/llvm/include/llvm/Transforms/Utils/ValueMapper.h
@@ -22,7 +22,7 @@ namespace llvm {
class Constant;
class Function;
-class GlobalAlias;
+class GlobalIndirectSymbol;
class GlobalVariable;
class Instruction;
class MDNode;
@@ -120,7 +120,7 @@ inline RemapFlags operator|(RemapFlags LHS, RemapFlags RHS) {
/// instance:
/// - \a scheduleMapGlobalInitializer()
/// - \a scheduleMapAppendingVariable()
-/// - \a scheduleMapGlobalAliasee()
+/// - \a scheduleMapGlobalIndirectSymbol()
/// - \a scheduleRemapFunction()
///
/// Sometimes a callback needs a different mapping context. Such a context can
@@ -180,8 +180,9 @@ public:
bool IsOldCtorDtor,
ArrayRef<Constant *> NewMembers,
unsigned MappingContextID = 0);
- void scheduleMapGlobalAliasee(GlobalAlias &GA, Constant &Aliasee,
- unsigned MappingContextID = 0);
+ void scheduleMapGlobalIndirectSymbol(GlobalIndirectSymbol &GIS,
+ Constant &Target,
+ unsigned MappingContextID = 0);
void scheduleRemapFunction(Function &F, unsigned MappingContextID = 0);
};
diff --git a/llvm/lib/Linker/IRMover.cpp b/llvm/lib/Linker/IRMover.cpp
index 37515d93ed5..8e89724d443 100644
--- a/llvm/lib/Linker/IRMover.cpp
+++ b/llvm/lib/Linker/IRMover.cpp
@@ -398,7 +398,7 @@ class IRLinker {
/// due to the use of Value handles which the Linker doesn't actually need,
/// but this allows us to reuse the ValueMapper code.
ValueToValueMapTy ValueMap;
- ValueToValueMapTy AliasValueMap;
+ ValueToValueMapTy IndirectSymbolValueMap;
DenseSet<GlobalValue *> ValuesToLink;
std::vector<GlobalValue *> Worklist;
@@ -437,7 +437,7 @@ class IRLinker {
/// Entry point for mapping values and alternate context for mapping aliases.
ValueMapper Mapper;
- unsigned AliasMCID;
+ unsigned IndirectSymbolMCID;
/// Handles cloning of a global values from the source module into
/// the destination module, including setting the attributes and visibility.
@@ -480,13 +480,15 @@ class IRLinker {
///
/// Note this code may call the client-provided \p AddLazyFor.
bool shouldLink(GlobalValue *DGV, GlobalValue &SGV);
- Expected<Constant *> linkGlobalValueProto(GlobalValue *GV, bool ForAlias);
+ Expected<Constant *> linkGlobalValueProto(GlobalValue *GV,
+ bool ForIndirectSymbol);
Error linkModuleFlagsMetadata();
void linkGlobalVariable(GlobalVariable &Dst, GlobalVariable &Src);
Error linkFunctionBody(Function &Dst, Function &Src);
- void linkAliasBody(GlobalAlias &Dst, GlobalAlias &Src);
+ void linkIndirectSymbolBody(GlobalIndirectSymbol &Dst,
+ GlobalIndirectSymbol &Src);
Error linkGlobalValueBody(GlobalValue &Dst, GlobalValue &Src);
/// Replace all types in the source AttributeList with the
@@ -497,7 +499,7 @@ class IRLinker {
/// into the destination module.
GlobalVariable *copyGlobalVariableProto(const GlobalVariable *SGVar);
Function *copyFunctionProto(const Function *SF);
- GlobalValue *copyGlobalAliasProto(const GlobalAlias *SGA);
+ GlobalValue *copyGlobalIndirectSymbolProto(const GlobalIndirectSymbol *SGIS);
/// Perform "replace all uses with" operations. These work items need to be
/// performed as part of materialization, but we postpone them to happen after
@@ -524,8 +526,8 @@ public:
SharedMDs(SharedMDs), IsPerformingImport(IsPerformingImport),
Mapper(ValueMap, RF_MoveDistinctMDs | RF_IgnoreMissingLocals, &TypeMap,
&GValMaterializer),
- AliasMCID(Mapper.registerAlternateMappingContext(AliasValueMap,
- &LValMaterializer)) {
+ IndirectSymbolMCID(Mapper.registerAlternateMappingContext(
+ IndirectSymbolValueMap, &LValMaterializer)) {
ValueMap.getMDMap() = std::move(SharedMDs);
for (GlobalValue *GV : ValuesToLink)
maybeAdd(GV);
@@ -535,7 +537,7 @@ public:
~IRLinker() { SharedMDs = std::move(*ValueMap.getMDMap()); }
Error run();
- Value *materialize(Value *V, bool ForAlias);
+ Value *materialize(Value *V, bool ForIndirectSymbol);
};
}
@@ -568,12 +570,12 @@ Value *LocalValueMaterializer::materialize(Value *SGV) {
return TheIRLinker.materialize(SGV, true);
}
-Value *IRLinker::materialize(Value *V, bool ForAlias) {
+Value *IRLinker::materialize(Value *V, bool ForIndirectSymbol) {
auto *SGV = dyn_cast<GlobalValue>(V);
if (!SGV)
return nullptr;
- Expected<Constant *> NewProto = linkGlobalValueProto(SGV, ForAlias);
+ Expected<Constant *> NewProto = linkGlobalValueProto(SGV, ForIndirectSymbol);
if (!NewProto) {
setError(NewProto.takeError());
return nullptr;
@@ -593,23 +595,23 @@ Value *IRLinker::materialize(Value *V, bool ForAlias) {
if (V->hasInitializer() || V->hasAppendingLinkage())
return New;
} else {
- auto *A = cast<GlobalAlias>(New);
- if (A->getAliasee())
+ auto *IS = cast<GlobalIndirectSymbol>(New);
+ if (IS->getIndirectSymbol())
return New;
}
- // When linking a global for an alias, it will always be linked. However we
- // need to check if it was not already scheduled to satisfy a reference from a
- // regular global value initializer. We know if it has been schedule if the
- // "New" GlobalValue that is mapped here for the alias is the same as the one
- // already mapped. If there is an entry in the ValueMap but the value is
- // different, it means that the value already had a definition in the
- // destination module (linkonce for instance), but we need a new definition
- // for the alias ("New" will be different.
- if (ForAlias && ValueMap.lookup(SGV) == New)
+ // When linking a global for an indirect symbol, it will always be linked.
+ // However we need to check if it was not already scheduled to satisfy a
+ // reference from a regular global value initializer. We know if it has been
+ // schedule if the "New" GlobalValue that is mapped here for the indirect
+ // symbol is the same as the one already mapped. If there is an entry in the
+ // ValueMap but the value is different, it means that the value already had a
+ // definition in the destination module (linkonce for instance), but we need a
+ // new definition for the indirect symbol ("New" will be different.
+ if (ForIndirectSymbol && ValueMap.lookup(SGV) == New)
return New;
- if (ForAlias || shouldLink(New, *SGV))
+ if (ForIndirectSymbol || shouldLink(New, *SGV))
setError(linkGlobalValueBody(*New, *SGV));
return New;
@@ -660,16 +662,24 @@ Function *IRLinker::copyFunctionProto(const Function *SF) {
return F;
}
-/// Set up prototypes for any aliases that come over from the source module.
-GlobalValue *IRLinker::copyGlobalAliasProto(const GlobalAlias *SGA) {
+/// Set up prototypes for any indirect symbols that come over from the source
+/// module.
+GlobalValue *
+IRLinker::copyGlobalIndirectSymbolProto(const GlobalIndirectSymbol *SGIS) {
// If there is no linkage to be performed or we're linking from the source,
// bring over SGA.
- auto *Ty = TypeMap.get(SGA->getValueType());
- auto *GA =
- GlobalAlias::create(Ty, SGA->getType()->getPointerAddressSpace(),
- GlobalValue::ExternalLinkage, SGA->getName(), &DstM);
- GA->copyAttributesFrom(SGA);
- return GA;
+ auto *Ty = TypeMap.get(SGIS->getValueType());
+ GlobalIndirectSymbol *GIS;
+ if (isa<GlobalAlias>(SGIS))
+ GIS = GlobalAlias::create(Ty, SGIS->getType()->getPointerAddressSpace(),
+ GlobalValue::ExternalLinkage, SGIS->getName(),
+ &DstM);
+ else
+ GIS = GlobalIFunc::create(Ty, SGIS->getType()->getPointerAddressSpace(),
+ GlobalValue::ExternalLinkage, SGIS->getName(),
+ nullptr, &DstM);
+ GIS->copyAttributesFrom(SGIS);
+ return GIS;
}
GlobalValue *IRLinker::copyGlobalValueProto(const GlobalValue *SGV,
@@ -681,7 +691,7 @@ GlobalValue *IRLinker::copyGlobalValueProto(const GlobalValue *SGV,
NewGV = copyFunctionProto(SF);
} else {
if (ForDefinition)
- NewGV = copyGlobalAliasProto(cast<GlobalAlias>(SGV));
+ NewGV = copyGlobalIndirectSymbolProto(cast<GlobalIndirectSymbol>(SGV));
else if (SGV->getValueType()->isFunctionTy())
NewGV =
Function::Create(cast<FunctionType>(TypeMap.get(SGV->getValueType())),
@@ -940,7 +950,7 @@ bool IRLinker::shouldLink(GlobalValue *DGV, GlobalValue &SGV) {
}
Expected<Constant *> IRLinker::linkGlobalValueProto(GlobalValue *SGV,
- bool ForAlias) {
+ bool ForIndirectSymbol) {
GlobalValue *DGV = getLinkedToGlobal(SGV);
bool ShouldLink = shouldLink(DGV, *SGV);
@@ -951,12 +961,12 @@ Expected<Constant *> IRLinker::linkGlobalValueProto(GlobalValue *SGV,
if (I != ValueMap.end())
return cast<Constant>(I->second);
- I = AliasValueMap.find(SGV);
- if (I != AliasValueMap.end())
+ I = IndirectSymbolValueMap.find(SGV);
+ if (I != IndirectSymbolValueMap.end())
return cast<Constant>(I->second);
}
- if (!ShouldLink && ForAlias)
+ if (!ShouldLink && ForIndirectSymbol)
DGV = nullptr;
// Handle the ultra special appending linkage case first.
@@ -975,8 +985,8 @@ Expected<Constant *> IRLinker::linkGlobalValueProto(GlobalValue *SGV,
if (DoneLinkingBodies)
return nullptr;
- NewGV = copyGlobalValueProto(SGV, ShouldLink || ForAlias);
- if (ShouldLink || !ForAlias)
+ NewGV = copyGlobalValueProto(SGV, ShouldLink || ForIndirectSymbol);
+ if (ShouldLink || !ForIndirectSymbol)
forceRenaming(NewGV, SGV->getName());
}
@@ -987,7 +997,7 @@ Expected<Constant *> IRLinker::linkGlobalValueProto(GlobalValue *SGV,
if (auto Remangled = Intrinsic::remangleIntrinsicFunction(F))
NewGV = Remangled.getValue();
- if (ShouldLink || ForAlias) {
+ if (ShouldLink || ForIndirectSymbol) {
if (const Comdat *SC = SGV->getComdat()) {
if (auto *GO = dyn_cast<GlobalObject>(NewGV)) {
Comdat *DC = DstM.getOrInsertComdat(SC->getName());
@@ -997,7 +1007,7 @@ Expected<Constant *> IRLinker::linkGlobalValueProto(GlobalValue *SGV,
}
}
- if (!ShouldLink && ForAlias)
+ if (!ShouldLink && ForIndirectSymbol)
NewGV->setLinkage(GlobalValue::InternalLinkage);
Constant *C = NewGV;
@@ -1060,8 +1070,10 @@ Error IRLinker::linkFunctionBody(Function &Dst, Function &Src) {
return Error::success();
}
-void IRLinker::linkAliasBody(GlobalAlias &Dst, GlobalAlias &Src) {
- Mapper.scheduleMapGlobalAliasee(Dst, *Src.getAliasee(), AliasMCID);
+void IRLinker::linkIndirectSymbolBody(GlobalIndirectSymbol &Dst,
+ GlobalIndirectSymbol &Src) {
+ Mapper.scheduleMapGlobalIndirectSymbol(Dst, *Src.getIndirectSymbol(),
+ IndirectSymbolMCID);
}
Error IRLinker::linkGlobalValueBody(GlobalValue &Dst, GlobalValue &Src) {
@@ -1071,7 +1083,7 @@ Error IRLinker::linkGlobalValueBody(GlobalValue &Dst, GlobalValue &Src) {
linkGlobalVariable(cast<GlobalVariable>(Dst), *GVar);
return Error::success();
}
- linkAliasBody(cast<GlobalAlias>(Dst), cast<GlobalAlias>(Src));
+ linkIndirectSymbolBody(cast<GlobalIndirectSymbol>(Dst), cast<GlobalIndirectSymbol>(Src));
return Error::success();
}
@@ -1411,7 +1423,7 @@ Error IRLinker::run() {
// Already mapped.
if (ValueMap.find(GV) != ValueMap.end() ||
- AliasValueMap.find(GV) != AliasValueMap.end())
+ IndirectSymbolValueMap.find(GV) != IndirectSymbolValueMap.end())
continue;
assert(!GV->isDeclaration());
diff --git a/llvm/lib/Transforms/Utils/ValueMapper.cpp b/llvm/lib/Transforms/Utils/ValueMapper.cpp
index fbc3407c301..6aca0e417bb 100644
--- a/llvm/lib/Transforms/Utils/ValueMapper.cpp
+++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp
@@ -27,8 +27,8 @@
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
-#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalObject.h"
+#include "llvm/IR/GlobalIndirectSymbol.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instruction.h"
@@ -66,7 +66,7 @@ struct WorklistEntry {
enum EntryKind {
MapGlobalInit,
MapAppendingVar,
- MapGlobalAliasee,
+ MapGlobalIndirectSymbol,
RemapFunction
};
struct GVInitTy {
@@ -77,9 +77,9 @@ struct WorklistEntry {
GlobalVariable *GV;
Constant *InitPrefix;
};
- struct GlobalAliaseeTy {
- GlobalAlias *GA;
- Constant *Aliasee;
+ struct GlobalIndirectSymbolTy {
+ GlobalIndirectSymbol *GIS;
+ Constant *Target;
};
unsigned Kind : 2;
@@ -89,7 +89,7 @@ struct WorklistEntry {
union {
GVInitTy GVInit;
AppendingGVTy AppendingGV;
- GlobalAliaseeTy GlobalAliasee;
+ GlobalIndirectSymbolTy GlobalIndirectSymbol;
Function *RemapF;
} Data;
};
@@ -161,8 +161,8 @@ public:
bool IsOldCtorDtor,
ArrayRef<Constant *> NewMembers,
unsigned MCID);
- void scheduleMapGlobalAliasee(GlobalAlias &GA, Constant &Aliasee,
- unsigned MCID);
+ void scheduleMapGlobalIndirectSymbol(GlobalIndirectSymbol &GIS, Constant &Target,
+ unsigned MCID);
void scheduleRemapFunction(Function &F, unsigned MCID);
void flush();
@@ -172,7 +172,7 @@ private:
void mapAppendingVariable(GlobalVariable &GV, Constant *InitPrefix,
bool IsOldCtorDtor,
ArrayRef<Constant *> NewMembers);
- void mapGlobalAliasee(GlobalAlias &GA, Constant &Aliasee);
+ void mapGlobalIndirectSymbol(GlobalIndirectSymbol &GIS, Constant &Target);
void remapFunction(Function &F, ValueToValueMapTy &VM);
ValueToValueMapTy &getVM() { return *MCs[CurrentMCID].VM; }
@@ -846,9 +846,9 @@ void Mapper::flush() {
AppendingInits.resize(PrefixSize);
break;
}
- case WorklistEntry::MapGlobalAliasee:
- E.Data.GlobalAliasee.GA->setAliasee(
- mapConstant(E.Data.GlobalAliasee.Aliasee));
+ case WorklistEntry::MapGlobalIndirectSymbol:
+ E.Data.GlobalIndirectSymbol.GIS->setIndirectSymbol(
+ mapConstant(E.Data.GlobalIndirectSymbol.Target));
break;
case WorklistEntry::RemapFunction:
remapFunction(*E.Data.RemapF);
@@ -1041,16 +1041,16 @@ void Mapper::scheduleMapAppendingVariable(GlobalVariable &GV,
AppendingInits.append(NewMembers.begin(), NewMembers.end());
}
-void Mapper::scheduleMapGlobalAliasee(GlobalAlias &GA, Constant &Aliasee,
- unsigned MCID) {
- assert(AlreadyScheduled.insert(&GA).second && "Should not reschedule");
+void Mapper::scheduleMapGlobalIndirectSymbol(GlobalIndirectSymbol &GIS,
+ Constant &Target, unsigned MCID) {
+ assert(AlreadyScheduled.insert(&GIS).second && "Should not reschedule");
assert(MCID < MCs.size() && "Invalid mapping context");
WorklistEntry WE;
- WE.Kind = WorklistEntry::MapGlobalAliasee;
+ WE.Kind = WorklistEntry::MapGlobalIndirectSymbol;
WE.MCID = MCID;
- WE.Data.GlobalAliasee.GA = &GA;
- WE.Data.GlobalAliasee.Aliasee = &Aliasee;
+ WE.Data.GlobalIndirectSymbol.GIS = &GIS;
+ WE.Data.GlobalIndirectSymbol.Target = &Target;
Worklist.push_back(WE);
}
@@ -1147,9 +1147,10 @@ void ValueMapper::scheduleMapAppendingVariable(GlobalVariable &GV,
GV, InitPrefix, IsOldCtorDtor, NewMembers, MCID);
}
-void ValueMapper::scheduleMapGlobalAliasee(GlobalAlias &GA, Constant &Aliasee,
- unsigned MCID) {
- getAsMapper(pImpl)->scheduleMapGlobalAliasee(GA, Aliasee, MCID);
+void ValueMapper::scheduleMapGlobalIndirectSymbol(GlobalIndirectSymbol &GIS,
+ Constant &Target,
+ unsigned MCID) {
+ getAsMapper(pImpl)->scheduleMapGlobalIndirectSymbol(GIS, Target, MCID);
}
void ValueMapper::scheduleRemapFunction(Function &F, unsigned MCID) {
diff --git a/llvm/test/LTO/Resolution/X86/Inputs/ifunc2.ll b/llvm/test/LTO/Resolution/X86/Inputs/ifunc2.ll
new file mode 100644
index 00000000000..a70325bebd6
--- /dev/null
+++ b/llvm/test/LTO/Resolution/X86/Inputs/ifunc2.ll
@@ -0,0 +1,6 @@
+target datalayout = "e-p:64:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+define i32 @foo_resolver() {
+ ret i32 2
+}
diff --git a/llvm/test/LTO/Resolution/X86/ifunc2.ll b/llvm/test/LTO/Resolution/X86/ifunc2.ll
new file mode 100644
index 00000000000..6dd5e598318
--- /dev/null
+++ b/llvm/test/LTO/Resolution/X86/ifunc2.ll
@@ -0,0 +1,19 @@
+; RUN: llvm-as -o %t1.o %s
+; RUN: llvm-as -o %t2.o %S/Inputs/ifunc2.ll
+; RUN: llvm-lto2 run %t1.o %t2.o -r %t1.o,foo,p -r %t1.o,foo_resolver, -r %t2.o,foo_resolver,p -save-temps -o %t3.o
+; RUN: llvm-dis -o - %t3.o.0.0.preopt.bc | FileCheck %s
+
+target datalayout = "e-p:64:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+; CHECK: @foo = ifunc i32 (), i32 ()* @foo_resolver.2
+@foo = ifunc i32 (), i32 ()* @foo_resolver
+
+; CHECK: define internal i32 @foo_resolver.2() {
+; CHECK-NEXT: ret i32 1
+define weak i32 @foo_resolver() {
+ ret i32 1
+}
+
+; CHECK: define i32 @foo_resolver() {
+; CHECK-NEXT: ret i32 2
OpenPOWER on IntegriCloud