[Orc] Update the Orc indirection utils and refactor the CompileOnDemand layer.
[oota-llvm.git] / lib / ExecutionEngine / Orc / IndirectionUtils.cpp
1 #include "llvm/ADT/Triple.h"
2 #include "llvm/ExecutionEngine/Orc/CloneSubModule.h"
3 #include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
4 #include "llvm/IR/CallSite.h"
5 #include "llvm/IR/IRBuilder.h"
6 #include <set>
7
8 using namespace llvm;
9
10 namespace llvm {
11
12 GlobalVariable* createImplPointer(Function &F, const Twine &Name,
13                                   Constant *Initializer) {
14   assert(F.getParent() && "Function isn't in a module.");
15   if (!Initializer)
16     Initializer = Constant::getNullValue(F.getType());
17   Module &M = *F.getParent();
18   return new GlobalVariable(M, F.getType(), false, GlobalValue::ExternalLinkage,
19                             Initializer, Name, nullptr,
20                             GlobalValue::NotThreadLocal, 0, true);
21 }
22
23 void makeStub(Function &F, GlobalVariable &ImplPointer) {
24   assert(F.isDeclaration() && "Can't turn a definition into a stub.");
25   assert(F.getParent() && "Function isn't in a module.");
26   Module &M = *F.getParent();
27   BasicBlock *EntryBlock = BasicBlock::Create(M.getContext(), "entry", &F);
28   IRBuilder<> Builder(EntryBlock);
29   LoadInst *ImplAddr = Builder.CreateLoad(&ImplPointer);
30   std::vector<Value*> CallArgs;
31   for (auto &A : F.args())
32     CallArgs.push_back(&A);
33   CallInst *Call = Builder.CreateCall(ImplAddr, CallArgs);
34   Call->setTailCall();
35   Builder.CreateRet(Call);
36 }
37
38 void partition(Module &M, const ModulePartitionMap &PMap) {
39
40   for (auto &KVPair : PMap) {
41
42     auto ExtractGlobalVars =
43       [&](GlobalVariable &New, const GlobalVariable &Orig,
44           ValueToValueMapTy &VMap) {
45         if (KVPair.second.count(&Orig)) {
46           copyGVInitializer(New, Orig, VMap);
47         }
48         if (New.getLinkage() == GlobalValue::PrivateLinkage) {
49           New.setLinkage(GlobalValue::ExternalLinkage);
50           New.setVisibility(GlobalValue::HiddenVisibility);
51         }
52       };
53
54     auto ExtractFunctions =
55       [&](Function &New, const Function &Orig, ValueToValueMapTy &VMap) {
56         if (KVPair.second.count(&Orig))
57           copyFunctionBody(New, Orig, VMap);
58         if (New.getLinkage() == GlobalValue::InternalLinkage) {
59           New.setLinkage(GlobalValue::ExternalLinkage);
60           New.setVisibility(GlobalValue::HiddenVisibility);
61         }
62       };
63
64     CloneSubModule(*KVPair.first, M, ExtractGlobalVars, ExtractFunctions,
65                    false);
66   }
67 }
68
69 FullyPartitionedModule fullyPartition(Module &M) {
70   FullyPartitionedModule MP;
71
72   ModulePartitionMap PMap;
73
74   for (auto &F : M) {
75
76     if (F.isDeclaration())
77       continue;
78
79     std::string NewModuleName = (M.getName() + "." + F.getName()).str();
80     MP.Functions.push_back(
81       llvm::make_unique<Module>(NewModuleName, M.getContext()));
82     MP.Functions.back()->setDataLayout(M.getDataLayout());
83     PMap[MP.Functions.back().get()].insert(&F);
84   }
85
86   MP.GlobalVars =
87     llvm::make_unique<Module>((M.getName() + ".globals_and_stubs").str(),
88                               M.getContext());
89   MP.GlobalVars->setDataLayout(M.getDataLayout());
90
91   MP.Commons =
92     llvm::make_unique<Module>((M.getName() + ".commons").str(), M.getContext());
93   MP.Commons->setDataLayout(M.getDataLayout());
94
95   // Make sure there's at least an empty set for the stubs map or we'll fail
96   // to clone anything for it (including the decls).
97   PMap[MP.GlobalVars.get()] = ModulePartitionMap::mapped_type();
98   for (auto &GV : M.globals())
99     if (GV.getLinkage() == GlobalValue::CommonLinkage)
100       PMap[MP.Commons.get()].insert(&GV);
101     else
102       PMap[MP.GlobalVars.get()].insert(&GV);
103
104   partition(M, PMap);
105
106   return MP;
107 }
108
109 }