mirror of
https://github.com/RPCS3/llvm.git
synced 2025-04-05 23:01:38 +00:00

This patch changes the design of GlobalAlias so that it doesn't take a ConstantExpr anymore. It now points directly to a GlobalObject, but its type is independent of the aliasee type. To avoid changing all alias related tests in this patches, I kept the common syntax @foo = alias i32* @bar to mean the same as now. The cases that used to use cast now use the more general syntax @foo = alias i16, i32* @bar. Note that GlobalAlias now behaves a bit more like GlobalVariable. We know that its type is always a pointer, so we omit the '*'. For the bitcode, a nice surprise is that we were writing both identical types already, so the format change is minimal. Auto upgrade is handled by looking through the casts and no new fields are needed for now. New bitcode will simply have different types for Alias and Aliasee. One last interesting point in the patch is that replaceAllUsesWith becomes smart enough to avoid putting a ConstantExpr in the aliasee. This seems better than checking and updating every caller. A followup patch will delete getAliasedGlobal now that it is redundant. Another patch will add support for an explicit offset. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@209007 91177308-0d34-0410-b5e6-96231b3b80d8
125 lines
4.8 KiB
C++
125 lines
4.8 KiB
C++
//===- CloneModule.cpp - Clone an entire module ---------------------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file implements the CloneModule interface which makes a copy of an
|
|
// entire module.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/Transforms/Utils/Cloning.h"
|
|
#include "llvm/IR/Constant.h"
|
|
#include "llvm/IR/DerivedTypes.h"
|
|
#include "llvm/IR/Module.h"
|
|
#include "llvm/Transforms/Utils/ValueMapper.h"
|
|
using namespace llvm;
|
|
|
|
/// CloneModule - Return an exact copy of the specified module. This is not as
|
|
/// easy as it might seem because we have to worry about making copies of global
|
|
/// variables and functions, and making their (initializers and references,
|
|
/// respectively) refer to the right globals.
|
|
///
|
|
Module *llvm::CloneModule(const Module *M) {
|
|
// Create the value map that maps things from the old module over to the new
|
|
// module.
|
|
ValueToValueMapTy VMap;
|
|
return CloneModule(M, VMap);
|
|
}
|
|
|
|
Module *llvm::CloneModule(const Module *M, ValueToValueMapTy &VMap) {
|
|
// First off, we need to create the new module.
|
|
Module *New = new Module(M->getModuleIdentifier(), M->getContext());
|
|
New->setDataLayout(M->getDataLayout());
|
|
New->setTargetTriple(M->getTargetTriple());
|
|
New->setModuleInlineAsm(M->getModuleInlineAsm());
|
|
|
|
// Loop over all of the global variables, making corresponding globals in the
|
|
// new module. Here we add them to the VMap and to the new Module. We
|
|
// don't worry about attributes or initializers, they will come later.
|
|
//
|
|
for (Module::const_global_iterator I = M->global_begin(), E = M->global_end();
|
|
I != E; ++I) {
|
|
GlobalVariable *GV = new GlobalVariable(*New,
|
|
I->getType()->getElementType(),
|
|
I->isConstant(), I->getLinkage(),
|
|
(Constant*) nullptr, I->getName(),
|
|
(GlobalVariable*) nullptr,
|
|
I->getThreadLocalMode(),
|
|
I->getType()->getAddressSpace());
|
|
GV->copyAttributesFrom(I);
|
|
VMap[I] = GV;
|
|
}
|
|
|
|
// Loop over the functions in the module, making external functions as before
|
|
for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) {
|
|
Function *NF =
|
|
Function::Create(cast<FunctionType>(I->getType()->getElementType()),
|
|
I->getLinkage(), I->getName(), New);
|
|
NF->copyAttributesFrom(I);
|
|
VMap[I] = NF;
|
|
}
|
|
|
|
// Loop over the aliases in the module
|
|
for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();
|
|
I != E; ++I) {
|
|
auto *PTy = cast<PointerType>(I->getType());
|
|
auto *GA =
|
|
new GlobalAlias(PTy->getElementType(), I->getLinkage(), I->getName(),
|
|
nullptr, New, PTy->getAddressSpace());
|
|
GA->copyAttributesFrom(I);
|
|
VMap[I] = GA;
|
|
}
|
|
|
|
// Now that all of the things that global variable initializer can refer to
|
|
// have been created, loop through and copy the global variable referrers
|
|
// over... We also set the attributes on the global now.
|
|
//
|
|
for (Module::const_global_iterator I = M->global_begin(), E = M->global_end();
|
|
I != E; ++I) {
|
|
GlobalVariable *GV = cast<GlobalVariable>(VMap[I]);
|
|
if (I->hasInitializer())
|
|
GV->setInitializer(MapValue(I->getInitializer(), VMap));
|
|
}
|
|
|
|
// Similarly, copy over function bodies now...
|
|
//
|
|
for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) {
|
|
Function *F = cast<Function>(VMap[I]);
|
|
if (!I->isDeclaration()) {
|
|
Function::arg_iterator DestI = F->arg_begin();
|
|
for (Function::const_arg_iterator J = I->arg_begin(); J != I->arg_end();
|
|
++J) {
|
|
DestI->setName(J->getName());
|
|
VMap[J] = DestI++;
|
|
}
|
|
|
|
SmallVector<ReturnInst*, 8> Returns; // Ignore returns cloned.
|
|
CloneFunctionInto(F, I, VMap, /*ModuleLevelChanges=*/true, Returns);
|
|
}
|
|
}
|
|
|
|
// And aliases
|
|
for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();
|
|
I != E; ++I) {
|
|
GlobalAlias *GA = cast<GlobalAlias>(VMap[I]);
|
|
if (const GlobalObject *C = I->getAliasee())
|
|
GA->setAliasee(cast<GlobalObject>(MapValue(C, VMap)));
|
|
}
|
|
|
|
// And named metadata....
|
|
for (Module::const_named_metadata_iterator I = M->named_metadata_begin(),
|
|
E = M->named_metadata_end(); I != E; ++I) {
|
|
const NamedMDNode &NMD = *I;
|
|
NamedMDNode *NewNMD = New->getOrInsertNamedMetadata(NMD.getName());
|
|
for (unsigned i = 0, e = NMD.getNumOperands(); i != e; ++i)
|
|
NewNMD->addOperand(MapValue(NMD.getOperand(i), VMap));
|
|
}
|
|
|
|
return New;
|
|
}
|