Go to the documentation of this file.
29 if (isa<Function>(GV)) {
30 auto &
F = cast<Function>(GV);
32 F.setPersonalityFn(
nullptr);
33 }
else if (isa<GlobalVariable>(GV)) {
34 cast<GlobalVariable>(GV).setInitializer(
nullptr);
35 }
else if (isa<GlobalAlias>(GV)) {
38 auto &
A = cast<GlobalAlias>(GV);
40 assert(
A.hasName() &&
"Anonymous alias?");
42 std::string AliasName = std::string(
A.getName());
44 if (isa<Function>(Aliasee)) {
46 A.replaceAllUsesWith(
F);
48 F->setName(AliasName);
49 }
else if (isa<GlobalVariable>(Aliasee)) {
51 *cast<GlobalVariable>(Aliasee));
52 A.replaceAllUsesWith(
G);
54 G->setName(AliasName);
62 NewTSM.withModuleDo([&](
Module &
M) {
63 M.setModuleIdentifier((
M.getModuleIdentifier() + Suffix).str());
89 void materialize(std::unique_ptr<MaterializationResponsibility> R)
override {
98 "ExtractingIRMaterializationUnit");
101 mutable std::mutex SourceModuleMutex;
118 :
IRLayer(ES, BaseLayer.getManglingOptions()), BaseLayer(BaseLayer),
120 BuildIndirectStubsManager(
std::
move(BuildIndirectStubsManager)) {}
127 this->AliaseeImpls = Imp;
131 assert(TSM &&
"Null module");
137 auto &PDR = getPerDylibResources(R->getTargetJITDylib());
146 for (
auto &KV : R->getSymbols()) {
147 auto &
Name = KV.first;
148 auto &Flags = KV.second;
149 if (Flags.isCallable())
157 if (
auto Err = PDR.getImplDylib().define(
158 std::make_unique<PartitioningIRMaterializationUnit>(
161 R->failMaterialization();
165 if (!NonCallables.
empty())
170 R->failMaterialization();
173 if (!Callables.
empty()) {
174 if (
auto Err = R->replace(
175 lazyReexports(LCTMgr, PDR.getISManager(), PDR.getImplDylib(),
178 R->failMaterialization();
184 CompileOnDemandLayer::PerDylibResources &
185 CompileOnDemandLayer::getPerDylibResources(
JITDylib &TargetD) {
186 std::lock_guard<std::mutex>
Lock(CODLayerMutex);
188 auto I = DylibResources.find(&TargetD);
189 if (
I == DylibResources.end()) {
194 NewLinkOrder = TargetLinkOrder;
197 assert(!NewLinkOrder.empty() && NewLinkOrder.front().first == &TargetD &&
198 NewLinkOrder.front().second ==
200 "TargetD must be at the front of its own search order and match "
201 "non-exported symbol");
202 NewLinkOrder.insert(std::next(NewLinkOrder.begin()),
203 {&ImplD, JITDylibLookupFlags::MatchAllSymbols});
204 ImplD.setLinkOrder(NewLinkOrder,
false);
207 PerDylibResources PDR(ImplD, BuildIndirectStubsManager());
208 I = DylibResources.insert(std::make_pair(&TargetD,
std::move(PDR))).first;
214 void CompileOnDemandLayer::cleanUpModule(
Module &M) {
215 for (
auto &
F :
M.functions()) {
216 if (
F.isDeclaration())
219 if (
F.hasAvailableExternallyLinkage()) {
221 F.setPersonalityFn(
nullptr);
227 void CompileOnDemandLayer::expandPartition(GlobalValueSet &Partition) {
234 assert(!Partition.empty() &&
"Unexpected empty partition");
237 bool ContainsGlobalVariables =
false;
238 std::vector<const GlobalValue *> GVsToAdd;
240 for (
auto *GV : Partition)
241 if (isa<GlobalAlias>(GV))
243 cast<GlobalValue>(cast<GlobalAlias>(GV)->getAliasee()));
244 else if (isa<GlobalVariable>(GV))
245 ContainsGlobalVariables =
true;
247 for (
auto &A :
M.aliases())
248 if (Partition.count(cast<GlobalValue>(
A.getAliasee())))
249 GVsToAdd.push_back(&A);
251 if (ContainsGlobalVariables)
252 for (
auto &
G :
M.globals())
253 GVsToAdd.push_back(&
G);
255 for (
auto *GV : GVsToAdd)
256 Partition.insert(GV);
259 void CompileOnDemandLayer::emitPartition(
270 for (
auto &
Name :
R->getRequestedSymbols()) {
271 if (
Name ==
R->getInitializerSymbol())
274 RequestedGVs.insert(&GV);
277 assert(Defs.count(
Name) &&
"No definition for symbol");
278 RequestedGVs.insert(Defs[
Name]);
290 if (GVsToExtract == None) {
297 if (GVsToExtract->empty()) {
299 R->replace(std::make_unique<PartitioningIRMaterializationUnit>(
302 R->getInitializerSymbol()),
305 R->failMaterialization();
320 auto PromotedGlobals = PromoteSymbols(M);
321 if (!PromotedGlobals.empty()) {
332 expandPartition(*GVsToExtract);
335 std::string SubModuleName;
337 std::vector<const GlobalValue*> HashGVs;
338 HashGVs.reserve(GVsToExtract->size());
339 for (
auto *GV : *GVsToExtract)
340 HashGVs.push_back(GV);
345 for (
auto *GV : HashGVs) {
346 assert(GV->hasName() &&
"All GVs to extract should be named by now");
347 auto GVName = GV->getName();
352 <<
formatv(
sizeof(
size_t) == 8 ?
"{0:x16}" :
"{0:x8}",
353 static_cast<size_t>(HC))
359 auto ShouldExtract = [&](
const GlobalValue &GV) ->
bool {
360 return GVsToExtract->count(&GV);
367 ES.reportError(ExtractedTSM.takeError());
368 R->failMaterialization();
372 if (
auto Err =
R->replace(std::make_unique<PartitioningIRMaterializationUnit>(
375 R->failMaterialization();
static void add(ExecutionSession &ES, const ManglingOptions &MO, ArrayRef< GlobalValue * > GVs, SymbolFlagsMap &SymbolFlags, SymbolNameToDefinitionMap *SymbolToDefinition=nullptr)
Add mangled symbols for the given GlobalValues to SymbolFlags.
auto withLinkOrderDo(Func &&F) -> decltype(F(std::declval< const JITDylibSearchOrder & >()))
Do something with the link order (run under the session lock).
This is an optimization pass for GlobalISel generic memory operations.
Represents a JIT'd dynamic library.
void setImplMap(ImplSymbolMap *Imp)
Sets the ImplSymbolMap.
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
void setLinkOrder(JITDylibSearchOrder NewSearchOrder, bool LinkAgainstThisJITDylibFirst=true)
Set the link order to be used when fixing up definitions in JITDylib.
IRMaterializationUnit is a convenient base class for MaterializationUnits wrapping LLVM IR.
void reportError(Error Err)
Report a error for this execution session.
CompileOnDemandLayer(ExecutionSession &ES, IRLayer &BaseLayer, LazyCallThroughManager &LCTMgr, IndirectStubsManagerBuilder BuildIndirectStubsManager)
Construct a CompileOnDemandLayer.
A raw_ostream that writes to an std::string.
void setPartitionFunction(PartitionFunction Partition)
Sets the partition function.
const std::string & getName() const
Get the name for this JITLinkDylib.
Pointer to a pooled string representing a symbol name.
Manages a set of 'lazy call-through' trampolines.
static Optional< GlobalValueSet > compileRequested(GlobalValueSet Requested)
Off-the-shelf partitioning which compiles all requested symbols (usually a single function at a time)...
const IRSymbolMapper::ManglingOptions *& getManglingOptions() const
Get the mangling options for this layer.
std::unique_ptr< LazyReexportsMaterializationUnit > lazyReexports(LazyCallThroughManager &LCTManager, IndirectStubsManager &ISManager, JITDylib &SourceJD, SymbolAliasMap CallableAliases, ImplSymbolMap *SrcJDLoc=nullptr)
Define lazy-reexports based on the given SymbolAliasMap.
Tagged union holding either a T or a Error.
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
std::function< Optional< GlobalValueSet >(GlobalValueSet Requested)> PartitionFunction
Partitioning function.
GlobalVariable * cloneGlobalVariableDecl(Module &Dst, const GlobalVariable &GV, ValueToValueMapTy *VMap=nullptr)
Clone a global variable declaration into a new module.
static ThreadSafeModule extractSubModule(ThreadSafeModule &TSM, StringRef Suffix, GVPredicate ShouldExtract)
iterator_range< StaticInitGVIterator > getStaticInitGVs(Module &M)
Create an iterator range over the GlobalValues that contribute to static initialization.
JITDylib & createBareJITDylib(std::string Name)
Add a new bare JITDylib to this ExecutionSession.
virtual void emit(std::unique_ptr< MaterializationResponsibility > R, ThreadSafeModule TSM)=0
Emit should materialize the given IR.
This is an important base class in LLVM.
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
std::vector< std::pair< JITDylib *, JITDylibLookupFlags > > JITDylibSearchOrder
A list of (JITDylib*, JITDylibLookupFlags) pairs to be used as a search order during symbol lookup.
A Module instance is used to store all the information related to an LLVM module.
ExecutionSession & getExecutionSession()
Returns the ExecutionSession for this layer.
std::set< const GlobalValue * > GlobalValueSet
std::unique_ptr< ReExportsMaterializationUnit > reexports(JITDylib &SourceJD, SymbolAliasMap Aliases, JITDylibLookupFlags SourceJDLookupFlags=JITDylibLookupFlags::MatchExportedSymbolsOnly)
Create a materialization unit for re-exporting symbols from another JITDylib with alternative names/f...
decltype(auto) withModuleDo(Func &&F)
Locks the associated ThreadSafeContext and calls the given function on the contained Module.
StringRef - Represent a constant reference to a string, i.e.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static const Function * getParent(const Value *V)
Function * cloneFunctionDecl(Module &Dst, const Function &F, ValueToValueMapTy *VMap=nullptr)
Clone a function declaration into a new module.
StringRef getName() const
Return a constant reference to the value's name.
Mangles symbol names then uniques them in the context of an ExecutionSession.
LLVM_NODISCARD bool empty() const
std::function< bool(const GlobalValue &)> GVPredicate
std::function< std::unique_ptr< IndirectStubsManager >()> IndirectStubsManagerBuilder
Builder for IndirectStubsManagers.
An ExecutionSession represents a running JIT program.
static Optional< GlobalValueSet > compileWholeModule(GlobalValueSet Requested)
Off-the-shelf partitioning which compiles whole modules whenever any symbol in them is requested.
void sort(IteratorTy Start, IteratorTy End)
void emit(std::unique_ptr< MaterializationResponsibility > R, ThreadSafeModule TSM) override
Emits the given module.
@ ExternalLinkage
Externally visible function.
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
hash_code hash_combine_range(InputIteratorT first, InputIteratorT last)
Compute a hash_code for a sequence of values.
An LLVM Module together with a shared ThreadSafeContext.
std::map< SymbolStringPtr, GlobalValue * > SymbolNameToDefinitionMap
Interface for layers that accept LLVM IR.
PartitioningIRMaterializationUnit(ThreadSafeModule TSM, Interface I, SymbolNameToDefinitionMap SymbolToDefinition, CompileOnDemandLayer &Parent)
PartitioningIRMaterializationUnit(ExecutionSession &ES, const IRSymbolMapper::ManglingOptions &MO, ThreadSafeModule TSM, CompileOnDemandLayer &Parent)
An opaque object representing a hash code.
ThreadSafeModule cloneToNewContext(const ThreadSafeModule &TSMW, GVPredicate ShouldCloneDef=GVPredicate(), GVModifier UpdateClonedDefSource=GVModifier())
Clones the given module on to a new context.