1 //===---- IndirectionUtils.cpp - Utilities for call indirection in Orc ----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/ADT/Triple.h"
11 #include "llvm/ExecutionEngine/Orc/CloneSubModule.h"
12 #include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
13 #include "llvm/IR/CallSite.h"
14 #include "llvm/IR/IRBuilder.h"
22 GlobalVariable* createImplPointer(Function &F, const Twine &Name,
23 Constant *Initializer) {
24 assert(F.getParent() && "Function isn't in a module.");
26 Initializer = Constant::getNullValue(F.getType());
27 Module &M = *F.getParent();
28 return new GlobalVariable(M, F.getType(), false, GlobalValue::ExternalLinkage,
29 Initializer, Name, nullptr,
30 GlobalValue::NotThreadLocal, 0, true);
33 void makeStub(Function &F, GlobalVariable &ImplPointer) {
34 assert(F.isDeclaration() && "Can't turn a definition into a stub.");
35 assert(F.getParent() && "Function isn't in a module.");
36 Module &M = *F.getParent();
37 BasicBlock *EntryBlock = BasicBlock::Create(M.getContext(), "entry", &F);
38 IRBuilder<> Builder(EntryBlock);
39 LoadInst *ImplAddr = Builder.CreateLoad(&ImplPointer);
40 std::vector<Value*> CallArgs;
41 for (auto &A : F.args())
42 CallArgs.push_back(&A);
43 CallInst *Call = Builder.CreateCall(ImplAddr, CallArgs);
45 Builder.CreateRet(Call);
48 void partition(Module &M, const ModulePartitionMap &PMap) {
50 for (auto &KVPair : PMap) {
52 auto ExtractGlobalVars =
53 [&](GlobalVariable &New, const GlobalVariable &Orig,
54 ValueToValueMapTy &VMap) {
55 if (KVPair.second.count(&Orig)) {
56 copyGVInitializer(New, Orig, VMap);
58 if (New.getLinkage() == GlobalValue::PrivateLinkage) {
59 New.setLinkage(GlobalValue::ExternalLinkage);
60 New.setVisibility(GlobalValue::HiddenVisibility);
64 auto ExtractFunctions =
65 [&](Function &New, const Function &Orig, ValueToValueMapTy &VMap) {
66 if (KVPair.second.count(&Orig))
67 copyFunctionBody(New, Orig, VMap);
68 if (New.getLinkage() == GlobalValue::InternalLinkage) {
69 New.setLinkage(GlobalValue::ExternalLinkage);
70 New.setVisibility(GlobalValue::HiddenVisibility);
74 CloneSubModule(*KVPair.first, M, ExtractGlobalVars, ExtractFunctions,
79 FullyPartitionedModule fullyPartition(Module &M) {
80 FullyPartitionedModule MP;
82 ModulePartitionMap PMap;
86 if (F.isDeclaration())
89 std::string NewModuleName = (M.getName() + "." + F.getName()).str();
90 MP.Functions.push_back(
91 llvm::make_unique<Module>(NewModuleName, M.getContext()));
92 MP.Functions.back()->setDataLayout(M.getDataLayout());
93 PMap[MP.Functions.back().get()].insert(&F);
97 llvm::make_unique<Module>((M.getName() + ".globals_and_stubs").str(),
99 MP.GlobalVars->setDataLayout(M.getDataLayout());
102 llvm::make_unique<Module>((M.getName() + ".commons").str(), M.getContext());
103 MP.Commons->setDataLayout(M.getDataLayout());
105 // Make sure there's at least an empty set for the stubs map or we'll fail
106 // to clone anything for it (including the decls).
107 PMap[MP.GlobalVars.get()] = ModulePartitionMap::mapped_type();
108 for (auto &GV : M.globals())
109 if (GV.getLinkage() == GlobalValue::CommonLinkage)
110 PMap[MP.Commons.get()].insert(&GV);
112 PMap[MP.GlobalVars.get()].insert(&GV);
119 } // End namespace orc.
120 } // End namespace llvm.