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/IR/Mangler.h"
12 #include "llvm/Object/ObjectFile.h"
13 #include "llvm/Support/MemoryBuffer.h"
14 
15 namespace llvm {
16 namespace orc {
17 
18 MangleAndInterner::MangleAndInterner(ExecutionSession &ES, const DataLayout &DL)
19     : ES(ES), DL(DL) {}
20 
21 SymbolStringPtr MangleAndInterner::operator()(StringRef Name) {
22   std::string MangledName;
23   {
24     raw_string_ostream MangledNameStream(MangledName);
25     Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
26   }
27   return ES.getSymbolStringPool().intern(MangledName);
28 }
29 
30 IRLayer::IRLayer(ExecutionSession &ES) : ES(ES) {}
31 IRLayer::~IRLayer() {}
32 
33 Error IRLayer::add(VSO &V, VModuleKey K, std::unique_ptr<Module> M) {
34   return V.define(llvm::make_unique<BasicIRLayerMaterializationUnit>(
35       *this, std::move(K), std::move(M)));
36 }
37 
38 IRMaterializationUnit::IRMaterializationUnit(ExecutionSession &ES,
39                                              std::unique_ptr<Module> M)
40   : MaterializationUnit(SymbolFlagsMap()), M(std::move(M)) {
41 
42   MangleAndInterner Mangle(ES, this->M->getDataLayout());
43   for (auto &G : this->M->global_values()) {
44     if (G.hasName() && !G.isDeclaration() &&
45         !G.hasLocalLinkage() &&
46         !G.hasAvailableExternallyLinkage()) {
47       auto MangledName = Mangle(G.getName());
48       SymbolFlags[MangledName] = JITSymbolFlags::fromGlobalValue(G);
49       Discardable[MangledName] = &G;
50     }
51   }
52 }
53 
54 void IRMaterializationUnit::discard(const VSO &V, SymbolStringPtr Name) {
55   auto I = Discardable.find(Name);
56   assert(I != Discardable.end() &&
57          "Symbol not provided by this MU, or previously discarded");
58   I->second->setLinkage(GlobalValue::AvailableExternallyLinkage);
59   Discardable.erase(I);
60 }
61 
62 BasicIRLayerMaterializationUnit::BasicIRLayerMaterializationUnit(
63     IRLayer &L, VModuleKey K, std::unique_ptr<Module> M)
64   : IRMaterializationUnit(L.getExecutionSession(), std::move(M)),
65       L(L), K(std::move(K)) {}
66 
67 void BasicIRLayerMaterializationUnit::materialize(
68     MaterializationResponsibility R) {
69   L.emit(std::move(R), std::move(K), std::move(M));
70 }
71 
72 ObjectLayer::ObjectLayer(ExecutionSession &ES) : ES(ES) {}
73 
74 ObjectLayer::~ObjectLayer() {}
75 
76 Error ObjectLayer::add(VSO &V, VModuleKey K, std::unique_ptr<MemoryBuffer> O) {
77   return V.define(llvm::make_unique<BasicObjectLayerMaterializationUnit>(
78       *this, std::move(K), std::move(O)));
79 }
80 
81 BasicObjectLayerMaterializationUnit::BasicObjectLayerMaterializationUnit(
82     ObjectLayer &L, VModuleKey K, std::unique_ptr<MemoryBuffer> O)
83     : MaterializationUnit(SymbolFlagsMap()), L(L), K(std::move(K)),
84       O(std::move(O)) {
85 
86   auto &ES = L.getExecutionSession();
87   auto Obj = cantFail(
88       object::ObjectFile::createObjectFile(this->O->getMemBufferRef()));
89 
90   for (auto &Sym : Obj->symbols()) {
91     if (!(Sym.getFlags() & object::BasicSymbolRef::SF_Undefined) &&
92          (Sym.getFlags() & object::BasicSymbolRef::SF_Exported)) {
93       auto InternedName =
94           ES.getSymbolStringPool().intern(cantFail(Sym.getName()));
95       SymbolFlags[InternedName] = JITSymbolFlags::fromObjectSymbol(Sym);
96     }
97   }
98 }
99 
100 void BasicObjectLayerMaterializationUnit::materialize(
101     MaterializationResponsibility R) {
102   L.emit(std::move(R), std::move(K), std::move(O));
103 }
104 
105 void BasicObjectLayerMaterializationUnit::discard(const VSO &V,
106                                                   SymbolStringPtr Name) {
107   // FIXME: Support object file level discard. This could be done by building a
108   //        filter to pass to the object layer along with the object itself.
109 }
110 
111 } // End namespace orc.
112 } // End namespace llvm.
113