xref: /freebsd/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/ObjectLinkingLayer.cpp (revision e8d8bef961a50d4dc22501cde4fb9fb0be1b2532)
10b57cec5SDimitry Andric //===------- ObjectLinkingLayer.cpp - JITLink backed ORC ObjectLayer ------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
100b57cec5SDimitry Andric 
110b57cec5SDimitry Andric #include "llvm/ADT/Optional.h"
120b57cec5SDimitry Andric #include "llvm/ExecutionEngine/JITLink/EHFrameSupport.h"
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include <vector>
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #define DEBUG_TYPE "orc"
170b57cec5SDimitry Andric 
180b57cec5SDimitry Andric using namespace llvm;
190b57cec5SDimitry Andric using namespace llvm::jitlink;
200b57cec5SDimitry Andric using namespace llvm::orc;
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric namespace llvm {
230b57cec5SDimitry Andric namespace orc {
240b57cec5SDimitry Andric 
250b57cec5SDimitry Andric class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
260b57cec5SDimitry Andric public:
27*e8d8bef9SDimitry Andric   ObjectLinkingLayerJITLinkContext(
28*e8d8bef9SDimitry Andric       ObjectLinkingLayer &Layer,
29*e8d8bef9SDimitry Andric       std::unique_ptr<MaterializationResponsibility> MR,
300b57cec5SDimitry Andric       std::unique_ptr<MemoryBuffer> ObjBuffer)
31*e8d8bef9SDimitry Andric       : JITLinkContext(&MR->getTargetJITDylib()), Layer(Layer),
32*e8d8bef9SDimitry Andric         MR(std::move(MR)), ObjBuffer(std::move(ObjBuffer)) {}
330b57cec5SDimitry Andric 
348bcb0991SDimitry Andric   ~ObjectLinkingLayerJITLinkContext() {
358bcb0991SDimitry Andric     // If there is an object buffer return function then use it to
368bcb0991SDimitry Andric     // return ownership of the buffer.
37*e8d8bef9SDimitry Andric     if (Layer.ReturnObjectBuffer && ObjBuffer)
388bcb0991SDimitry Andric       Layer.ReturnObjectBuffer(std::move(ObjBuffer));
398bcb0991SDimitry Andric   }
408bcb0991SDimitry Andric 
41*e8d8bef9SDimitry Andric   JITLinkMemoryManager &getMemoryManager() override { return Layer.MemMgr; }
420b57cec5SDimitry Andric 
430b57cec5SDimitry Andric   void notifyFailed(Error Err) override {
44*e8d8bef9SDimitry Andric     for (auto &P : Layer.Plugins)
45*e8d8bef9SDimitry Andric       Err = joinErrors(std::move(Err), P->notifyFailed(*MR));
460b57cec5SDimitry Andric     Layer.getExecutionSession().reportError(std::move(Err));
47*e8d8bef9SDimitry Andric     MR->failMaterialization();
480b57cec5SDimitry Andric   }
490b57cec5SDimitry Andric 
50480093f4SDimitry Andric   void lookup(const LookupMap &Symbols,
518bcb0991SDimitry Andric               std::unique_ptr<JITLinkAsyncLookupContinuation> LC) override {
520b57cec5SDimitry Andric 
535ffd83dbSDimitry Andric     JITDylibSearchOrder LinkOrder;
54*e8d8bef9SDimitry Andric     MR->getTargetJITDylib().withLinkOrderDo(
555ffd83dbSDimitry Andric         [&](const JITDylibSearchOrder &LO) { LinkOrder = LO; });
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric     auto &ES = Layer.getExecutionSession();
580b57cec5SDimitry Andric 
59480093f4SDimitry Andric     SymbolLookupSet LookupSet;
60480093f4SDimitry Andric     for (auto &KV : Symbols) {
61480093f4SDimitry Andric       orc::SymbolLookupFlags LookupFlags;
62480093f4SDimitry Andric       switch (KV.second) {
63480093f4SDimitry Andric       case jitlink::SymbolLookupFlags::RequiredSymbol:
64480093f4SDimitry Andric         LookupFlags = orc::SymbolLookupFlags::RequiredSymbol;
65480093f4SDimitry Andric         break;
66480093f4SDimitry Andric       case jitlink::SymbolLookupFlags::WeaklyReferencedSymbol:
67480093f4SDimitry Andric         LookupFlags = orc::SymbolLookupFlags::WeaklyReferencedSymbol;
68480093f4SDimitry Andric         break;
69480093f4SDimitry Andric       }
70480093f4SDimitry Andric       LookupSet.add(ES.intern(KV.first), LookupFlags);
71480093f4SDimitry Andric     }
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric     // OnResolve -- De-intern the symbols and pass the result to the linker.
74*e8d8bef9SDimitry Andric     auto OnResolve = [LookupContinuation =
75*e8d8bef9SDimitry Andric                           std::move(LC)](Expected<SymbolMap> Result) mutable {
760b57cec5SDimitry Andric       if (!Result)
778bcb0991SDimitry Andric         LookupContinuation->run(Result.takeError());
780b57cec5SDimitry Andric       else {
790b57cec5SDimitry Andric         AsyncLookupResult LR;
800b57cec5SDimitry Andric         for (auto &KV : *Result)
810b57cec5SDimitry Andric           LR[*KV.first] = KV.second;
828bcb0991SDimitry Andric         LookupContinuation->run(std::move(LR));
830b57cec5SDimitry Andric       }
840b57cec5SDimitry Andric     };
850b57cec5SDimitry Andric 
865ffd83dbSDimitry Andric     for (auto &KV : InternalNamedSymbolDeps) {
875ffd83dbSDimitry Andric       SymbolDependenceMap InternalDeps;
88*e8d8bef9SDimitry Andric       InternalDeps[&MR->getTargetJITDylib()] = std::move(KV.second);
89*e8d8bef9SDimitry Andric       MR->addDependencies(KV.first, InternalDeps);
905ffd83dbSDimitry Andric     }
915ffd83dbSDimitry Andric 
925ffd83dbSDimitry Andric     ES.lookup(LookupKind::Static, LinkOrder, std::move(LookupSet),
93480093f4SDimitry Andric               SymbolState::Resolved, std::move(OnResolve),
94480093f4SDimitry Andric               [this](const SymbolDependenceMap &Deps) {
950b57cec5SDimitry Andric                 registerDependencies(Deps);
960b57cec5SDimitry Andric               });
970b57cec5SDimitry Andric   }
980b57cec5SDimitry Andric 
99*e8d8bef9SDimitry Andric   Error notifyResolved(LinkGraph &G) override {
1000b57cec5SDimitry Andric     auto &ES = Layer.getExecutionSession();
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric     SymbolFlagsMap ExtraSymbolsToClaim;
1030b57cec5SDimitry Andric     bool AutoClaim = Layer.AutoClaimObjectSymbols;
1040b57cec5SDimitry Andric 
1050b57cec5SDimitry Andric     SymbolMap InternedResult;
1068bcb0991SDimitry Andric     for (auto *Sym : G.defined_symbols())
1078bcb0991SDimitry Andric       if (Sym->hasName() && Sym->getScope() != Scope::Local) {
1088bcb0991SDimitry Andric         auto InternedName = ES.intern(Sym->getName());
1090b57cec5SDimitry Andric         JITSymbolFlags Flags;
1100b57cec5SDimitry Andric 
1118bcb0991SDimitry Andric         if (Sym->isCallable())
1120b57cec5SDimitry Andric           Flags |= JITSymbolFlags::Callable;
1138bcb0991SDimitry Andric         if (Sym->getScope() == Scope::Default)
1148bcb0991SDimitry Andric           Flags |= JITSymbolFlags::Exported;
1150b57cec5SDimitry Andric 
1160b57cec5SDimitry Andric         InternedResult[InternedName] =
1178bcb0991SDimitry Andric             JITEvaluatedSymbol(Sym->getAddress(), Flags);
118*e8d8bef9SDimitry Andric         if (AutoClaim && !MR->getSymbols().count(InternedName)) {
1190b57cec5SDimitry Andric           assert(!ExtraSymbolsToClaim.count(InternedName) &&
1200b57cec5SDimitry Andric                  "Duplicate symbol to claim?");
1210b57cec5SDimitry Andric           ExtraSymbolsToClaim[InternedName] = Flags;
1220b57cec5SDimitry Andric         }
1230b57cec5SDimitry Andric       }
1240b57cec5SDimitry Andric 
1258bcb0991SDimitry Andric     for (auto *Sym : G.absolute_symbols())
1268bcb0991SDimitry Andric       if (Sym->hasName()) {
1278bcb0991SDimitry Andric         auto InternedName = ES.intern(Sym->getName());
1280b57cec5SDimitry Andric         JITSymbolFlags Flags;
1290b57cec5SDimitry Andric         Flags |= JITSymbolFlags::Absolute;
1308bcb0991SDimitry Andric         if (Sym->isCallable())
1310b57cec5SDimitry Andric           Flags |= JITSymbolFlags::Callable;
1328bcb0991SDimitry Andric         if (Sym->getLinkage() == Linkage::Weak)
1338bcb0991SDimitry Andric           Flags |= JITSymbolFlags::Weak;
1340b57cec5SDimitry Andric         InternedResult[InternedName] =
1358bcb0991SDimitry Andric             JITEvaluatedSymbol(Sym->getAddress(), Flags);
136*e8d8bef9SDimitry Andric         if (AutoClaim && !MR->getSymbols().count(InternedName)) {
1370b57cec5SDimitry Andric           assert(!ExtraSymbolsToClaim.count(InternedName) &&
1380b57cec5SDimitry Andric                  "Duplicate symbol to claim?");
1390b57cec5SDimitry Andric           ExtraSymbolsToClaim[InternedName] = Flags;
1400b57cec5SDimitry Andric         }
1410b57cec5SDimitry Andric       }
1420b57cec5SDimitry Andric 
1430b57cec5SDimitry Andric     if (!ExtraSymbolsToClaim.empty())
144*e8d8bef9SDimitry Andric       if (auto Err = MR->defineMaterializing(ExtraSymbolsToClaim))
145*e8d8bef9SDimitry Andric         return Err;
1465ffd83dbSDimitry Andric 
1475ffd83dbSDimitry Andric     {
1485ffd83dbSDimitry Andric 
149*e8d8bef9SDimitry Andric       // Check that InternedResult matches up with MR->getSymbols().
1505ffd83dbSDimitry Andric       // This guards against faulty transformations / compilers / object caches.
1515ffd83dbSDimitry Andric 
1525ffd83dbSDimitry Andric       // First check that there aren't any missing symbols.
1535ffd83dbSDimitry Andric       size_t NumMaterializationSideEffectsOnlySymbols = 0;
1545ffd83dbSDimitry Andric       SymbolNameVector ExtraSymbols;
1555ffd83dbSDimitry Andric       SymbolNameVector MissingSymbols;
156*e8d8bef9SDimitry Andric       for (auto &KV : MR->getSymbols()) {
1575ffd83dbSDimitry Andric 
1585ffd83dbSDimitry Andric         // If this is a materialization-side-effects only symbol then bump
1595ffd83dbSDimitry Andric         // the counter and make sure it's *not* defined, otherwise make
1605ffd83dbSDimitry Andric         // sure that it is defined.
1615ffd83dbSDimitry Andric         if (KV.second.hasMaterializationSideEffectsOnly()) {
1625ffd83dbSDimitry Andric           ++NumMaterializationSideEffectsOnlySymbols;
1635ffd83dbSDimitry Andric           if (InternedResult.count(KV.first))
1645ffd83dbSDimitry Andric             ExtraSymbols.push_back(KV.first);
1655ffd83dbSDimitry Andric           continue;
1665ffd83dbSDimitry Andric         } else if (!InternedResult.count(KV.first))
1675ffd83dbSDimitry Andric           MissingSymbols.push_back(KV.first);
1685ffd83dbSDimitry Andric       }
1695ffd83dbSDimitry Andric 
1705ffd83dbSDimitry Andric       // If there were missing symbols then report the error.
171*e8d8bef9SDimitry Andric       if (!MissingSymbols.empty())
172*e8d8bef9SDimitry Andric         return make_error<MissingSymbolDefinitions>(G.getName(),
173*e8d8bef9SDimitry Andric                                                     std::move(MissingSymbols));
1745ffd83dbSDimitry Andric 
1755ffd83dbSDimitry Andric       // If there are more definitions than expected, add them to the
1765ffd83dbSDimitry Andric       // ExtraSymbols vector.
1775ffd83dbSDimitry Andric       if (InternedResult.size() >
178*e8d8bef9SDimitry Andric           MR->getSymbols().size() - NumMaterializationSideEffectsOnlySymbols) {
1795ffd83dbSDimitry Andric         for (auto &KV : InternedResult)
180*e8d8bef9SDimitry Andric           if (!MR->getSymbols().count(KV.first))
1815ffd83dbSDimitry Andric             ExtraSymbols.push_back(KV.first);
1825ffd83dbSDimitry Andric       }
1835ffd83dbSDimitry Andric 
1845ffd83dbSDimitry Andric       // If there were extra definitions then report the error.
185*e8d8bef9SDimitry Andric       if (!ExtraSymbols.empty())
186*e8d8bef9SDimitry Andric         return make_error<UnexpectedSymbolDefinitions>(G.getName(),
187*e8d8bef9SDimitry Andric                                                        std::move(ExtraSymbols));
1885ffd83dbSDimitry Andric     }
1895ffd83dbSDimitry Andric 
190*e8d8bef9SDimitry Andric     if (auto Err = MR->notifyResolved(InternedResult))
191*e8d8bef9SDimitry Andric       return Err;
192*e8d8bef9SDimitry Andric 
193*e8d8bef9SDimitry Andric     Layer.notifyLoaded(*MR);
194*e8d8bef9SDimitry Andric     return Error::success();
1950b57cec5SDimitry Andric   }
1960b57cec5SDimitry Andric 
1970b57cec5SDimitry Andric   void notifyFinalized(
1980b57cec5SDimitry Andric       std::unique_ptr<JITLinkMemoryManager::Allocation> A) override {
199*e8d8bef9SDimitry Andric     if (auto Err = Layer.notifyEmitted(*MR, std::move(A))) {
2000b57cec5SDimitry Andric       Layer.getExecutionSession().reportError(std::move(Err));
201*e8d8bef9SDimitry Andric       MR->failMaterialization();
2020b57cec5SDimitry Andric       return;
2030b57cec5SDimitry Andric     }
204*e8d8bef9SDimitry Andric     if (auto Err = MR->notifyEmitted()) {
2058bcb0991SDimitry Andric       Layer.getExecutionSession().reportError(std::move(Err));
206*e8d8bef9SDimitry Andric       MR->failMaterialization();
2078bcb0991SDimitry Andric     }
2080b57cec5SDimitry Andric   }
2090b57cec5SDimitry Andric 
2108bcb0991SDimitry Andric   LinkGraphPassFunction getMarkLivePass(const Triple &TT) const override {
2118bcb0991SDimitry Andric     return [this](LinkGraph &G) { return markResponsibilitySymbolsLive(G); };
2120b57cec5SDimitry Andric   }
2130b57cec5SDimitry Andric 
2140b57cec5SDimitry Andric   Error modifyPassConfig(const Triple &TT, PassConfiguration &Config) override {
2150b57cec5SDimitry Andric     // Add passes to mark duplicate defs as should-discard, and to walk the
2168bcb0991SDimitry Andric     // link graph to build the symbol dependence graph.
217*e8d8bef9SDimitry Andric     Config.PrePrunePasses.push_back([this](LinkGraph &G) {
218*e8d8bef9SDimitry Andric       return claimOrExternalizeWeakAndCommonSymbols(G);
219*e8d8bef9SDimitry Andric     });
2200b57cec5SDimitry Andric 
221*e8d8bef9SDimitry Andric     Layer.modifyPassConfig(*MR, TT, Config);
2220b57cec5SDimitry Andric 
2235ffd83dbSDimitry Andric     Config.PostPrunePasses.push_back(
2245ffd83dbSDimitry Andric         [this](LinkGraph &G) { return computeNamedSymbolDependencies(G); });
2255ffd83dbSDimitry Andric 
2260b57cec5SDimitry Andric     return Error::success();
2270b57cec5SDimitry Andric   }
2280b57cec5SDimitry Andric 
2290b57cec5SDimitry Andric private:
2305ffd83dbSDimitry Andric   struct LocalSymbolNamedDependencies {
2315ffd83dbSDimitry Andric     SymbolNameSet Internal, External;
2325ffd83dbSDimitry Andric   };
2335ffd83dbSDimitry Andric 
2345ffd83dbSDimitry Andric   using LocalSymbolNamedDependenciesMap =
2355ffd83dbSDimitry Andric       DenseMap<const Symbol *, LocalSymbolNamedDependencies>;
2360b57cec5SDimitry Andric 
237*e8d8bef9SDimitry Andric   Error claimOrExternalizeWeakAndCommonSymbols(LinkGraph &G) {
2380b57cec5SDimitry Andric     auto &ES = Layer.getExecutionSession();
2390b57cec5SDimitry Andric 
240*e8d8bef9SDimitry Andric     SymbolFlagsMap NewSymbolsToClaim;
241*e8d8bef9SDimitry Andric     std::vector<std::pair<SymbolStringPtr, Symbol *>> NameToSym;
242*e8d8bef9SDimitry Andric 
243*e8d8bef9SDimitry Andric     auto ProcessSymbol = [&](Symbol *Sym) {
2448bcb0991SDimitry Andric       if (Sym->hasName() && Sym->getLinkage() == Linkage::Weak) {
245*e8d8bef9SDimitry Andric         auto Name = ES.intern(Sym->getName());
246*e8d8bef9SDimitry Andric         if (!MR->getSymbols().count(ES.intern(Sym->getName()))) {
247*e8d8bef9SDimitry Andric           JITSymbolFlags SF = JITSymbolFlags::Weak;
248*e8d8bef9SDimitry Andric           if (Sym->getScope() == Scope::Default)
249*e8d8bef9SDimitry Andric             SF |= JITSymbolFlags::Exported;
250*e8d8bef9SDimitry Andric           NewSymbolsToClaim[Name] = SF;
251*e8d8bef9SDimitry Andric           NameToSym.push_back(std::make_pair(std::move(Name), Sym));
2520b57cec5SDimitry Andric         }
253*e8d8bef9SDimitry Andric       }
254*e8d8bef9SDimitry Andric     };
255*e8d8bef9SDimitry Andric 
256*e8d8bef9SDimitry Andric     for (auto *Sym : G.defined_symbols())
257*e8d8bef9SDimitry Andric       ProcessSymbol(Sym);
258*e8d8bef9SDimitry Andric     for (auto *Sym : G.absolute_symbols())
259*e8d8bef9SDimitry Andric       ProcessSymbol(Sym);
260*e8d8bef9SDimitry Andric 
261*e8d8bef9SDimitry Andric     // Attempt to claim all weak defs that we're not already responsible for.
262*e8d8bef9SDimitry Andric     // This cannot fail -- any clashes will just result in rejection of our
263*e8d8bef9SDimitry Andric     // claim, at which point we'll externalize that symbol.
264*e8d8bef9SDimitry Andric     cantFail(MR->defineMaterializing(std::move(NewSymbolsToClaim)));
265*e8d8bef9SDimitry Andric 
266*e8d8bef9SDimitry Andric     for (auto &KV : NameToSym)
267*e8d8bef9SDimitry Andric       if (!MR->getSymbols().count(KV.first))
268*e8d8bef9SDimitry Andric         G.makeExternal(*KV.second);
2690b57cec5SDimitry Andric 
2700b57cec5SDimitry Andric     return Error::success();
2710b57cec5SDimitry Andric   }
2720b57cec5SDimitry Andric 
2738bcb0991SDimitry Andric   Error markResponsibilitySymbolsLive(LinkGraph &G) const {
2740b57cec5SDimitry Andric     auto &ES = Layer.getExecutionSession();
2758bcb0991SDimitry Andric     for (auto *Sym : G.defined_symbols())
276*e8d8bef9SDimitry Andric       if (Sym->hasName() && MR->getSymbols().count(ES.intern(Sym->getName())))
2778bcb0991SDimitry Andric         Sym->setLive(true);
2780b57cec5SDimitry Andric     return Error::success();
2790b57cec5SDimitry Andric   }
2800b57cec5SDimitry Andric 
2818bcb0991SDimitry Andric   Error computeNamedSymbolDependencies(LinkGraph &G) {
282*e8d8bef9SDimitry Andric     auto &ES = MR->getTargetJITDylib().getExecutionSession();
2835ffd83dbSDimitry Andric     auto LocalDeps = computeLocalDeps(G);
2840b57cec5SDimitry Andric 
2855ffd83dbSDimitry Andric     // Compute dependencies for symbols defined in the JITLink graph.
2868bcb0991SDimitry Andric     for (auto *Sym : G.defined_symbols()) {
2870b57cec5SDimitry Andric 
2885ffd83dbSDimitry Andric       // Skip local symbols: we do not track dependencies for these.
2898bcb0991SDimitry Andric       if (Sym->getScope() == Scope::Local)
2900b57cec5SDimitry Andric         continue;
2915ffd83dbSDimitry Andric       assert(Sym->hasName() &&
2925ffd83dbSDimitry Andric              "Defined non-local jitlink::Symbol should have a name");
2930b57cec5SDimitry Andric 
2945ffd83dbSDimitry Andric       SymbolNameSet ExternalSymDeps, InternalSymDeps;
2950b57cec5SDimitry Andric 
2965ffd83dbSDimitry Andric       // Find internal and external named symbol dependencies.
2978bcb0991SDimitry Andric       for (auto &E : Sym->getBlock().edges()) {
2988bcb0991SDimitry Andric         auto &TargetSym = E.getTarget();
2990b57cec5SDimitry Andric 
3005ffd83dbSDimitry Andric         if (TargetSym.getScope() != Scope::Local) {
3015ffd83dbSDimitry Andric           if (TargetSym.isExternal())
3025ffd83dbSDimitry Andric             ExternalSymDeps.insert(ES.intern(TargetSym.getName()));
3035ffd83dbSDimitry Andric           else if (&TargetSym != Sym)
3045ffd83dbSDimitry Andric             InternalSymDeps.insert(ES.intern(TargetSym.getName()));
3055ffd83dbSDimitry Andric         } else {
3068bcb0991SDimitry Andric           assert(TargetSym.isDefined() &&
3075ffd83dbSDimitry Andric                  "local symbols must be defined");
3085ffd83dbSDimitry Andric           auto I = LocalDeps.find(&TargetSym);
3095ffd83dbSDimitry Andric           if (I != LocalDeps.end()) {
3105ffd83dbSDimitry Andric             for (auto &S : I->second.External)
3115ffd83dbSDimitry Andric               ExternalSymDeps.insert(S);
3125ffd83dbSDimitry Andric             for (auto &S : I->second.Internal)
3135ffd83dbSDimitry Andric               InternalSymDeps.insert(S);
3145ffd83dbSDimitry Andric           }
3155ffd83dbSDimitry Andric         }
3165ffd83dbSDimitry Andric       }
3175ffd83dbSDimitry Andric 
3185ffd83dbSDimitry Andric       if (ExternalSymDeps.empty() && InternalSymDeps.empty())
3195ffd83dbSDimitry Andric         continue;
3205ffd83dbSDimitry Andric 
3215ffd83dbSDimitry Andric       auto SymName = ES.intern(Sym->getName());
3225ffd83dbSDimitry Andric       if (!ExternalSymDeps.empty())
3235ffd83dbSDimitry Andric         ExternalNamedSymbolDeps[SymName] = std::move(ExternalSymDeps);
3245ffd83dbSDimitry Andric       if (!InternalSymDeps.empty())
3255ffd83dbSDimitry Andric         InternalNamedSymbolDeps[SymName] = std::move(InternalSymDeps);
3265ffd83dbSDimitry Andric     }
3275ffd83dbSDimitry Andric 
3285ffd83dbSDimitry Andric     for (auto &P : Layer.Plugins) {
329*e8d8bef9SDimitry Andric       auto SyntheticLocalDeps = P->getSyntheticSymbolLocalDependencies(*MR);
3305ffd83dbSDimitry Andric       if (SyntheticLocalDeps.empty())
3315ffd83dbSDimitry Andric         continue;
3325ffd83dbSDimitry Andric 
3335ffd83dbSDimitry Andric       for (auto &KV : SyntheticLocalDeps) {
3345ffd83dbSDimitry Andric         auto &Name = KV.first;
3355ffd83dbSDimitry Andric         auto &LocalDepsForName = KV.second;
3365ffd83dbSDimitry Andric         for (auto *Local : LocalDepsForName) {
3375ffd83dbSDimitry Andric           assert(Local->getScope() == Scope::Local &&
3385ffd83dbSDimitry Andric                  "Dependence on non-local symbol");
3395ffd83dbSDimitry Andric           auto LocalNamedDepsItr = LocalDeps.find(Local);
3405ffd83dbSDimitry Andric           if (LocalNamedDepsItr == LocalDeps.end())
3415ffd83dbSDimitry Andric             continue;
3425ffd83dbSDimitry Andric           for (auto &S : LocalNamedDepsItr->second.Internal)
3435ffd83dbSDimitry Andric             InternalNamedSymbolDeps[Name].insert(S);
3445ffd83dbSDimitry Andric           for (auto &S : LocalNamedDepsItr->second.External)
3455ffd83dbSDimitry Andric             ExternalNamedSymbolDeps[Name].insert(S);
3460b57cec5SDimitry Andric         }
3470b57cec5SDimitry Andric       }
3480b57cec5SDimitry Andric     }
3490b57cec5SDimitry Andric 
3500b57cec5SDimitry Andric     return Error::success();
3510b57cec5SDimitry Andric   }
3520b57cec5SDimitry Andric 
3535ffd83dbSDimitry Andric   LocalSymbolNamedDependenciesMap computeLocalDeps(LinkGraph &G) {
3545ffd83dbSDimitry Andric     DenseMap<jitlink::Symbol *, DenseSet<jitlink::Symbol *>> DepMap;
3550b57cec5SDimitry Andric 
3565ffd83dbSDimitry Andric     // For all local symbols:
3570b57cec5SDimitry Andric     // (1) Add their named dependencies.
3580b57cec5SDimitry Andric     // (2) Add them to the worklist for further iteration if they have any
3595ffd83dbSDimitry Andric     //     depend on any other local symbols.
3600b57cec5SDimitry Andric     struct WorklistEntry {
3615ffd83dbSDimitry Andric       WorklistEntry(Symbol *Sym, DenseSet<Symbol *> LocalDeps)
3625ffd83dbSDimitry Andric           : Sym(Sym), LocalDeps(std::move(LocalDeps)) {}
3630b57cec5SDimitry Andric 
3648bcb0991SDimitry Andric       Symbol *Sym = nullptr;
3655ffd83dbSDimitry Andric       DenseSet<Symbol *> LocalDeps;
3660b57cec5SDimitry Andric     };
3670b57cec5SDimitry Andric     std::vector<WorklistEntry> Worklist;
3688bcb0991SDimitry Andric     for (auto *Sym : G.defined_symbols())
3695ffd83dbSDimitry Andric       if (Sym->getScope() == Scope::Local) {
3708bcb0991SDimitry Andric         auto &SymNamedDeps = DepMap[Sym];
3715ffd83dbSDimitry Andric         DenseSet<Symbol *> LocalDeps;
3720b57cec5SDimitry Andric 
3738bcb0991SDimitry Andric         for (auto &E : Sym->getBlock().edges()) {
3748bcb0991SDimitry Andric           auto &TargetSym = E.getTarget();
3755ffd83dbSDimitry Andric           if (TargetSym.getScope() != Scope::Local)
3765ffd83dbSDimitry Andric             SymNamedDeps.insert(&TargetSym);
3770b57cec5SDimitry Andric           else {
3788bcb0991SDimitry Andric             assert(TargetSym.isDefined() &&
3795ffd83dbSDimitry Andric                    "local symbols must be defined");
3805ffd83dbSDimitry Andric             LocalDeps.insert(&TargetSym);
3810b57cec5SDimitry Andric           }
3820b57cec5SDimitry Andric         }
3830b57cec5SDimitry Andric 
3845ffd83dbSDimitry Andric         if (!LocalDeps.empty())
3855ffd83dbSDimitry Andric           Worklist.push_back(WorklistEntry(Sym, std::move(LocalDeps)));
3860b57cec5SDimitry Andric       }
3870b57cec5SDimitry Andric 
3885ffd83dbSDimitry Andric     // Loop over all local symbols with local dependencies, propagating
3895ffd83dbSDimitry Andric     // their respective non-local dependencies. Iterate until we hit a stable
3900b57cec5SDimitry Andric     // state.
3910b57cec5SDimitry Andric     bool Changed;
3920b57cec5SDimitry Andric     do {
3930b57cec5SDimitry Andric       Changed = false;
3940b57cec5SDimitry Andric       for (auto &WLEntry : Worklist) {
3958bcb0991SDimitry Andric         auto *Sym = WLEntry.Sym;
3965ffd83dbSDimitry Andric         auto &NamedDeps = DepMap[Sym];
3975ffd83dbSDimitry Andric         auto &LocalDeps = WLEntry.LocalDeps;
3980b57cec5SDimitry Andric 
3995ffd83dbSDimitry Andric         for (auto *TargetSym : LocalDeps) {
4008bcb0991SDimitry Andric           auto I = DepMap.find(TargetSym);
4010b57cec5SDimitry Andric           if (I != DepMap.end())
4020b57cec5SDimitry Andric             for (const auto &S : I->second)
4035ffd83dbSDimitry Andric               Changed |= NamedDeps.insert(S).second;
4040b57cec5SDimitry Andric         }
4050b57cec5SDimitry Andric       }
4060b57cec5SDimitry Andric     } while (Changed);
4070b57cec5SDimitry Andric 
4085ffd83dbSDimitry Andric     // Intern the results to produce a mapping of jitlink::Symbol* to internal
4095ffd83dbSDimitry Andric     // and external symbol names.
4105ffd83dbSDimitry Andric     auto &ES = Layer.getExecutionSession();
4115ffd83dbSDimitry Andric     LocalSymbolNamedDependenciesMap Result;
4125ffd83dbSDimitry Andric     for (auto &KV : DepMap) {
4135ffd83dbSDimitry Andric       auto *Local = KV.first;
4145ffd83dbSDimitry Andric       assert(Local->getScope() == Scope::Local &&
4155ffd83dbSDimitry Andric              "DepMap keys should all be local symbols");
4165ffd83dbSDimitry Andric       auto &LocalNamedDeps = Result[Local];
4175ffd83dbSDimitry Andric       for (auto *Named : KV.second) {
4185ffd83dbSDimitry Andric         assert(Named->getScope() != Scope::Local &&
4195ffd83dbSDimitry Andric                "DepMap values should all be non-local symbol sets");
4205ffd83dbSDimitry Andric         if (Named->isExternal())
4215ffd83dbSDimitry Andric           LocalNamedDeps.External.insert(ES.intern(Named->getName()));
4225ffd83dbSDimitry Andric         else
4235ffd83dbSDimitry Andric           LocalNamedDeps.Internal.insert(ES.intern(Named->getName()));
4245ffd83dbSDimitry Andric       }
4255ffd83dbSDimitry Andric     }
4265ffd83dbSDimitry Andric 
4275ffd83dbSDimitry Andric     return Result;
4280b57cec5SDimitry Andric   }
4290b57cec5SDimitry Andric 
4300b57cec5SDimitry Andric   void registerDependencies(const SymbolDependenceMap &QueryDeps) {
4315ffd83dbSDimitry Andric     for (auto &NamedDepsEntry : ExternalNamedSymbolDeps) {
4320b57cec5SDimitry Andric       auto &Name = NamedDepsEntry.first;
4330b57cec5SDimitry Andric       auto &NameDeps = NamedDepsEntry.second;
4340b57cec5SDimitry Andric       SymbolDependenceMap SymbolDeps;
4350b57cec5SDimitry Andric 
4360b57cec5SDimitry Andric       for (const auto &QueryDepsEntry : QueryDeps) {
4370b57cec5SDimitry Andric         JITDylib &SourceJD = *QueryDepsEntry.first;
4380b57cec5SDimitry Andric         const SymbolNameSet &Symbols = QueryDepsEntry.second;
4390b57cec5SDimitry Andric         auto &DepsForJD = SymbolDeps[&SourceJD];
4400b57cec5SDimitry Andric 
4410b57cec5SDimitry Andric         for (const auto &S : Symbols)
4420b57cec5SDimitry Andric           if (NameDeps.count(S))
4430b57cec5SDimitry Andric             DepsForJD.insert(S);
4440b57cec5SDimitry Andric 
4450b57cec5SDimitry Andric         if (DepsForJD.empty())
4460b57cec5SDimitry Andric           SymbolDeps.erase(&SourceJD);
4470b57cec5SDimitry Andric       }
4480b57cec5SDimitry Andric 
449*e8d8bef9SDimitry Andric       MR->addDependencies(Name, SymbolDeps);
4500b57cec5SDimitry Andric     }
4510b57cec5SDimitry Andric   }
4520b57cec5SDimitry Andric 
4530b57cec5SDimitry Andric   ObjectLinkingLayer &Layer;
454*e8d8bef9SDimitry Andric   std::unique_ptr<MaterializationResponsibility> MR;
4550b57cec5SDimitry Andric   std::unique_ptr<MemoryBuffer> ObjBuffer;
4565ffd83dbSDimitry Andric   DenseMap<SymbolStringPtr, SymbolNameSet> ExternalNamedSymbolDeps;
4575ffd83dbSDimitry Andric   DenseMap<SymbolStringPtr, SymbolNameSet> InternalNamedSymbolDeps;
4580b57cec5SDimitry Andric };
4590b57cec5SDimitry Andric 
4600b57cec5SDimitry Andric ObjectLinkingLayer::Plugin::~Plugin() {}
4610b57cec5SDimitry Andric 
462*e8d8bef9SDimitry Andric ObjectLinkingLayer::ObjectLinkingLayer(ExecutionSession &ES,
463*e8d8bef9SDimitry Andric                                        JITLinkMemoryManager &MemMgr)
464*e8d8bef9SDimitry Andric     : ObjectLayer(ES), MemMgr(MemMgr) {
465*e8d8bef9SDimitry Andric   ES.registerResourceManager(*this);
4660b57cec5SDimitry Andric }
4670b57cec5SDimitry Andric 
468*e8d8bef9SDimitry Andric ObjectLinkingLayer::ObjectLinkingLayer(
469*e8d8bef9SDimitry Andric     ExecutionSession &ES, std::unique_ptr<JITLinkMemoryManager> MemMgr)
470*e8d8bef9SDimitry Andric     : ObjectLayer(ES), MemMgr(*MemMgr), MemMgrOwnership(std::move(MemMgr)) {
471*e8d8bef9SDimitry Andric   ES.registerResourceManager(*this);
472*e8d8bef9SDimitry Andric }
473*e8d8bef9SDimitry Andric 
474*e8d8bef9SDimitry Andric ObjectLinkingLayer::~ObjectLinkingLayer() {
475*e8d8bef9SDimitry Andric   assert(Allocs.empty() && "Layer destroyed with resources still attached");
476*e8d8bef9SDimitry Andric   getExecutionSession().deregisterResourceManager(*this);
477*e8d8bef9SDimitry Andric }
478*e8d8bef9SDimitry Andric 
479*e8d8bef9SDimitry Andric void ObjectLinkingLayer::emit(std::unique_ptr<MaterializationResponsibility> R,
4800b57cec5SDimitry Andric                               std::unique_ptr<MemoryBuffer> O) {
4810b57cec5SDimitry Andric   assert(O && "Object must not be null");
482*e8d8bef9SDimitry Andric   auto ObjBuffer = O->getMemBufferRef();
483*e8d8bef9SDimitry Andric   auto Ctx = std::make_unique<ObjectLinkingLayerJITLinkContext>(
484*e8d8bef9SDimitry Andric       *this, std::move(R), std::move(O));
485*e8d8bef9SDimitry Andric   if (auto G = createLinkGraphFromObject(std::move(ObjBuffer)))
486*e8d8bef9SDimitry Andric     link(std::move(*G), std::move(Ctx));
487*e8d8bef9SDimitry Andric   else
488*e8d8bef9SDimitry Andric     Ctx->notifyFailed(G.takeError());
489*e8d8bef9SDimitry Andric }
490*e8d8bef9SDimitry Andric 
491*e8d8bef9SDimitry Andric void ObjectLinkingLayer::emit(std::unique_ptr<MaterializationResponsibility> R,
492*e8d8bef9SDimitry Andric                               std::unique_ptr<LinkGraph> G) {
493*e8d8bef9SDimitry Andric   link(std::move(G), std::make_unique<ObjectLinkingLayerJITLinkContext>(
494*e8d8bef9SDimitry Andric                          *this, std::move(R), nullptr));
4950b57cec5SDimitry Andric }
4960b57cec5SDimitry Andric 
4970b57cec5SDimitry Andric void ObjectLinkingLayer::modifyPassConfig(MaterializationResponsibility &MR,
4980b57cec5SDimitry Andric                                           const Triple &TT,
4990b57cec5SDimitry Andric                                           PassConfiguration &PassConfig) {
5000b57cec5SDimitry Andric   for (auto &P : Plugins)
5010b57cec5SDimitry Andric     P->modifyPassConfig(MR, TT, PassConfig);
5020b57cec5SDimitry Andric }
5030b57cec5SDimitry Andric 
5040b57cec5SDimitry Andric void ObjectLinkingLayer::notifyLoaded(MaterializationResponsibility &MR) {
5050b57cec5SDimitry Andric   for (auto &P : Plugins)
5060b57cec5SDimitry Andric     P->notifyLoaded(MR);
5070b57cec5SDimitry Andric }
5080b57cec5SDimitry Andric 
5090b57cec5SDimitry Andric Error ObjectLinkingLayer::notifyEmitted(MaterializationResponsibility &MR,
5100b57cec5SDimitry Andric                                         AllocPtr Alloc) {
5110b57cec5SDimitry Andric   Error Err = Error::success();
5120b57cec5SDimitry Andric   for (auto &P : Plugins)
5130b57cec5SDimitry Andric     Err = joinErrors(std::move(Err), P->notifyEmitted(MR));
5140b57cec5SDimitry Andric 
5150b57cec5SDimitry Andric   if (Err)
5160b57cec5SDimitry Andric     return Err;
5170b57cec5SDimitry Andric 
518*e8d8bef9SDimitry Andric   return MR.withResourceKeyDo(
519*e8d8bef9SDimitry Andric       [&](ResourceKey K) { Allocs[K].push_back(std::move(Alloc)); });
5200b57cec5SDimitry Andric }
5210b57cec5SDimitry Andric 
522*e8d8bef9SDimitry Andric Error ObjectLinkingLayer::handleRemoveResources(ResourceKey K) {
5230b57cec5SDimitry Andric 
5240b57cec5SDimitry Andric   Error Err = Error::success();
5250b57cec5SDimitry Andric 
5260b57cec5SDimitry Andric   for (auto &P : Plugins)
527*e8d8bef9SDimitry Andric     Err = joinErrors(std::move(Err), P->notifyRemovingResources(K));
5280b57cec5SDimitry Andric 
529*e8d8bef9SDimitry Andric   std::vector<AllocPtr> AllocsToRemove;
530*e8d8bef9SDimitry Andric   getExecutionSession().runSessionLocked([&] {
531*e8d8bef9SDimitry Andric     auto I = Allocs.find(K);
532*e8d8bef9SDimitry Andric     if (I != Allocs.end()) {
533*e8d8bef9SDimitry Andric       std::swap(AllocsToRemove, I->second);
534*e8d8bef9SDimitry Andric       Allocs.erase(I);
5350b57cec5SDimitry Andric     }
536*e8d8bef9SDimitry Andric   });
5370b57cec5SDimitry Andric 
538*e8d8bef9SDimitry Andric   while (!AllocsToRemove.empty()) {
539*e8d8bef9SDimitry Andric     Err = joinErrors(std::move(Err), AllocsToRemove.back()->deallocate());
540*e8d8bef9SDimitry Andric     AllocsToRemove.pop_back();
5410b57cec5SDimitry Andric   }
5420b57cec5SDimitry Andric 
5430b57cec5SDimitry Andric   return Err;
5440b57cec5SDimitry Andric }
5450b57cec5SDimitry Andric 
546*e8d8bef9SDimitry Andric void ObjectLinkingLayer::handleTransferResources(ResourceKey DstKey,
547*e8d8bef9SDimitry Andric                                                  ResourceKey SrcKey) {
548*e8d8bef9SDimitry Andric   auto I = Allocs.find(SrcKey);
549*e8d8bef9SDimitry Andric   if (I != Allocs.end()) {
550*e8d8bef9SDimitry Andric     auto &SrcAllocs = I->second;
551*e8d8bef9SDimitry Andric     auto &DstAllocs = Allocs[DstKey];
552*e8d8bef9SDimitry Andric     DstAllocs.reserve(DstAllocs.size() + SrcAllocs.size());
553*e8d8bef9SDimitry Andric     for (auto &Alloc : SrcAllocs)
554*e8d8bef9SDimitry Andric       DstAllocs.push_back(std::move(Alloc));
555*e8d8bef9SDimitry Andric 
556*e8d8bef9SDimitry Andric     // Erase SrcKey entry using value rather than iterator I: I may have been
557*e8d8bef9SDimitry Andric     // invalidated when we looked up DstKey.
558*e8d8bef9SDimitry Andric     Allocs.erase(SrcKey);
559*e8d8bef9SDimitry Andric   }
560*e8d8bef9SDimitry Andric 
561*e8d8bef9SDimitry Andric   for (auto &P : Plugins)
562*e8d8bef9SDimitry Andric     P->notifyTransferringResources(DstKey, SrcKey);
563*e8d8bef9SDimitry Andric }
564*e8d8bef9SDimitry Andric 
5650b57cec5SDimitry Andric EHFrameRegistrationPlugin::EHFrameRegistrationPlugin(
566*e8d8bef9SDimitry Andric     ExecutionSession &ES, std::unique_ptr<EHFrameRegistrar> Registrar)
567*e8d8bef9SDimitry Andric     : ES(ES), Registrar(std::move(Registrar)) {}
5680b57cec5SDimitry Andric 
5690b57cec5SDimitry Andric void EHFrameRegistrationPlugin::modifyPassConfig(
5700b57cec5SDimitry Andric     MaterializationResponsibility &MR, const Triple &TT,
5710b57cec5SDimitry Andric     PassConfiguration &PassConfig) {
5720b57cec5SDimitry Andric 
5735ffd83dbSDimitry Andric   PassConfig.PostFixupPasses.push_back(createEHFrameRecorderPass(
5745ffd83dbSDimitry Andric       TT, [this, &MR](JITTargetAddress Addr, size_t Size) {
5755ffd83dbSDimitry Andric         if (Addr) {
5765ffd83dbSDimitry Andric           std::lock_guard<std::mutex> Lock(EHFramePluginMutex);
5775ffd83dbSDimitry Andric           assert(!InProcessLinks.count(&MR) &&
5785ffd83dbSDimitry Andric                  "Link for MR already being tracked?");
5798bcb0991SDimitry Andric           InProcessLinks[&MR] = {Addr, Size};
5805ffd83dbSDimitry Andric         }
5810b57cec5SDimitry Andric       }));
5820b57cec5SDimitry Andric }
5830b57cec5SDimitry Andric 
5840b57cec5SDimitry Andric Error EHFrameRegistrationPlugin::notifyEmitted(
5850b57cec5SDimitry Andric     MaterializationResponsibility &MR) {
586*e8d8bef9SDimitry Andric 
587*e8d8bef9SDimitry Andric   EHFrameRange EmittedRange;
588*e8d8bef9SDimitry Andric   {
5895ffd83dbSDimitry Andric     std::lock_guard<std::mutex> Lock(EHFramePluginMutex);
5900b57cec5SDimitry Andric 
5918bcb0991SDimitry Andric     auto EHFrameRangeItr = InProcessLinks.find(&MR);
5928bcb0991SDimitry Andric     if (EHFrameRangeItr == InProcessLinks.end())
5930b57cec5SDimitry Andric       return Error::success();
5940b57cec5SDimitry Andric 
595*e8d8bef9SDimitry Andric     EmittedRange = EHFrameRangeItr->second;
596*e8d8bef9SDimitry Andric     assert(EmittedRange.Addr && "eh-frame addr to register can not be null");
5978bcb0991SDimitry Andric     InProcessLinks.erase(EHFrameRangeItr);
5980b57cec5SDimitry Andric   }
5990b57cec5SDimitry Andric 
600*e8d8bef9SDimitry Andric   if (auto Err = MR.withResourceKeyDo(
601*e8d8bef9SDimitry Andric           [&](ResourceKey K) { EHFrameRanges[K].push_back(EmittedRange); }))
602*e8d8bef9SDimitry Andric     return Err;
6035ffd83dbSDimitry Andric 
604*e8d8bef9SDimitry Andric   return Registrar->registerEHFrames(EmittedRange.Addr, EmittedRange.Size);
605*e8d8bef9SDimitry Andric }
606*e8d8bef9SDimitry Andric 
607*e8d8bef9SDimitry Andric Error EHFrameRegistrationPlugin::notifyFailed(
608*e8d8bef9SDimitry Andric     MaterializationResponsibility &MR) {
609*e8d8bef9SDimitry Andric   std::lock_guard<std::mutex> Lock(EHFramePluginMutex);
610*e8d8bef9SDimitry Andric   InProcessLinks.erase(&MR);
6110b57cec5SDimitry Andric   return Error::success();
6120b57cec5SDimitry Andric }
6130b57cec5SDimitry Andric 
614*e8d8bef9SDimitry Andric Error EHFrameRegistrationPlugin::notifyRemovingResources(ResourceKey K) {
615*e8d8bef9SDimitry Andric   std::vector<EHFrameRange> RangesToRemove;
6160b57cec5SDimitry Andric 
617*e8d8bef9SDimitry Andric   ES.runSessionLocked([&] {
618*e8d8bef9SDimitry Andric     auto I = EHFrameRanges.find(K);
619*e8d8bef9SDimitry Andric     if (I != EHFrameRanges.end()) {
620*e8d8bef9SDimitry Andric       RangesToRemove = std::move(I->second);
621*e8d8bef9SDimitry Andric       EHFrameRanges.erase(I);
622*e8d8bef9SDimitry Andric     }
623*e8d8bef9SDimitry Andric   });
6240b57cec5SDimitry Andric 
6250b57cec5SDimitry Andric   Error Err = Error::success();
626*e8d8bef9SDimitry Andric   while (!RangesToRemove.empty()) {
627*e8d8bef9SDimitry Andric     auto RangeToRemove = RangesToRemove.back();
628*e8d8bef9SDimitry Andric     RangesToRemove.pop_back();
629*e8d8bef9SDimitry Andric     assert(RangeToRemove.Addr && "Untracked eh-frame range must not be null");
630*e8d8bef9SDimitry Andric     Err = joinErrors(
631*e8d8bef9SDimitry Andric         std::move(Err),
632*e8d8bef9SDimitry Andric         Registrar->deregisterEHFrames(RangeToRemove.Addr, RangeToRemove.Size));
6330b57cec5SDimitry Andric   }
6340b57cec5SDimitry Andric 
6350b57cec5SDimitry Andric   return Err;
6360b57cec5SDimitry Andric }
6370b57cec5SDimitry Andric 
638*e8d8bef9SDimitry Andric void EHFrameRegistrationPlugin::notifyTransferringResources(
639*e8d8bef9SDimitry Andric     ResourceKey DstKey, ResourceKey SrcKey) {
640*e8d8bef9SDimitry Andric   auto SI = EHFrameRanges.find(SrcKey);
641*e8d8bef9SDimitry Andric   if (SI != EHFrameRanges.end()) {
642*e8d8bef9SDimitry Andric     auto &SrcRanges = SI->second;
643*e8d8bef9SDimitry Andric     auto &DstRanges = EHFrameRanges[DstKey];
644*e8d8bef9SDimitry Andric     DstRanges.reserve(DstRanges.size() + SrcRanges.size());
645*e8d8bef9SDimitry Andric     for (auto &SrcRange : SrcRanges)
646*e8d8bef9SDimitry Andric       DstRanges.push_back(std::move(SrcRange));
647*e8d8bef9SDimitry Andric     EHFrameRanges.erase(SI);
648*e8d8bef9SDimitry Andric   }
649*e8d8bef9SDimitry Andric }
650*e8d8bef9SDimitry Andric 
6510b57cec5SDimitry Andric } // End namespace orc.
6520b57cec5SDimitry Andric } // End namespace llvm.
653