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