1ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/ExecutionEngine/Orc/CloneSubModule.h" 2ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/Function.h" 3ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/GlobalVariable.h" 4ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/Module.h" 5ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Transforms/Utils/Cloning.h" 6ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 7ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesnamespace llvm { 8ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesnamespace orc { 9ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 10ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid copyGVInitializer(GlobalVariable &New, const GlobalVariable &Orig, 11ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ValueToValueMapTy &VMap) { 12ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Orig.hasInitializer()) 13ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines New.setInitializer(MapValue(Orig.getInitializer(), VMap)); 14ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 15ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 16ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid copyFunctionBody(Function &New, const Function &Orig, 17ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ValueToValueMapTy &VMap) { 18ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!Orig.isDeclaration()) { 19ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Function::arg_iterator DestI = New.arg_begin(); 20ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (Function::const_arg_iterator J = Orig.arg_begin(); J != Orig.arg_end(); 21ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ++J) { 22ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DestI->setName(J->getName()); 23ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines VMap[J] = DestI++; 24ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 25ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 26ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SmallVector<ReturnInst *, 8> Returns; // Ignore returns cloned. 27ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CloneFunctionInto(&New, &Orig, VMap, /*ModuleLevelChanges=*/true, Returns); 28ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 29ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 30ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 31ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid CloneSubModule(llvm::Module &Dst, const Module &Src, 32ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines HandleGlobalVariableFtor HandleGlobalVariable, 33ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines HandleFunctionFtor HandleFunction, bool CloneInlineAsm) { 34ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 35ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ValueToValueMapTy VMap; 36ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 37ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (CloneInlineAsm) 38ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Dst.appendModuleInlineAsm(Src.getModuleInlineAsm()); 39ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 40ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Copy global variables (but not initializers, yet). 41ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (Module::const_global_iterator I = Src.global_begin(), E = Src.global_end(); 42ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines I != E; ++I) { 43ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines GlobalVariable *GV = new GlobalVariable( 44ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Dst, I->getType()->getElementType(), I->isConstant(), I->getLinkage(), 45ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines (Constant *)nullptr, I->getName(), (GlobalVariable *)nullptr, 46ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines I->getThreadLocalMode(), I->getType()->getAddressSpace()); 47ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines GV->copyAttributesFrom(I); 48ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines VMap[I] = GV; 49ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 50ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 51ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Loop over the functions in the module, making external functions as before 52ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (Module::const_iterator I = Src.begin(), E = Src.end(); I != E; ++I) { 53ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Function *NF = 54ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Function::Create(cast<FunctionType>(I->getType()->getElementType()), 55ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines I->getLinkage(), I->getName(), &Dst); 56ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines NF->copyAttributesFrom(I); 57ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines VMap[I] = NF; 58ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 59ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 60ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Loop over the aliases in the module 61ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (Module::const_alias_iterator I = Src.alias_begin(), E = Src.alias_end(); 62ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines I != E; ++I) { 63ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines auto *PTy = cast<PointerType>(I->getType()); 64ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines auto *GA = 65ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines GlobalAlias::create(PTy->getElementType(), PTy->getAddressSpace(), 66ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines I->getLinkage(), I->getName(), &Dst); 67ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines GA->copyAttributesFrom(I); 68ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines VMap[I] = GA; 69ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 70ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 71ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Now that all of the things that global variable initializer can refer to 72ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // have been created, loop through and copy the global variable referrers 73ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // over... We also set the attributes on the global now. 74ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (Module::const_global_iterator I = Src.global_begin(), E = Src.global_end(); 75ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines I != E; ++I) { 76ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines GlobalVariable &GV = *cast<GlobalVariable>(VMap[I]); 77ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines HandleGlobalVariable(GV, *I, VMap); 78ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 79ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 80ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Similarly, copy over function bodies now... 81ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // 82ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (Module::const_iterator I = Src.begin(), E = Src.end(); I != E; ++I) { 83ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Function &F = *cast<Function>(VMap[I]); 84ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines HandleFunction(F, *I, VMap); 85ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 86ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 87ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // And aliases 88ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (Module::const_alias_iterator I = Src.alias_begin(), E = Src.alias_end(); 89ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines I != E; ++I) { 90ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines GlobalAlias *GA = cast<GlobalAlias>(VMap[I]); 91ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (const Constant *C = I->getAliasee()) 92ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines GA->setAliasee(MapValue(C, VMap)); 93ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 94ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 95ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // And named metadata.... 96ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (Module::const_named_metadata_iterator I = Src.named_metadata_begin(), 97ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines E = Src.named_metadata_end(); 98ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines I != E; ++I) { 99ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const NamedMDNode &NMD = *I; 100ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines NamedMDNode *NewNMD = Dst.getOrInsertNamedMetadata(NMD.getName()); 101ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (unsigned i = 0, e = NMD.getNumOperands(); i != e; ++i) 102ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines NewNMD->addOperand(MapMetadata(NMD.getOperand(i), VMap)); 103ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 104ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 105ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 106ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 107ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} // End namespace orc. 108ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} // End namespace llvm. 109