Line data Source code
1 : //===-------------------- Layer.cpp - Layer interfaces --------------------===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 :
10 : #include "llvm/ExecutionEngine/Orc/Layer.h"
11 : #include "llvm/Object/ObjectFile.h"
12 : #include "llvm/Support/Debug.h"
13 :
14 : #define DEBUG_TYPE "orc"
15 :
16 : namespace llvm {
17 : namespace orc {
18 :
19 41 : IRLayer::IRLayer(ExecutionSession &ES) : ES(ES) {}
20 38 : IRLayer::~IRLayer() {}
21 :
22 16 : Error IRLayer::add(JITDylib &JD, ThreadSafeModule TSM, VModuleKey K) {
23 16 : return JD.define(llvm::make_unique<BasicIRLayerMaterializationUnit>(
24 16 : *this, std::move(K), std::move(TSM)));
25 : }
26 :
27 52 : IRMaterializationUnit::IRMaterializationUnit(ExecutionSession &ES,
28 52 : ThreadSafeModule TSM, VModuleKey K)
29 104 : : MaterializationUnit(SymbolFlagsMap(), std::move(K)), TSM(std::move(TSM)) {
30 :
31 : assert(this->TSM && "Module must not be null");
32 :
33 52 : MangleAndInterner Mangle(ES, this->TSM.getModule()->getDataLayout());
34 299 : for (auto &G : this->TSM.getModule()->global_values()) {
35 279 : if (G.hasName() && !G.isDeclaration() && !G.hasLocalLinkage() &&
36 281 : !G.hasAvailableExternallyLinkage() && !G.hasAppendingLinkage()) {
37 83 : auto MangledName = Mangle(G.getName());
38 83 : SymbolFlags[MangledName] = JITSymbolFlags::fromGlobalValue(G);
39 83 : SymbolToDefinition[MangledName] = &G;
40 : }
41 : }
42 52 : }
43 :
44 0 : IRMaterializationUnit::IRMaterializationUnit(
45 : ThreadSafeModule TSM, VModuleKey K, SymbolFlagsMap SymbolFlags,
46 0 : SymbolNameToDefinitionMap SymbolToDefinition)
47 : : MaterializationUnit(std::move(SymbolFlags), std::move(K)),
48 0 : TSM(std::move(TSM)), SymbolToDefinition(std::move(SymbolToDefinition)) {}
49 :
50 0 : StringRef IRMaterializationUnit::getName() const {
51 0 : if (TSM.getModule())
52 0 : return TSM.getModule()->getModuleIdentifier();
53 0 : return "<null module>";
54 : }
55 :
56 1 : void IRMaterializationUnit::discard(const JITDylib &JD,
57 : const SymbolStringPtr &Name) {
58 : LLVM_DEBUG(JD.getExecutionSession().runSessionLocked([&]() {
59 : dbgs() << "In " << JD.getName() << " discarding " << *Name << " from MU@"
60 : << this << " (" << getName() << ")\n";
61 : }););
62 :
63 : auto I = SymbolToDefinition.find(Name);
64 : assert(I != SymbolToDefinition.end() &&
65 : "Symbol not provided by this MU, or previously discarded");
66 : assert(!I->second->isDeclaration() &&
67 : "Discard should only apply to definitions");
68 1 : I->second->setLinkage(GlobalValue::AvailableExternallyLinkage);
69 : SymbolToDefinition.erase(I);
70 1 : }
71 :
72 16 : BasicIRLayerMaterializationUnit::BasicIRLayerMaterializationUnit(
73 16 : IRLayer &L, VModuleKey K, ThreadSafeModule TSM)
74 : : IRMaterializationUnit(L.getExecutionSession(), std::move(TSM),
75 : std::move(K)),
76 32 : L(L), K(std::move(K)) {}
77 :
78 15 : void BasicIRLayerMaterializationUnit::materialize(
79 : MaterializationResponsibility R) {
80 :
81 : // Throw away the SymbolToDefinition map: it's not usable after we hand
82 : // off the module.
83 : SymbolToDefinition.clear();
84 :
85 : // If cloneToNewContextOnEmit is set, clone the module now.
86 15 : if (L.getCloneToNewContextOnEmit())
87 2 : TSM = cloneToNewContext(TSM);
88 :
89 : #ifndef NDEBUG
90 : auto &ES = R.getTargetJITDylib().getExecutionSession();
91 : #endif // NDEBUG
92 :
93 15 : auto Lock = TSM.getContextLock();
94 : LLVM_DEBUG(ES.runSessionLocked([&]() {
95 : dbgs() << "Emitting, for " << R.getTargetJITDylib().getName() << ", "
96 : << *this << "\n";
97 : }););
98 30 : L.emit(std::move(R), std::move(TSM));
99 : LLVM_DEBUG(ES.runSessionLocked([&]() {
100 : dbgs() << "Finished emitting, for " << R.getTargetJITDylib().getName()
101 : << ", " << *this << "\n";
102 : }););
103 15 : }
104 :
105 17 : ObjectLayer::ObjectLayer(ExecutionSession &ES) : ES(ES) {}
106 :
107 16 : ObjectLayer::~ObjectLayer() {}
108 :
109 6 : Error ObjectLayer::add(JITDylib &JD, std::unique_ptr<MemoryBuffer> O,
110 : VModuleKey K) {
111 : auto ObjMU = BasicObjectLayerMaterializationUnit::Create(*this, std::move(K),
112 18 : std::move(O));
113 6 : if (!ObjMU)
114 : return ObjMU.takeError();
115 5 : return JD.define(std::move(*ObjMU));
116 : }
117 :
118 : Expected<std::unique_ptr<BasicObjectLayerMaterializationUnit>>
119 6 : BasicObjectLayerMaterializationUnit::Create(ObjectLayer &L, VModuleKey K,
120 : std::unique_ptr<MemoryBuffer> O) {
121 : auto SymbolFlags =
122 12 : getObjectSymbolFlags(L.getExecutionSession(), O->getMemBufferRef());
123 :
124 6 : if (!SymbolFlags)
125 : return SymbolFlags.takeError();
126 :
127 5 : return std::unique_ptr<BasicObjectLayerMaterializationUnit>(
128 : new BasicObjectLayerMaterializationUnit(L, K, std::move(O),
129 5 : std::move(*SymbolFlags)));
130 : }
131 :
132 5 : BasicObjectLayerMaterializationUnit::BasicObjectLayerMaterializationUnit(
133 : ObjectLayer &L, VModuleKey K, std::unique_ptr<MemoryBuffer> O,
134 5 : SymbolFlagsMap SymbolFlags)
135 : : MaterializationUnit(std::move(SymbolFlags), std::move(K)), L(L),
136 10 : O(std::move(O)) {}
137 :
138 0 : StringRef BasicObjectLayerMaterializationUnit::getName() const {
139 0 : if (O)
140 0 : return O->getBufferIdentifier();
141 0 : return "<null object>";
142 : }
143 :
144 5 : void BasicObjectLayerMaterializationUnit::materialize(
145 : MaterializationResponsibility R) {
146 10 : L.emit(std::move(R), std::move(O));
147 5 : }
148 :
149 1 : void BasicObjectLayerMaterializationUnit::discard(const JITDylib &JD,
150 : const SymbolStringPtr &Name) {
151 : // FIXME: Support object file level discard. This could be done by building a
152 : // filter to pass to the object layer along with the object itself.
153 1 : }
154 :
155 6 : Expected<SymbolFlagsMap> getObjectSymbolFlags(ExecutionSession &ES,
156 : MemoryBufferRef ObjBuffer) {
157 12 : auto Obj = object::ObjectFile::createObjectFile(ObjBuffer);
158 :
159 6 : if (!Obj)
160 : return Obj.takeError();
161 :
162 : SymbolFlagsMap SymbolFlags;
163 23 : for (auto &Sym : (*Obj)->symbols()) {
164 : // Skip symbols not defined in this object file.
165 18 : if (Sym.getFlags() & object::BasicSymbolRef::SF_Undefined)
166 12 : continue;
167 :
168 : // Skip symbols that are not global.
169 13 : if (!(Sym.getFlags() & object::BasicSymbolRef::SF_Global))
170 : continue;
171 :
172 : auto Name = Sym.getName();
173 6 : if (!Name)
174 : return Name.takeError();
175 6 : auto InternedName = ES.intern(*Name);
176 6 : auto SymFlags = JITSymbolFlags::fromObjectSymbol(Sym);
177 6 : if (!SymFlags)
178 : return SymFlags.takeError();
179 6 : SymbolFlags[InternedName] = std::move(*SymFlags);
180 : }
181 :
182 : return SymbolFlags;
183 : }
184 :
185 : } // End namespace orc.
186 : } // End namespace llvm.
|