From 0340a6ff3176c0e76e3f11838d0f8a541ea2da67 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 9 Dec 2015 00:51:06 +0000 Subject: [PATCH] Simplify memory management. NFC. This passes std::unique_ptr to predicates that are expected to delete their argument. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@255086 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/bugpoint/Miscompilation.cpp | 151 ++++++++++++++---------------- 1 file changed, 72 insertions(+), 79 deletions(-) diff --git a/tools/bugpoint/Miscompilation.cpp b/tools/bugpoint/Miscompilation.cpp index 0c8b313c6a8..7458a080b10 100644 --- a/tools/bugpoint/Miscompilation.cpp +++ b/tools/bugpoint/Miscompilation.cpp @@ -177,12 +177,15 @@ ReduceMiscompilingPasses::doTest(std::vector &Prefix, namespace { class ReduceMiscompilingFunctions : public ListReducer { BugDriver &BD; - bool (*TestFn)(BugDriver &, Module *, Module *, std::string &); + bool (*TestFn)(BugDriver &, std::unique_ptr, + std::unique_ptr, std::string &); + public: ReduceMiscompilingFunctions(BugDriver &bd, - bool (*F)(BugDriver &, Module *, Module *, + bool (*F)(BugDriver &, std::unique_ptr, + std::unique_ptr, std::string &)) - : BD(bd), TestFn(F) {} + : BD(bd), TestFn(F) {} TestResult doTest(std::vector &Prefix, std::vector &Suffix, @@ -279,12 +282,12 @@ bool ReduceMiscompilingFunctions::TestFuncs(const std::vector &Funcs, // 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 ToNotOptimize = CloneModule(BD.getProgram(), VMap); + std::unique_ptr 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); @@ -303,14 +306,14 @@ static void DisambiguateGlobalSymbols(Module *M) { 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 &MiscompiledFunctions, + bool (*TestFn)(BugDriver &, std::unique_ptr, + std::unique_ptr, std::string &), + std::vector &MiscompiledFunctions, std::string &Error) { bool MadeChange = false; while (1) { @@ -382,8 +385,8 @@ static bool ExtractLoops(BugDriver &BD, for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i) MiscompiledFunctions[i] = cast(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; @@ -451,14 +454,15 @@ static bool ExtractLoops(BugDriver &BD, namespace { class ReduceMiscompiledBlocks : public ListReducer { BugDriver &BD; - bool (*TestFn)(BugDriver &, Module *, Module *, std::string &); + bool (*TestFn)(BugDriver &, std::unique_ptr, + std::unique_ptr, std::string &); std::vector FunctionsBeingTested; public: ReduceMiscompiledBlocks(BugDriver &bd, - bool (*F)(BugDriver &, Module *, Module *, - std::string &), - const std::vector &Fns) - : BD(bd), TestFn(F), FunctionsBeingTested(Fns) {} + bool (*F)(BugDriver &, std::unique_ptr, + std::unique_ptr, std::string &), + const std::vector &Fns) + : BD(bd), TestFn(F), FunctionsBeingTested(Fns) {} TestResult doTest(std::vector &Prefix, std::vector &Suffix, @@ -518,36 +522,30 @@ bool ReduceMiscompiledBlocks::TestFuncs(const std::vector &BBs, } VMap.clear(); - Module *ToNotOptimize = CloneModule(BD.getProgram(), VMap).release(); - Module *ToOptimize = - SplitFunctionsOutOfModule(ToNotOptimize, FuncsOnClone, VMap).release(); + std::unique_ptr ToNotOptimize = CloneModule(BD.getProgram(), VMap); + std::unique_ptr 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 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, + std::unique_ptr, std::string &), - std::vector &MiscompiledFunctions, + std::vector &MiscompiledFunctions, std::string &Error) { if (BugpointIsInterrupted) return false; @@ -620,14 +618,13 @@ static bool ExtractBlocks(BugDriver &BD, 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 +static std::vector DebugAMiscompilation(BugDriver &BD, - bool (*TestFn)(BugDriver &, Module *, Module *, - std::string &), + bool (*TestFn)(BugDriver &, std::unique_ptr, + std::unique_ptr, 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 @@ -706,24 +703,24 @@ DebugAMiscompilation(BugDriver &BD, 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 Test, + std::unique_ptr 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 Optimized = BD.runPassesOn(Test, BD.getPassesToRun(), - /*AutoDebugCrashes*/ true); + std::unique_ptr 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. @@ -776,13 +773,13 @@ void BugDriver::debugMiscompilation(std::string *Error) { 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 &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; @@ -795,14 +792,14 @@ static void CleanupAndPrepareModules(BugDriver &BD, Module *&Test, // 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 args; for (Function::arg_iterator @@ -938,15 +935,14 @@ static void CleanupAndPrepareModules(BugDriver &BD, Module *&Test, } } - - -/// 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 Test, + std::unique_ptr Safe, std::string &Error) { - CleanupAndPrepareModules(BD, Test, Safe); + CleanupAndPrepareModules(BD, Test, Safe.get()); SmallString<128> TestModuleBC; int TestModuleFD; @@ -957,12 +953,11 @@ static bool TestCodeGenerator(BugDriver &BD, Module *Test, Module *Safe, << 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); @@ -977,7 +972,7 @@ static bool TestCodeGenerator(BugDriver &BD, Module *Test, Module *Safe, 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); @@ -988,7 +983,6 @@ static bool TestCodeGenerator(BugDriver &BD, Module *Test, Module *Safe, std::string SharedObject = BD.compileSharedObject(SafeModuleBC.str(), Error); if (!Error.empty()) return false; - delete Safe; FileRemover SharedObjectRemover(SharedObject, !SaveTemps); @@ -1036,12 +1030,12 @@ bool BugDriver::debugCodeGenerator(std::string *Error) { // 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 ToNotCodeGen = CloneModule(getProgram(), VMap); + std::unique_ptr ToCodeGen = + SplitFunctionsOutOfModule(ToNotCodeGen.get(), Funcs, VMap); // Condition the modules - CleanupAndPrepareModules(*this, ToCodeGen, ToNotCodeGen); + CleanupAndPrepareModules(*this, ToCodeGen, ToNotCodeGen.get()); SmallString<128> TestModuleBC; int TestModuleFD; @@ -1053,12 +1047,11 @@ bool BugDriver::debugCodeGenerator(std::string *Error) { 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; @@ -1071,7 +1064,8 @@ bool BugDriver::debugCodeGenerator(std::string *Error) { exit(1); } - if (writeProgramToFile(SafeModuleBC.str(), SafeModuleFD, ToNotCodeGen)) { + if (writeProgramToFile(SafeModuleBC.str(), SafeModuleFD, + ToNotCodeGen.get())) { errs() << "Error writing bitcode to `" << SafeModuleBC << "'\nExiting."; exit(1); @@ -1079,7 +1073,6 @@ bool BugDriver::debugCodeGenerator(std::string *Error) { 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()) { -- 2.34.1