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       SymbolToDefinition[MangledName] = &G;
50     }
51   }
52 }
53 
54 IRMaterializationUnit::IRMaterializationUnit(
55     std::unique_ptr<Module> M, SymbolFlagsMap SymbolFlags,
56     SymbolNameToDefinitionMap SymbolToDefinition)
57     : MaterializationUnit(std::move(SymbolFlags)), M(std::move(M)),
58       SymbolToDefinition(std::move(SymbolToDefinition)) {}
59 
60 void IRMaterializationUnit::discard(const VSO &V, SymbolStringPtr Name) {
61   auto I = SymbolToDefinition.find(Name);
62   assert(I != SymbolToDefinition.end() &&
63          "Symbol not provided by this MU, or previously discarded");
64   assert(!I->second->isDeclaration() &&
65          "Discard should only apply to definitions");
66   I->second->setLinkage(GlobalValue::AvailableExternallyLinkage);
67   SymbolToDefinition.erase(I);
68 }
69 
70 BasicIRLayerMaterializationUnit::BasicIRLayerMaterializationUnit(
71     IRLayer &L, VModuleKey K, std::unique_ptr<Module> M)
72   : IRMaterializationUnit(L.getExecutionSession(), std::move(M)),
73       L(L), K(std::move(K)) {}
74 
75 void BasicIRLayerMaterializationUnit::materialize(
76     MaterializationResponsibility R) {
77   L.emit(std::move(R), std::move(K), std::move(M));
78 }
79 
80 ObjectLayer::ObjectLayer(ExecutionSession &ES) : ES(ES) {}
81 
82 ObjectLayer::~ObjectLayer() {}
83 
84 Error ObjectLayer::add(VSO &V, VModuleKey K, std::unique_ptr<MemoryBuffer> O) {
85   return V.define(llvm::make_unique<BasicObjectLayerMaterializationUnit>(
86       *this, std::move(K), std::move(O)));
87 }
88 
89 BasicObjectLayerMaterializationUnit::BasicObjectLayerMaterializationUnit(
90     ObjectLayer &L, VModuleKey K, std::unique_ptr<MemoryBuffer> O)
91     : MaterializationUnit(SymbolFlagsMap()), L(L), K(std::move(K)),
92       O(std::move(O)) {
93 
94   auto &ES = L.getExecutionSession();
95   auto Obj = cantFail(
96       object::ObjectFile::createObjectFile(this->O->getMemBufferRef()));
97 
98   for (auto &Sym : Obj->symbols()) {
99     if (!(Sym.getFlags() & object::BasicSymbolRef::SF_Undefined) &&
100          (Sym.getFlags() & object::BasicSymbolRef::SF_Exported)) {
101       auto InternedName =
102           ES.getSymbolStringPool().intern(cantFail(Sym.getName()));
103       SymbolFlags[InternedName] = JITSymbolFlags::fromObjectSymbol(Sym);
104     }
105   }
106 }
107 
108 void BasicObjectLayerMaterializationUnit::materialize(
109     MaterializationResponsibility R) {
110   L.emit(std::move(R), std::move(K), std::move(O));
111 }
112 
113 void BasicObjectLayerMaterializationUnit::discard(const VSO &V,
114                                                   SymbolStringPtr Name) {
115   // FIXME: Support object file level discard. This could be done by building a
116   //        filter to pass to the object layer along with the object itself.
117 }
118 
119 } // End namespace orc.
120 } // End namespace llvm.
121