namespace {
class ReduceMiscompilingFunctions : public ListReducer<Function*> {
BugDriver &BD;
- bool (*TestFn)(BugDriver &, Module *, Module *, std::string &);
+ bool (*TestFn)(BugDriver &, std::unique_ptr<Module>,
+ std::unique_ptr<Module>, std::string &);
+
public:
ReduceMiscompilingFunctions(BugDriver &bd,
- bool (*F)(BugDriver &, Module *, Module *,
+ bool (*F)(BugDriver &, std::unique_ptr<Module>,
+ std::unique_ptr<Module>,
std::string &))
- : BD(bd), TestFn(F) {}
+ : BD(bd), TestFn(F) {}
TestResult doTest(std::vector<Function*> &Prefix,
std::vector<Function*> &Suffix,
// Split the module into the two halves of the program we want.
VMap.clear();
- Module *ToNotOptimize = CloneModule(BD.getProgram(), VMap).release();
- Module *ToOptimize =
- SplitFunctionsOutOfModule(ToNotOptimize, FuncsOnClone, VMap).release();
+ std::unique_ptr<Module> ToNotOptimize = CloneModule(BD.getProgram(), VMap);
+ std::unique_ptr<Module> ToOptimize =
+ SplitFunctionsOutOfModule(ToNotOptimize.get(), FuncsOnClone, VMap);
- // Run the predicate, note that the predicate will delete both input modules.
- bool Broken = TestFn(BD, ToOptimize, ToNotOptimize, Error);
+ bool Broken =
+ TestFn(BD, std::move(ToOptimize), std::move(ToNotOptimize), Error);
delete BD.swapProgramIn(Orig);
I->setName("anon_fn");
}
-/// ExtractLoops - Given a reduced list of functions that still exposed the bug,
-/// check to see if we can extract the loops in the region without obscuring the
-/// bug. If so, it reduces the amount of code identified.
+/// Given a reduced list of functions that still exposed the bug, check to see
+/// if we can extract the loops in the region without obscuring the bug. If so,
+/// it reduces the amount of code identified.
///
static bool ExtractLoops(BugDriver &BD,
- bool (*TestFn)(BugDriver &, Module *, Module *,
- std::string &),
- std::vector<Function*> &MiscompiledFunctions,
+ bool (*TestFn)(BugDriver &, std::unique_ptr<Module>,
+ std::unique_ptr<Module>, std::string &),
+ std::vector<Function *> &MiscompiledFunctions,
std::string &Error) {
bool MadeChange = false;
while (1) {
for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i)
MiscompiledFunctions[i] = cast<Function>(VMap[MiscompiledFunctions[i]]);
- Failure =
- TestFn(BD, ToOptimizeLoopExtracted.get(), ToNotOptimize.get(), Error);
+ Failure = TestFn(BD, std::move(ToOptimizeLoopExtracted),
+ std::move(ToNotOptimize), Error);
if (!Error.empty())
return false;
namespace {
class ReduceMiscompiledBlocks : public ListReducer<BasicBlock*> {
BugDriver &BD;
- bool (*TestFn)(BugDriver &, Module *, Module *, std::string &);
+ bool (*TestFn)(BugDriver &, std::unique_ptr<Module>,
+ std::unique_ptr<Module>, std::string &);
std::vector<Function*> FunctionsBeingTested;
public:
ReduceMiscompiledBlocks(BugDriver &bd,
- bool (*F)(BugDriver &, Module *, Module *,
- std::string &),
- const std::vector<Function*> &Fns)
- : BD(bd), TestFn(F), FunctionsBeingTested(Fns) {}
+ bool (*F)(BugDriver &, std::unique_ptr<Module>,
+ std::unique_ptr<Module>, std::string &),
+ const std::vector<Function *> &Fns)
+ : BD(bd), TestFn(F), FunctionsBeingTested(Fns) {}
TestResult doTest(std::vector<BasicBlock*> &Prefix,
std::vector<BasicBlock*> &Suffix,
}
VMap.clear();
- Module *ToNotOptimize = CloneModule(BD.getProgram(), VMap).release();
- Module *ToOptimize =
- SplitFunctionsOutOfModule(ToNotOptimize, FuncsOnClone, VMap).release();
+ std::unique_ptr<Module> ToNotOptimize = CloneModule(BD.getProgram(), VMap);
+ std::unique_ptr<Module> ToOptimize =
+ SplitFunctionsOutOfModule(ToNotOptimize.get(), FuncsOnClone, VMap);
// Try the extraction. If it doesn't work, then the block extractor crashed
// or something, in which case bugpoint can't chase down this possibility.
if (std::unique_ptr<Module> New =
- BD.extractMappedBlocksFromModule(BBsOnClone, ToOptimize)) {
- delete ToOptimize;
- // Run the predicate,
- // note that the predicate will delete both input modules.
- bool Ret = TestFn(BD, New.get(), ToNotOptimize, Error);
+ BD.extractMappedBlocksFromModule(BBsOnClone, ToOptimize.get())) {
+ bool Ret = TestFn(BD, std::move(New), std::move(ToNotOptimize), Error);
delete BD.swapProgramIn(Orig);
return Ret;
}
delete BD.swapProgramIn(Orig);
- delete ToOptimize;
- delete ToNotOptimize;
return false;
}
-
-/// ExtractBlocks - Given a reduced list of functions that still expose the bug,
-/// extract as many basic blocks from the region as possible without obscuring
-/// the bug.
+/// Given a reduced list of functions that still expose the bug, extract as many
+/// basic blocks from the region as possible without obscuring the bug.
///
static bool ExtractBlocks(BugDriver &BD,
- bool (*TestFn)(BugDriver &, Module *, Module *,
+ bool (*TestFn)(BugDriver &, std::unique_ptr<Module>,
+ std::unique_ptr<Module>,
std::string &),
- std::vector<Function*> &MiscompiledFunctions,
+ std::vector<Function *> &MiscompiledFunctions,
std::string &Error) {
if (BugpointIsInterrupted) return false;
return true;
}
-
-/// DebugAMiscompilation - This is a generic driver to narrow down
-/// miscompilations, either in an optimization or a code generator.
+/// This is a generic driver to narrow down miscompilations, either in an
+/// optimization or a code generator.
///
-static std::vector<Function*>
+static std::vector<Function *>
DebugAMiscompilation(BugDriver &BD,
- bool (*TestFn)(BugDriver &, Module *, Module *,
- std::string &),
+ bool (*TestFn)(BugDriver &, std::unique_ptr<Module>,
+ std::unique_ptr<Module>, std::string &),
std::string &Error) {
// Okay, now that we have reduced the list of passes which are causing the
// failure, see if we can pin down which functions are being
return MiscompiledFunctions;
}
-/// TestOptimizer - This is the predicate function used to check to see if the
-/// "Test" portion of the program is misoptimized. If so, return true. In any
-/// case, both module arguments are deleted.
+/// This is the predicate function used to check to see if the "Test" portion of
+/// the program is misoptimized. If so, return true. In any case, both module
+/// arguments are deleted.
///
-static bool TestOptimizer(BugDriver &BD, Module *Test, Module *Safe,
- std::string &Error) {
+static bool TestOptimizer(BugDriver &BD, std::unique_ptr<Module> Test,
+ std::unique_ptr<Module> Safe, std::string &Error) {
// Run the optimization passes on ToOptimize, producing a transformed version
// of the functions being tested.
outs() << " Optimizing functions being tested: ";
- std::unique_ptr<Module> Optimized = BD.runPassesOn(Test, BD.getPassesToRun(),
- /*AutoDebugCrashes*/ true);
+ std::unique_ptr<Module> Optimized =
+ BD.runPassesOn(Test.get(), BD.getPassesToRun(),
+ /*AutoDebugCrashes*/ true);
outs() << "done.\n";
- delete Test;
outs() << " Checking to see if the merged program executes correctly: ";
bool Broken;
Module *New =
- TestMergedProgram(BD, Optimized.get(), Safe, true, Error, Broken);
+ TestMergedProgram(BD, Optimized.get(), Safe.get(), true, Error, Broken);
if (New) {
outs() << (Broken ? " nope.\n" : " yup.\n");
// Delete the original and set the new program.
return;
}
-/// CleanupAndPrepareModules - Get the specified modules ready for code
-/// generator testing.
+/// Get the specified modules ready for code generator testing.
///
-static void CleanupAndPrepareModules(BugDriver &BD, Module *&Test,
+static void CleanupAndPrepareModules(BugDriver &BD,
+ std::unique_ptr<Module> &Test,
Module *Safe) {
// Clean up the modules, removing extra cruft that we don't need anymore...
- Test = BD.performFinalCleanups(Test).release();
+ Test = BD.performFinalCleanups(Test.get());
// If we are executing the JIT, we have several nasty issues to take care of.
if (!BD.isExecutingJIT()) return;
// Rename it
oldMain->setName("llvm_bugpoint_old_main");
// Create a NEW `main' function with same type in the test module.
- Function *newMain = Function::Create(oldMain->getFunctionType(),
- GlobalValue::ExternalLinkage,
- "main", Test);
+ Function *newMain =
+ Function::Create(oldMain->getFunctionType(),
+ GlobalValue::ExternalLinkage, "main", Test.get());
// Create an `oldmain' prototype in the test module, which will
// corresponds to the real main function in the same module.
Function *oldMainProto = Function::Create(oldMain->getFunctionType(),
GlobalValue::ExternalLinkage,
- oldMain->getName(), Test);
+ oldMain->getName(), Test.get());
// Set up and remember the argument list for the main function.
std::vector<Value*> args;
for (Function::arg_iterator
}
}
-
-
-/// TestCodeGenerator - This is the predicate function used to check to see if
-/// the "Test" portion of the program is miscompiled by the code generator under
-/// test. If so, return true. In any case, both module arguments are deleted.
+/// This is the predicate function used to check to see if the "Test" portion of
+/// the program is miscompiled by the code generator under test. If so, return
+/// true. In any case, both module arguments are deleted.
///
-static bool TestCodeGenerator(BugDriver &BD, Module *Test, Module *Safe,
+static bool TestCodeGenerator(BugDriver &BD, std::unique_ptr<Module> Test,
+ std::unique_ptr<Module> Safe,
std::string &Error) {
- CleanupAndPrepareModules(BD, Test, Safe);
+ CleanupAndPrepareModules(BD, Test, Safe.get());
SmallString<128> TestModuleBC;
int TestModuleFD;
<< EC.message() << "\n";
exit(1);
}
- if (BD.writeProgramToFile(TestModuleBC.str(), TestModuleFD, Test)) {
+ if (BD.writeProgramToFile(TestModuleBC.str(), TestModuleFD, Test.get())) {
errs() << "Error writing bitcode to `" << TestModuleBC.str()
<< "'\nExiting.";
exit(1);
}
- delete Test;
FileRemover TestModuleBCRemover(TestModuleBC.str(), !SaveTemps);
exit(1);
}
- if (BD.writeProgramToFile(SafeModuleBC.str(), SafeModuleFD, Safe)) {
+ if (BD.writeProgramToFile(SafeModuleBC.str(), SafeModuleFD, Safe.get())) {
errs() << "Error writing bitcode to `" << SafeModuleBC
<< "'\nExiting.";
exit(1);
std::string SharedObject = BD.compileSharedObject(SafeModuleBC.str(), Error);
if (!Error.empty())
return false;
- delete Safe;
FileRemover SharedObjectRemover(SharedObject, !SaveTemps);
// Split the module into the two halves of the program we want.
ValueToValueMapTy VMap;
- Module *ToNotCodeGen = CloneModule(getProgram(), VMap).release();
- Module *ToCodeGen =
- SplitFunctionsOutOfModule(ToNotCodeGen, Funcs, VMap).release();
+ std::unique_ptr<Module> ToNotCodeGen = CloneModule(getProgram(), VMap);
+ std::unique_ptr<Module> ToCodeGen =
+ SplitFunctionsOutOfModule(ToNotCodeGen.get(), Funcs, VMap);
// Condition the modules
- CleanupAndPrepareModules(*this, ToCodeGen, ToNotCodeGen);
+ CleanupAndPrepareModules(*this, ToCodeGen, ToNotCodeGen.get());
SmallString<128> TestModuleBC;
int TestModuleFD;
exit(1);
}
- if (writeProgramToFile(TestModuleBC.str(), TestModuleFD, ToCodeGen)) {
+ if (writeProgramToFile(TestModuleBC.str(), TestModuleFD, ToCodeGen.get())) {
errs() << "Error writing bitcode to `" << TestModuleBC
<< "'\nExiting.";
exit(1);
}
- delete ToCodeGen;
// Make the shared library
SmallString<128> SafeModuleBC;
exit(1);
}
- if (writeProgramToFile(SafeModuleBC.str(), SafeModuleFD, ToNotCodeGen)) {
+ if (writeProgramToFile(SafeModuleBC.str(), SafeModuleFD,
+ ToNotCodeGen.get())) {
errs() << "Error writing bitcode to `" << SafeModuleBC
<< "'\nExiting.";
exit(1);
std::string SharedObject = compileSharedObject(SafeModuleBC.str(), *Error);
if (!Error->empty())
return true;
- delete ToNotCodeGen;
outs() << "You can reproduce the problem with the command line: \n";
if (isExecutingJIT()) {