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