1f22ef01cSRoman Divacky //===- CloneModule.cpp - Clone an entire module ---------------------------===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky //                     The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
10f22ef01cSRoman Divacky // This file implements the CloneModule interface which makes a copy of an
11f22ef01cSRoman Divacky // entire module.
12f22ef01cSRoman Divacky //
13f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
14f22ef01cSRoman Divacky 
15f22ef01cSRoman Divacky #include "llvm/Transforms/Utils/Cloning.h"
16139f7f9bSDimitry Andric #include "llvm/IR/Constant.h"
17139f7f9bSDimitry Andric #include "llvm/IR/DerivedTypes.h"
18139f7f9bSDimitry Andric #include "llvm/IR/Module.h"
19e580952dSDimitry Andric #include "llvm/Transforms/Utils/ValueMapper.h"
20f22ef01cSRoman Divacky using namespace llvm;
21f22ef01cSRoman Divacky 
22f22ef01cSRoman Divacky /// CloneModule - Return an exact copy of the specified module.  This is not as
23f22ef01cSRoman Divacky /// easy as it might seem because we have to worry about making copies of global
24f22ef01cSRoman Divacky /// variables and functions, and making their (initializers and references,
25f22ef01cSRoman Divacky /// respectively) refer to the right globals.
26f22ef01cSRoman Divacky ///
27f22ef01cSRoman Divacky Module *llvm::CloneModule(const Module *M) {
28f22ef01cSRoman Divacky   // Create the value map that maps things from the old module over to the new
29f22ef01cSRoman Divacky   // module.
30ffd1746dSEd Schouten   ValueToValueMapTy VMap;
31ffd1746dSEd Schouten   return CloneModule(M, VMap);
32f22ef01cSRoman Divacky }
33f22ef01cSRoman Divacky 
3417a519f9SDimitry Andric Module *llvm::CloneModule(const Module *M, ValueToValueMapTy &VMap) {
3517a519f9SDimitry Andric   // First off, we need to create the new module.
36f22ef01cSRoman Divacky   Module *New = new Module(M->getModuleIdentifier(), M->getContext());
37f22ef01cSRoman Divacky   New->setDataLayout(M->getDataLayout());
38f22ef01cSRoman Divacky   New->setTargetTriple(M->getTargetTriple());
39f22ef01cSRoman Divacky   New->setModuleInlineAsm(M->getModuleInlineAsm());
40f22ef01cSRoman Divacky 
41f22ef01cSRoman Divacky   // Loop over all of the global variables, making corresponding globals in the
42ffd1746dSEd Schouten   // new module.  Here we add them to the VMap and to the new Module.  We
43f22ef01cSRoman Divacky   // don't worry about attributes or initializers, they will come later.
44f22ef01cSRoman Divacky   //
45f22ef01cSRoman Divacky   for (Module::const_global_iterator I = M->global_begin(), E = M->global_end();
46f22ef01cSRoman Divacky        I != E; ++I) {
47f22ef01cSRoman Divacky     GlobalVariable *GV = new GlobalVariable(*New,
48f22ef01cSRoman Divacky                                             I->getType()->getElementType(),
496122f3e6SDimitry Andric                                             I->isConstant(), I->getLinkage(),
5091bc56edSDimitry Andric                                             (Constant*) nullptr, I->getName(),
5191bc56edSDimitry Andric                                             (GlobalVariable*) nullptr,
527ae0e2c9SDimitry Andric                                             I->getThreadLocalMode(),
536122f3e6SDimitry Andric                                             I->getType()->getAddressSpace());
546122f3e6SDimitry Andric     GV->copyAttributesFrom(I);
55ffd1746dSEd Schouten     VMap[I] = GV;
56f22ef01cSRoman Divacky   }
57f22ef01cSRoman Divacky 
58f22ef01cSRoman Divacky   // Loop over the functions in the module, making external functions as before
59f22ef01cSRoman Divacky   for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) {
60f22ef01cSRoman Divacky     Function *NF =
61f22ef01cSRoman Divacky       Function::Create(cast<FunctionType>(I->getType()->getElementType()),
626122f3e6SDimitry Andric                        I->getLinkage(), I->getName(), New);
63f22ef01cSRoman Divacky     NF->copyAttributesFrom(I);
64ffd1746dSEd Schouten     VMap[I] = NF;
65f22ef01cSRoman Divacky   }
66f22ef01cSRoman Divacky 
67f22ef01cSRoman Divacky   // Loop over the aliases in the module
68f22ef01cSRoman Divacky   for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();
696122f3e6SDimitry Andric        I != E; ++I) {
7091bc56edSDimitry Andric     auto *PTy = cast<PointerType>(I->getType());
7191bc56edSDimitry Andric     auto *GA =
7291bc56edSDimitry Andric         GlobalAlias::create(PTy->getElementType(), PTy->getAddressSpace(),
7391bc56edSDimitry Andric                             I->getLinkage(), I->getName(), New);
746122f3e6SDimitry Andric     GA->copyAttributesFrom(I);
756122f3e6SDimitry Andric     VMap[I] = GA;
766122f3e6SDimitry Andric   }
77f22ef01cSRoman Divacky 
78f22ef01cSRoman Divacky   // Now that all of the things that global variable initializer can refer to
79f22ef01cSRoman Divacky   // have been created, loop through and copy the global variable referrers
80f22ef01cSRoman Divacky   // over...  We also set the attributes on the global now.
81f22ef01cSRoman Divacky   //
82f22ef01cSRoman Divacky   for (Module::const_global_iterator I = M->global_begin(), E = M->global_end();
83f22ef01cSRoman Divacky        I != E; ++I) {
84ffd1746dSEd Schouten     GlobalVariable *GV = cast<GlobalVariable>(VMap[I]);
85f22ef01cSRoman Divacky     if (I->hasInitializer())
8617a519f9SDimitry Andric       GV->setInitializer(MapValue(I->getInitializer(), VMap));
87f22ef01cSRoman Divacky   }
88f22ef01cSRoman Divacky 
89f22ef01cSRoman Divacky   // Similarly, copy over function bodies now...
90f22ef01cSRoman Divacky   //
91f22ef01cSRoman Divacky   for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) {
92ffd1746dSEd Schouten     Function *F = cast<Function>(VMap[I]);
93f22ef01cSRoman Divacky     if (!I->isDeclaration()) {
94f22ef01cSRoman Divacky       Function::arg_iterator DestI = F->arg_begin();
95f22ef01cSRoman Divacky       for (Function::const_arg_iterator J = I->arg_begin(); J != I->arg_end();
96f22ef01cSRoman Divacky            ++J) {
97f22ef01cSRoman Divacky         DestI->setName(J->getName());
98ffd1746dSEd Schouten         VMap[J] = DestI++;
99f22ef01cSRoman Divacky       }
100f22ef01cSRoman Divacky 
101f22ef01cSRoman Divacky       SmallVector<ReturnInst*, 8> Returns;  // Ignore returns cloned.
102e580952dSDimitry Andric       CloneFunctionInto(F, I, VMap, /*ModuleLevelChanges=*/true, Returns);
103f22ef01cSRoman Divacky     }
104f22ef01cSRoman Divacky   }
105f22ef01cSRoman Divacky 
106f22ef01cSRoman Divacky   // And aliases
107f22ef01cSRoman Divacky   for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();
108f22ef01cSRoman Divacky        I != E; ++I) {
109ffd1746dSEd Schouten     GlobalAlias *GA = cast<GlobalAlias>(VMap[I]);
110f22ef01cSRoman Divacky     if (const Constant *C = I->getAliasee())
11191bc56edSDimitry Andric       GA->setAliasee(cast<GlobalObject>(MapValue(C, VMap)));
112f22ef01cSRoman Divacky   }
113f22ef01cSRoman Divacky 
114ffd1746dSEd Schouten   // And named metadata....
115ffd1746dSEd Schouten   for (Module::const_named_metadata_iterator I = M->named_metadata_begin(),
116ffd1746dSEd Schouten          E = M->named_metadata_end(); I != E; ++I) {
117ffd1746dSEd Schouten     const NamedMDNode &NMD = *I;
118e580952dSDimitry Andric     NamedMDNode *NewNMD = New->getOrInsertNamedMetadata(NMD.getName());
119ffd1746dSEd Schouten     for (unsigned i = 0, e = NMD.getNumOperands(); i != e; ++i)
12017a519f9SDimitry Andric       NewNMD->addOperand(MapValue(NMD.getOperand(i), VMap));
121ffd1746dSEd Schouten   }
122ffd1746dSEd Schouten 
123f22ef01cSRoman Divacky   return New;
124f22ef01cSRoman Divacky }
125