class AssumptionCacheTracker;
class DominatorTree;
-/// CloneModule - Return an exact copy of the specified module
+/// Return an exact copy of the specified module
///
-Module *CloneModule(const Module *M);
-Module *CloneModule(const Module *M, ValueToValueMapTy &VMap);
+std::unique_ptr<Module> CloneModule(const Module *M);
+std::unique_ptr<Module> CloneModule(const Module *M, ValueToValueMapTy &VMap);
/// Return a copy of the specified module. The ShouldCloneDefinition function
/// controls whether a specific GlobalValue's definition is cloned. If the
/// function returns false, the module copy will contain an external reference
/// in place of the global definition.
-Module *
+std::unique_ptr<Module>
CloneModule(const Module *M, ValueToValueMapTy &VMap,
std::function<bool(const GlobalValue *)> ShouldCloneDefinition);
#include "llvm-c/Core.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.
+/// 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) {
+std::unique_ptr<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) {
+std::unique_ptr<Module> llvm::CloneModule(const Module *M,
+ ValueToValueMapTy &VMap) {
return CloneModule(M, VMap, [](const GlobalValue *GV) { return true; });
}
-Module *llvm::CloneModule(
+std::unique_ptr<Module> llvm::CloneModule(
const Module *M, ValueToValueMapTy &VMap,
std::function<bool(const GlobalValue *)> ShouldCloneDefinition) {
// First off, we need to create the new module.
- Module *New = new Module(M->getModuleIdentifier(), M->getContext());
+ std::unique_ptr<Module> New =
+ llvm::make_unique<Module>(M->getModuleIdentifier(), M->getContext());
New->setDataLayout(M->getDataLayout());
New->setTargetTriple(M->getTargetTriple());
New->setModuleInlineAsm(M->getModuleInlineAsm());
// 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);
+ Function::Create(cast<FunctionType>(I->getType()->getElementType()),
+ I->getLinkage(), I->getName(), New.get());
NF->copyAttributesFrom(&*I);
VMap[&*I] = NF;
}
GlobalValue *GV;
if (I->getValueType()->isFunctionTy())
GV = Function::Create(cast<FunctionType>(I->getValueType()),
- GlobalValue::ExternalLinkage, I->getName(), New);
+ GlobalValue::ExternalLinkage, I->getName(),
+ New.get());
else
GV = new GlobalVariable(
*New, I->getValueType(), false, GlobalValue::ExternalLinkage,
}
auto *GA = GlobalAlias::create(I->getValueType(),
I->getType()->getPointerAddressSpace(),
- I->getLinkage(), I->getName(), New);
+ I->getLinkage(), I->getName(), New.get());
GA->copyAttributesFrom(&*I);
VMap[&*I] = GA;
}
extern "C" {
LLVMModuleRef LLVMCloneModule(LLVMModuleRef M) {
- return wrap(CloneModule(unwrap(M)));
+ return wrap(CloneModule(unwrap(M)).release());
}
}
std::vector<GlobalVariable*> &GVs) {
// Clone the program to try hacking it apart...
ValueToValueMapTy VMap;
- Module *M = CloneModule(BD.getProgram(), VMap);
+ Module *M = CloneModule(BD.getProgram(), VMap).release();
// Convert list to set for fast lookup...
std::set<GlobalVariable*> GVSet;
// Clone the program to try hacking it apart...
ValueToValueMapTy VMap;
- Module *M = CloneModule(BD.getProgram(), VMap);
+ Module *M = CloneModule(BD.getProgram(), VMap).release();
// Convert list to set for fast lookup...
std::set<Function*> Functions;
bool ReduceCrashingBlocks::TestBlocks(std::vector<const BasicBlock*> &BBs) {
// Clone the program to try hacking it apart...
ValueToValueMapTy VMap;
- Module *M = CloneModule(BD.getProgram(), VMap);
+ Module *M = CloneModule(BD.getProgram(), VMap).release();
// Convert list to set for fast lookup...
SmallPtrSet<BasicBlock*, 8> Blocks;
&Insts) {
// Clone the program to try hacking it apart...
ValueToValueMapTy VMap;
- Module *M = CloneModule(BD.getProgram(), VMap);
+ Module *M = CloneModule(BD.getProgram(), VMap).release();
// Convert list to set for fast lookup...
SmallPtrSet<Instruction*, 64> Instructions;
bool ReduceCrashingNamedMD::TestNamedMDs(std::vector<std::string> &NamedMDs) {
ValueToValueMapTy VMap;
- Module *M = CloneModule(BD.getProgram(), VMap);
+ Module *M = CloneModule(BD.getProgram(), VMap).release();
outs() << "Checking for crash with only these named metadata nodes:";
unsigned NumPrint = std::min<size_t>(NamedMDs.size(), 10);
outs() << " named metadata operands: ";
ValueToValueMapTy VMap;
- Module *M = CloneModule(BD.getProgram(), VMap);
+ Module *M = CloneModule(BD.getProgram(), VMap).release();
// This is a little wasteful. In the future it might be good if we could have
// these dropped during cloning.
BD.getProgram()->global_begin() != BD.getProgram()->global_end()) {
// Now try to reduce the number of global variable initializers in the
// module to something small.
- Module *M = CloneModule(BD.getProgram());
+ Module *M = CloneModule(BD.getProgram()).release();
bool DeletedInit = false;
for (Module::global_iterator I = M->global_begin(), E = M->global_end();
// Try to clean up the testcase by running funcresolve and globaldce...
if (!BugpointIsInterrupted) {
outs() << "\n*** Attempting to perform final cleanups: ";
- Module *M = CloneModule(BD.getProgram());
+ Module *M = CloneModule(BD.getProgram()).release();
M = BD.performFinalCleanups(M, true).release();
// Find out if the pass still crashes on the cleaned up program...
BugDriver::deleteInstructionFromProgram(const Instruction *I,
unsigned Simplification) {
// FIXME, use vmap?
- Module *Clone = CloneModule(Program);
+ Module *Clone = CloneModule(Program).release();
const BasicBlock *PBB = I->getParent();
const Function *PF = PBB->getParent();
}
ValueToValueMapTy NewVMap;
- Module *New = CloneModule(M, NewVMap);
+ Module *New = CloneModule(M, NewVMap).release();
// Remove the Test functions from the Safe module
std::set<Function *> TestFunctions;
bool &Broken) {
// Link the two portions of the program back to together.
if (!DeleteInputs) {
- M1 = CloneModule(M1);
- M2 = CloneModule(M2);
+ M1 = CloneModule(M1).release();
+ M2 = CloneModule(M2).release();
}
if (Linker::linkModules(*M1, *M2, diagnosticHandler))
exit(1);
// we can conclude that a function triggers the bug when in fact one
// needs a larger set of original functions to do so.
ValueToValueMapTy VMap;
- Module *Clone = CloneModule(BD.getProgram(), VMap);
+ Module *Clone = CloneModule(BD.getProgram(), VMap).release();
Module *Orig = BD.swapProgramIn(Clone);
std::vector<Function*> FuncsOnClone;
// Split the module into the two halves of the program we want.
VMap.clear();
- Module *ToNotOptimize = CloneModule(BD.getProgram(), VMap);
+ Module *ToNotOptimize = CloneModule(BD.getProgram(), VMap).release();
Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize, FuncsOnClone,
VMap);
if (BugpointIsInterrupted) return MadeChange;
ValueToValueMapTy VMap;
- Module *ToNotOptimize = CloneModule(BD.getProgram(), VMap);
+ Module *ToNotOptimize = CloneModule(BD.getProgram(), VMap).release();
Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize,
MiscompiledFunctions,
VMap);
outs() << " Testing after loop extraction:\n";
// Clone modules, the tester function will free them.
- Module *TOLEBackup = CloneModule(ToOptimizeLoopExtracted, VMap);
- Module *TNOBackup = CloneModule(ToNotOptimize, VMap);
+ Module *TOLEBackup = CloneModule(ToOptimizeLoopExtracted, VMap).release();
+ Module *TNOBackup = CloneModule(ToNotOptimize, VMap).release();
for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i)
MiscompiledFunctions[i] = cast<Function>(VMap[MiscompiledFunctions[i]]);
// Split the module into the two halves of the program we want.
ValueToValueMapTy VMap;
- Module *Clone = CloneModule(BD.getProgram(), VMap);
+ Module *Clone = CloneModule(BD.getProgram(), VMap).release();
Module *Orig = BD.swapProgramIn(Clone);
std::vector<Function*> FuncsOnClone;
std::vector<BasicBlock*> BBsOnClone;
}
VMap.clear();
- Module *ToNotOptimize = CloneModule(BD.getProgram(), VMap);
+ Module *ToNotOptimize = CloneModule(BD.getProgram(), VMap).release();
Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize,
FuncsOnClone,
VMap);
}
ValueToValueMapTy VMap;
- Module *ProgClone = CloneModule(BD.getProgram(), VMap);
+ Module *ProgClone = CloneModule(BD.getProgram(), VMap).release();
Module *ToExtract = SplitFunctionsOutOfModule(ProgClone,
MiscompiledFunctions,
VMap);
// Output a bunch of bitcode files for the user...
outs() << "Outputting reduced bitcode files which expose the problem:\n";
ValueToValueMapTy VMap;
- Module *ToNotOptimize = CloneModule(getProgram(), VMap);
+ Module *ToNotOptimize = CloneModule(getProgram(), VMap).release();
Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize,
MiscompiledFunctions,
VMap);
// Split the module into the two halves of the program we want.
ValueToValueMapTy VMap;
- Module *ToNotCodeGen = CloneModule(getProgram(), VMap);
+ Module *ToNotCodeGen = CloneModule(getProgram(), VMap).release();
Module *ToCodeGen = SplitFunctionsOutOfModule(ToNotCodeGen, Funcs, VMap);
// Condition the modules
IBuilder.CreateRetVoid();
}
- void CreateNewModule() { NewM = llvm::CloneModule(OldM); }
+ void CreateNewModule() { NewM = llvm::CloneModule(OldM).release(); }
LLVMContext C;
Module *OldM;