diff options
Diffstat (limited to 'tools/bugpoint')
-rw-r--r-- | tools/bugpoint/Android.mk | 1 | ||||
-rw-r--r-- | tools/bugpoint/BugDriver.cpp | 21 | ||||
-rw-r--r-- | tools/bugpoint/BugDriver.h | 81 | ||||
-rw-r--r-- | tools/bugpoint/CrashDebugger.cpp | 31 | ||||
-rw-r--r-- | tools/bugpoint/ExtractFunction.cpp | 45 | ||||
-rw-r--r-- | tools/bugpoint/ListReducer.h | 4 | ||||
-rw-r--r-- | tools/bugpoint/Miscompilation.cpp | 57 | ||||
-rw-r--r-- | tools/bugpoint/OptimizerDriver.cpp | 50 | ||||
-rw-r--r-- | tools/bugpoint/ToolRunner.cpp | 33 | ||||
-rw-r--r-- | tools/bugpoint/ToolRunner.h | 4 | ||||
-rw-r--r-- | tools/bugpoint/bugpoint.cpp | 14 |
11 files changed, 154 insertions, 187 deletions
diff --git a/tools/bugpoint/Android.mk b/tools/bugpoint/Android.mk index 78f3eff..512a91f 100644 --- a/tools/bugpoint/Android.mk +++ b/tools/bugpoint/Android.mk @@ -35,6 +35,7 @@ bugpoint_STATIC_LIBRARIES := \ libLLVMTarget \ libLLVMCore \ libLLVMMC \ + libLLVMProfileData \ libLLVMTransformUtils \ libLLVMVectorize \ libLLVMSupport \ diff --git a/tools/bugpoint/BugDriver.cpp b/tools/bugpoint/BugDriver.cpp index cecccbe..b8be17e 100644 --- a/tools/bugpoint/BugDriver.cpp +++ b/tools/bugpoint/BugDriver.cpp @@ -82,14 +82,10 @@ BugDriver::~BugDriver() { delete gcc; } - -/// ParseInputFile - Given a bitcode or assembly input filename, parse and -/// return it, or return null if not possible. -/// -Module *llvm::ParseInputFile(const std::string &Filename, - LLVMContext& Ctxt) { +std::unique_ptr<Module> llvm::parseInputFile(StringRef Filename, + LLVMContext &Ctxt) { SMDiagnostic Err; - Module *Result = ParseIRFile(Filename, Err, Ctxt); + std::unique_ptr<Module> Result = parseIRFile(Filename, Err, Ctxt); if (!Result) Err.print("bugpoint", errs()); @@ -120,23 +116,18 @@ bool BugDriver::addSources(const std::vector<std::string> &Filenames) { assert(!Filenames.empty() && "Must specify at least on input filename!"); // Load the first input file. - Program = ParseInputFile(Filenames[0], Context); + Program = parseInputFile(Filenames[0], Context).release(); if (!Program) return true; outs() << "Read input file : '" << Filenames[0] << "'\n"; for (unsigned i = 1, e = Filenames.size(); i != e; ++i) { - std::unique_ptr<Module> M(ParseInputFile(Filenames[i], Context)); + std::unique_ptr<Module> M = parseInputFile(Filenames[i], Context); if (!M.get()) return true; outs() << "Linking in input file: '" << Filenames[i] << "'\n"; - std::string ErrorMessage; - if (Linker::LinkModules(Program, M.get(), Linker::DestroySource, - &ErrorMessage)) { - errs() << ToolName << ": error linking in '" << Filenames[i] << "': " - << ErrorMessage << '\n'; + if (Linker::LinkModules(Program, M.get())) return true; - } } outs() << "*** All input ok\n"; diff --git a/tools/bugpoint/BugDriver.h b/tools/bugpoint/BugDriver.h index 3169d29..5797812 100644 --- a/tools/bugpoint/BugDriver.h +++ b/tools/bugpoint/BugDriver.h @@ -13,11 +13,12 @@ // //===----------------------------------------------------------------------===// -#ifndef BUGDRIVER_H -#define BUGDRIVER_H +#ifndef LLVM_TOOLS_BUGPOINT_BUGDRIVER_H +#define LLVM_TOOLS_BUGPOINT_BUGDRIVER_H #include "llvm/IR/ValueMap.h" #include "llvm/Transforms/Utils/ValueMapper.h" +#include <memory> #include <string> #include <vector> @@ -210,41 +211,46 @@ public: void EmitProgressBitcode(const Module *M, const std::string &ID, bool NoFlyer = false) const; - /// deleteInstructionFromProgram - This method clones the current Program and - /// deletes the specified instruction from the cloned module. It then runs a - /// series of cleanup passes (ADCE and SimplifyCFG) to eliminate any code - /// which depends on the value. The modified module is then returned. + /// This method clones the current Program and deletes the specified + /// instruction from the cloned module. It then runs a series of cleanup + /// passes (ADCE and SimplifyCFG) to eliminate any code which depends on the + /// value. The modified module is then returned. /// - Module *deleteInstructionFromProgram(const Instruction *I, unsigned Simp); + std::unique_ptr<Module> deleteInstructionFromProgram(const Instruction *I, + unsigned Simp); - /// performFinalCleanups - This method clones the current Program and performs - /// a series of cleanups intended to get rid of extra cruft on the module. If - /// the MayModifySemantics argument is true, then the cleanups is allowed to + /// This method clones the current Program and performs a series of cleanups + /// intended to get rid of extra cruft on the module. If the + /// MayModifySemantics argument is true, then the cleanups is allowed to /// modify how the code behaves. /// - Module *performFinalCleanups(Module *M, bool MayModifySemantics = false); - - /// ExtractLoop - Given a module, extract up to one loop from it into a new - /// function. This returns null if there are no extractable loops in the - /// program or if the loop extractor crashes. - Module *ExtractLoop(Module *M); - - /// ExtractMappedBlocksFromModule - Extract all but the specified basic blocks - /// into their own functions. The only detail is that M is actually a module - /// cloned from the one the BBs are in, so some mapping needs to be performed. - /// If this operation fails for some reason (ie the implementation is buggy), - /// this function should return null, otherwise it returns a new Module. - Module *ExtractMappedBlocksFromModule(const std::vector<BasicBlock*> &BBs, - Module *M); - - /// runPassesOn - Carefully run the specified set of pass on the specified - /// module, returning the transformed module on success, or a null pointer on - /// failure. If AutoDebugCrashes is set to true, then bugpoint will - /// automatically attempt to track down a crashing pass if one exists, and - /// this method will never return null. - Module *runPassesOn(Module *M, const std::vector<std::string> &Passes, - bool AutoDebugCrashes = false, unsigned NumExtraArgs = 0, - const char * const *ExtraArgs = nullptr); + std::unique_ptr<Module> performFinalCleanups(Module *M, + bool MayModifySemantics = false); + + /// Given a module, extract up to one loop from it into a new function. This + /// returns null if there are no extractable loops in the program or if the + /// loop extractor crashes. + std::unique_ptr<Module> extractLoop(Module *M); + + /// Extract all but the specified basic blocks into their own functions. The + /// only detail is that M is actually a module cloned from the one the BBs are + /// in, so some mapping needs to be performed. If this operation fails for + /// some reason (ie the implementation is buggy), this function should return + /// null, otherwise it returns a new Module. + std::unique_ptr<Module> + extractMappedBlocksFromModule(const std::vector<BasicBlock *> &BBs, + Module *M); + + /// Carefully run the specified set of pass on the specified/ module, + /// returning the transformed module on success, or a null pointer on failure. + /// If AutoDebugCrashes is set to true, then bugpoint will automatically + /// attempt to track down a crashing pass if one exists, and this method will + /// never return null. + std::unique_ptr<Module> runPassesOn(Module *M, + const std::vector<std::string> &Passes, + bool AutoDebugCrashes = false, + unsigned NumExtraArgs = 0, + const char *const *ExtraArgs = nullptr); /// runPasses - Run the specified passes on Program, outputting a bitcode /// file and writting the filename into OutputFile if successful. If the @@ -296,12 +302,11 @@ private: bool initializeExecutionEnvironment(); }; -/// ParseInputFile - Given a bitcode or assembly input filename, parse and -/// return it, or return null if not possible. +/// Given a bitcode or assembly input filename, parse and return it, or return +/// null if not possible. /// -Module *ParseInputFile(const std::string &InputFilename, - LLVMContext& ctxt); - +std::unique_ptr<Module> parseInputFile(StringRef InputFilename, + LLVMContext &ctxt); /// getPassesString - Turn a list of passes into a string which indicates the /// command line options that must be passed to add the passes. diff --git a/tools/bugpoint/CrashDebugger.cpp b/tools/bugpoint/CrashDebugger.cpp index 8bd61b3..bac948a 100644 --- a/tools/bugpoint/CrashDebugger.cpp +++ b/tools/bugpoint/CrashDebugger.cpp @@ -72,7 +72,7 @@ ReducePassList::doTest(std::vector<std::string> &Prefix, OrigProgram = BD.Program; - BD.Program = ParseInputFile(PrefixOutput, BD.getContext()); + BD.Program = parseInputFile(PrefixOutput, BD.getContext()).release(); if (BD.Program == nullptr) { errs() << BD.getToolName() << ": Error reading bitcode file '" << PrefixOutput << "'!\n"; @@ -312,22 +312,21 @@ bool ReduceCrashingBlocks::TestBlocks(std::vector<const BasicBlock*> &BBs) { // have to take. std::vector<std::pair<std::string, std::string> > BlockInfo; - for (SmallPtrSet<BasicBlock*, 8>::iterator I = Blocks.begin(), - E = Blocks.end(); I != E; ++I) - BlockInfo.push_back(std::make_pair((*I)->getParent()->getName(), - (*I)->getName())); + for (BasicBlock *BB : Blocks) + BlockInfo.push_back(std::make_pair(BB->getParent()->getName(), + BB->getName())); // Now run the CFG simplify pass on the function... std::vector<std::string> Passes; Passes.push_back("simplifycfg"); Passes.push_back("verify"); - Module *New = BD.runPassesOn(M, Passes); + std::unique_ptr<Module> New = BD.runPassesOn(M, Passes); delete M; if (!New) { errs() << "simplifycfg failed!\n"; exit(1); } - M = New; + M = New.release(); // Try running on the hacked up program... if (TestFn(BD, M)) { @@ -420,9 +419,8 @@ bool ReduceCrashingInstructions::TestInsts(std::vector<const Instruction*> // Make sure to use instruction pointers that point into the now-current // module, and that they don't include any deleted blocks. Insts.clear(); - for (SmallPtrSet<Instruction*, 64>::const_iterator I = Instructions.begin(), - E = Instructions.end(); I != E; ++I) - Insts.push_back(*I); + for (Instruction *Inst : Instructions) + Insts.push_back(Inst); return true; } delete M; // It didn't crash, try something else. @@ -578,20 +576,17 @@ static bool DebugACrash(BugDriver &BD, continue; outs() << "Checking instruction: " << *I; - Module *M = BD.deleteInstructionFromProgram(I, Simplification); + std::unique_ptr<Module> M = + BD.deleteInstructionFromProgram(I, Simplification); // Find out if the pass still crashes on this pass... - if (TestFn(BD, M)) { + if (TestFn(BD, M.get())) { // Yup, it does, we delete the old module, and continue trying // to reduce the testcase... - BD.setNewProgram(M); + BD.setNewProgram(M.release()); InstructionsToSkipBeforeDeleting = CurInstructionNum; goto TryAgain; // I wish I had a multi-level break here! } - - // This pass didn't crash without this instruction, try the next - // one. - delete M; } } @@ -607,7 +602,7 @@ ExitLoops: if (!BugpointIsInterrupted) { outs() << "\n*** Attempting to perform final cleanups: "; Module *M = CloneModule(BD.getProgram()); - M = BD.performFinalCleanups(M, true); + M = BD.performFinalCleanups(M, true).release(); // Find out if the pass still crashes on the cleaned up program... if (TestFn(BD, M)) { diff --git a/tools/bugpoint/ExtractFunction.cpp b/tools/bugpoint/ExtractFunction.cpp index 4fb6856..34fe53c 100644 --- a/tools/bugpoint/ExtractFunction.cpp +++ b/tools/bugpoint/ExtractFunction.cpp @@ -82,13 +82,9 @@ namespace { } } // end anonymous namespace -/// deleteInstructionFromProgram - This method clones the current Program and -/// deletes the specified instruction from the cloned module. It then runs a -/// series of cleanup passes (ADCE and SimplifyCFG) to eliminate any code which -/// depends on the value. The modified module is then returned. -/// -Module *BugDriver::deleteInstructionFromProgram(const Instruction *I, - unsigned Simplification) { +std::unique_ptr<Module> +BugDriver::deleteInstructionFromProgram(const Instruction *I, + unsigned Simplification) { // FIXME, use vmap? Module *Clone = CloneModule(Program); @@ -123,7 +119,7 @@ Module *BugDriver::deleteInstructionFromProgram(const Instruction *I, Passes.push_back("simplifycfg"); // Delete dead control flow Passes.push_back("verify"); - Module *New = runPassesOn(Clone, Passes); + std::unique_ptr<Module> New = runPassesOn(Clone, Passes); delete Clone; if (!New) { errs() << "Instruction removal failed. Sorry. :( Please report a bug!\n"; @@ -132,11 +128,8 @@ Module *BugDriver::deleteInstructionFromProgram(const Instruction *I, return New; } -/// performFinalCleanups - This method clones the current Program and performs -/// a series of cleanups intended to get rid of extra cruft on the module -/// before handing it to the user. -/// -Module *BugDriver::performFinalCleanups(Module *M, bool MayModifySemantics) { +std::unique_ptr<Module> +BugDriver::performFinalCleanups(Module *M, bool MayModifySemantics) { // Make all functions external, so GlobalDCE doesn't delete them... for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) I->setLinkage(GlobalValue::ExternalLinkage); @@ -149,24 +142,20 @@ Module *BugDriver::performFinalCleanups(Module *M, bool MayModifySemantics) { else CleanupPasses.push_back("deadargelim"); - Module *New = runPassesOn(M, CleanupPasses); + std::unique_ptr<Module> New = runPassesOn(M, CleanupPasses); if (!New) { errs() << "Final cleanups failed. Sorry. :( Please report a bug!\n"; - return M; + return nullptr; } delete M; return New; } - -/// ExtractLoop - Given a module, extract up to one loop from it into a new -/// function. This returns null if there are no extractable loops in the -/// program or if the loop extractor crashes. -Module *BugDriver::ExtractLoop(Module *M) { +std::unique_ptr<Module> BugDriver::extractLoop(Module *M) { std::vector<std::string> LoopExtractPasses; LoopExtractPasses.push_back("loop-extract-single"); - Module *NewM = runPassesOn(M, LoopExtractPasses); + std::unique_ptr<Module> NewM = runPassesOn(M, LoopExtractPasses); if (!NewM) { outs() << "*** Loop extraction failed: "; EmitProgressBitcode(M, "loopextraction", true); @@ -179,7 +168,6 @@ Module *BugDriver::ExtractLoop(Module *M) { // to avoid taking forever. static unsigned NumExtracted = 32; if (M->size() == NewM->size() || --NumExtracted == 0) { - delete NewM; return nullptr; } else { assert(M->size() < NewM->size() && "Loop extract removed functions?"); @@ -356,14 +344,9 @@ llvm::SplitFunctionsOutOfModule(Module *M, // Basic Block Extraction Code //===----------------------------------------------------------------------===// -/// ExtractMappedBlocksFromModule - Extract all but the specified basic blocks -/// into their own functions. The only detail is that M is actually a module -/// cloned from the one the BBs are in, so some mapping needs to be performed. -/// If this operation fails for some reason (ie the implementation is buggy), -/// this function should return null, otherwise it returns a new Module. -Module *BugDriver::ExtractMappedBlocksFromModule(const - std::vector<BasicBlock*> &BBs, - Module *M) { +std::unique_ptr<Module> +BugDriver::extractMappedBlocksFromModule(const std::vector<BasicBlock *> &BBs, + Module *M) { SmallString<128> Filename; int FD; std::error_code EC = sys::fs::createUniqueFile( @@ -401,7 +384,7 @@ Module *BugDriver::ExtractMappedBlocksFromModule(const std::vector<std::string> PI; PI.push_back("extract-blocks"); - Module *Ret = runPassesOn(M, PI, false, 1, &ExtraArg); + std::unique_ptr<Module> Ret = runPassesOn(M, PI, false, 1, &ExtraArg); sys::fs::remove(Filename.c_str()); diff --git a/tools/bugpoint/ListReducer.h b/tools/bugpoint/ListReducer.h index 8083e2d..a0bb570 100644 --- a/tools/bugpoint/ListReducer.h +++ b/tools/bugpoint/ListReducer.h @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef BUGPOINT_LIST_REDUCER_H -#define BUGPOINT_LIST_REDUCER_H +#ifndef LLVM_TOOLS_BUGPOINT_LISTREDUCER_H +#define LLVM_TOOLS_BUGPOINT_LISTREDUCER_H #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" diff --git a/tools/bugpoint/Miscompilation.cpp b/tools/bugpoint/Miscompilation.cpp index 3f1f84e..8cb4583 100644 --- a/tools/bugpoint/Miscompilation.cpp +++ b/tools/bugpoint/Miscompilation.cpp @@ -128,8 +128,8 @@ ReduceMiscompilingPasses::doTest(std::vector<std::string> &Prefix, // Ok, so now we know that the prefix passes work, try running the suffix // passes on the result of the prefix passes. // - std::unique_ptr<Module> PrefixOutput( - ParseInputFile(BitcodeResult, BD.getContext())); + std::unique_ptr<Module> PrefixOutput = + parseInputFile(BitcodeResult, BD.getContext()); if (!PrefixOutput) { errs() << BD.getToolName() << ": Error reading bitcode file '" << BitcodeResult << "'!\n"; @@ -218,16 +218,12 @@ static Module *TestMergedProgram(const BugDriver &BD, Module *M1, Module *M2, bool DeleteInputs, std::string &Error, bool &Broken) { // Link the two portions of the program back to together. - std::string ErrorMsg; if (!DeleteInputs) { M1 = CloneModule(M1); M2 = CloneModule(M2); } - if (Linker::LinkModules(M1, M2, Linker::DestroySource, &ErrorMsg)) { - errs() << BD.getToolName() << ": Error linking modules together:" - << ErrorMsg << '\n'; + if (Linker::LinkModules(M1, M2)) exit(1); - } delete M2; // We are done with this module. // Execute the program. @@ -316,7 +312,7 @@ static bool ExtractLoops(BugDriver &BD, Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize, MiscompiledFunctions, VMap); - Module *ToOptimizeLoopExtracted = BD.ExtractLoop(ToOptimize); + Module *ToOptimizeLoopExtracted = BD.extractLoop(ToOptimize).release(); if (!ToOptimizeLoopExtracted) { // If the loop extractor crashed or if there were no extractible loops, // then this chapter of our odyssey is over with. @@ -334,8 +330,8 @@ static bool ExtractLoops(BugDriver &BD, // extraction. AbstractInterpreter *AI = BD.switchToSafeInterpreter(); bool Failure; - Module *New = TestMergedProgram(BD, ToOptimizeLoopExtracted, ToNotOptimize, - false, Error, Failure); + Module *New = TestMergedProgram(BD, ToOptimizeLoopExtracted, + ToNotOptimize, false, Error, Failure); if (!New) return false; @@ -364,7 +360,6 @@ static bool ExtractLoops(BugDriver &BD, << OutputPrefix << "-loop-extract-fail-*.bc files.\n"; delete ToOptimize; delete ToNotOptimize; - delete ToOptimizeLoopExtracted; return MadeChange; } delete ToOptimize; @@ -397,13 +392,8 @@ static bool ExtractLoops(BugDriver &BD, F->getFunctionType())); } - std::string ErrorMsg; - if (Linker::LinkModules(ToNotOptimize, ToOptimizeLoopExtracted, - Linker::DestroySource, &ErrorMsg)){ - errs() << BD.getToolName() << ": Error linking modules together:" - << ErrorMsg << '\n'; + if (Linker::LinkModules(ToNotOptimize, ToOptimizeLoopExtracted)) exit(1); - } MiscompiledFunctions.clear(); for (unsigned i = 0, e = MisCompFunctions.size(); i != e; ++i) { @@ -431,13 +421,9 @@ static bool ExtractLoops(BugDriver &BD, // extraction both didn't break the program, and didn't mask the problem. // Replace the current program with the loop extracted version, and try to // extract another loop. - std::string ErrorMsg; - if (Linker::LinkModules(ToNotOptimize, ToOptimizeLoopExtracted, - Linker::DestroySource, &ErrorMsg)){ - errs() << BD.getToolName() << ": Error linking modules together:" - << ErrorMsg << '\n'; + if (Linker::LinkModules(ToNotOptimize, ToOptimizeLoopExtracted)) exit(1); - } + delete ToOptimizeLoopExtracted; // All of the Function*'s in the MiscompiledFunctions list are in the old @@ -533,11 +519,12 @@ bool ReduceMiscompiledBlocks::TestFuncs(const std::vector<BasicBlock*> &BBs, // 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 (Module *New = BD.ExtractMappedBlocksFromModule(BBsOnClone, ToOptimize)) { + 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, ToNotOptimize, Error); + bool Ret = TestFn(BD, New.get(), ToNotOptimize, Error); delete BD.swapProgramIn(Orig); return Ret; } @@ -591,7 +578,8 @@ static bool ExtractBlocks(BugDriver &BD, Module *ToExtract = SplitFunctionsOutOfModule(ProgClone, MiscompiledFunctions, VMap); - Module *Extracted = BD.ExtractMappedBlocksFromModule(Blocks, ToExtract); + std::unique_ptr<Module> Extracted = + BD.extractMappedBlocksFromModule(Blocks, ToExtract); if (!Extracted) { // Weird, extraction should have worked. errs() << "Nondeterministic problem extracting blocks??\n"; @@ -611,14 +599,8 @@ static bool ExtractBlocks(BugDriver &BD, MisCompFunctions.push_back(std::make_pair(I->getName(), I->getFunctionType())); - std::string ErrorMsg; - if (Linker::LinkModules(ProgClone, Extracted, Linker::DestroySource, - &ErrorMsg)) { - errs() << BD.getToolName() << ": Error linking modules together:" - << ErrorMsg << '\n'; + if (Linker::LinkModules(ProgClone, Extracted.get())) exit(1); - } - delete Extracted; // Set the new program and delete the old one. BD.setNewProgram(ProgClone); @@ -730,14 +712,15 @@ static bool TestOptimizer(BugDriver &BD, Module *Test, Module *Safe, // Run the optimization passes on ToOptimize, producing a transformed version // of the functions being tested. outs() << " Optimizing functions being tested: "; - Module *Optimized = BD.runPassesOn(Test, BD.getPassesToRun(), - /*AutoDebugCrashes*/true); + std::unique_ptr<Module> Optimized = BD.runPassesOn(Test, 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, Safe, true, Error, Broken); + Module *New = + TestMergedProgram(BD, Optimized.get(), Safe, true, Error, Broken); if (New) { outs() << (Broken ? " nope.\n" : " yup.\n"); // Delete the original and set the new program. @@ -796,7 +779,7 @@ void BugDriver::debugMiscompilation(std::string *Error) { static void CleanupAndPrepareModules(BugDriver &BD, Module *&Test, Module *Safe) { // Clean up the modules, removing extra cruft that we don't need anymore... - Test = BD.performFinalCleanups(Test); + Test = BD.performFinalCleanups(Test).release(); // If we are executing the JIT, we have several nasty issues to take care of. if (!BD.isExecutingJIT()) return; diff --git a/tools/bugpoint/OptimizerDriver.cpp b/tools/bugpoint/OptimizerDriver.cpp index d452fd9..f197cc5 100644 --- a/tools/bugpoint/OptimizerDriver.cpp +++ b/tools/bugpoint/OptimizerDriver.cpp @@ -66,15 +66,15 @@ static bool writeProgramToFileAux(tool_output_file &Out, const Module *M) { bool BugDriver::writeProgramToFile(const std::string &Filename, int FD, const Module *M) const { - tool_output_file Out(Filename.c_str(), FD); + tool_output_file Out(Filename, FD); return writeProgramToFileAux(Out, M); } bool BugDriver::writeProgramToFile(const std::string &Filename, const Module *M) const { - std::string ErrInfo; - tool_output_file Out(Filename.c_str(), ErrInfo, sys::fs::F_None); - if (ErrInfo.empty()) + std::error_code EC; + tool_output_file Out(Filename, EC, sys::fs::F_None); + if (!EC) return writeProgramToFileAux(Out, M); return true; } @@ -149,7 +149,7 @@ bool BugDriver::runPasses(Module *Program, return 1; } - tool_output_file InFile(InputFilename.c_str(), InputFD); + tool_output_file InFile(InputFilename, InputFD); WriteBitcodeToFile(Program, InFile.os()); InFile.os().close(); @@ -159,12 +159,31 @@ bool BugDriver::runPasses(Module *Program, return 1; } - std::string tool = OptCmd.empty()? sys::FindProgramByName("opt") : OptCmd; + std::string tool = OptCmd; + if (OptCmd.empty()) { + if (ErrorOr<std::string> Path = sys::findProgramByName("opt")) + tool = *Path; + else + errs() << Path.getError().message() << "\n"; + } if (tool.empty()) { errs() << "Cannot find `opt' in PATH!\n"; return 1; } + std::string Prog; + if (UseValgrind) { + if (ErrorOr<std::string> Path = sys::findProgramByName("valgrind")) + Prog = *Path; + else + errs() << Path.getError().message() << "\n"; + } else + Prog = tool; + if (Prog.empty()) { + errs() << "Cannot find `valgrind' in PATH!\n"; + return 1; + } + // Ok, everything that could go wrong before running opt is done. InFile.keep(); @@ -204,12 +223,6 @@ bool BugDriver::runPasses(Module *Program, errs() << "\n"; ); - std::string Prog; - if (UseValgrind) - Prog = sys::FindProgramByName("valgrind"); - else - Prog = tool; - // Redirect stdout and stderr to nowhere if SilencePasses is given StringRef Nowhere; const StringRef *Redirects[3] = {nullptr, &Nowhere, &Nowhere}; @@ -247,13 +260,10 @@ bool BugDriver::runPasses(Module *Program, } -/// runPassesOn - Carefully run the specified set of pass on the specified -/// module, returning the transformed module on success, or a null pointer on -/// failure. -Module *BugDriver::runPassesOn(Module *M, - const std::vector<std::string> &Passes, - bool AutoDebugCrashes, unsigned NumExtraArgs, - const char * const *ExtraArgs) { +std::unique_ptr<Module> +BugDriver::runPassesOn(Module *M, const std::vector<std::string> &Passes, + bool AutoDebugCrashes, unsigned NumExtraArgs, + const char *const *ExtraArgs) { std::string BitcodeResult; if (runPasses(M, Passes, BitcodeResult, false/*delete*/, true/*quiet*/, NumExtraArgs, ExtraArgs)) { @@ -267,7 +277,7 @@ Module *BugDriver::runPassesOn(Module *M, return nullptr; } - Module *Ret = ParseInputFile(BitcodeResult, Context); + std::unique_ptr<Module> Ret = parseInputFile(BitcodeResult, Context); if (!Ret) { errs() << getToolName() << ": Error reading bitcode file '" << BitcodeResult << "'!\n"; diff --git a/tools/bugpoint/ToolRunner.cpp b/tools/bugpoint/ToolRunner.cpp index 4a2401b..51091e2 100644 --- a/tools/bugpoint/ToolRunner.cpp +++ b/tools/bugpoint/ToolRunner.cpp @@ -141,13 +141,13 @@ static std::string ProcessFailure(StringRef ProgPath, const char** Args, // Rerun the compiler, capturing any error messages to print them. SmallString<128> ErrorFilename; - int ErrorFD; std::error_code EC = sys::fs::createTemporaryFile( - "bugpoint.program_error_messages", "", ErrorFD, ErrorFilename); + "bugpoint.program_error_messages", "", ErrorFilename); if (EC) { errs() << "Error making unique filename: " << EC.message() << "\n"; exit(1); } + RunProgramWithTimeout(ProgPath, Args, "", ErrorFilename.str(), ErrorFilename.str(), Timeout, MemoryLimit); // FIXME: check return code ? @@ -427,13 +427,14 @@ static void lexCommand(std::string &Message, const std::string &CommandLine, pos = CommandLine.find_first_of(delimiters, lastPos); } - CmdPath = sys::FindProgramByName(Command); - if (CmdPath.empty()) { + auto Path = sys::findProgramByName(Command); + if (!Path) { Message = std::string("Cannot find '") + Command + - "' in PATH!\n"; + "' in PATH: " + Path.getError().message() + "\n"; return; } + CmdPath = *Path; Message = "Found command in: " + CmdPath + "\n"; } @@ -907,16 +908,24 @@ int GCC::MakeSharedObject(const std::string &InputFile, FileType fileType, GCC *GCC::create(std::string &Message, const std::string &GCCBinary, const std::vector<std::string> *Args) { - std::string GCCPath = sys::FindProgramByName(GCCBinary); - if (GCCPath.empty()) { - Message = "Cannot find `"+ GCCBinary +"' in PATH!\n"; + auto GCCPath = sys::findProgramByName(GCCBinary); + if (!GCCPath) { + Message = "Cannot find `" + GCCBinary + "' in PATH: " + + GCCPath.getError().message() + "\n"; return nullptr; } std::string RemoteClientPath; - if (!RemoteClient.empty()) - RemoteClientPath = sys::FindProgramByName(RemoteClient); + if (!RemoteClient.empty()) { + auto Path = sys::findProgramByName(RemoteClient); + if (!Path) { + Message = "Cannot find `" + RemoteClient + "' in PATH: " + + Path.getError().message() + "\n"; + return nullptr; + } + RemoteClientPath = *Path; + } - Message = "Found gcc: " + GCCPath + "\n"; - return new GCC(GCCPath, RemoteClientPath, Args); + Message = "Found gcc: " + *GCCPath + "\n"; + return new GCC(*GCCPath, RemoteClientPath, Args); } diff --git a/tools/bugpoint/ToolRunner.h b/tools/bugpoint/ToolRunner.h index 6e7b95c..454724a 100644 --- a/tools/bugpoint/ToolRunner.h +++ b/tools/bugpoint/ToolRunner.h @@ -14,8 +14,8 @@ // //===----------------------------------------------------------------------===// -#ifndef BUGPOINT_TOOLRUNNER_H -#define BUGPOINT_TOOLRUNNER_H +#ifndef LLVM_TOOLS_BUGPOINT_TOOLRUNNER_H +#define LLVM_TOOLS_BUGPOINT_TOOLRUNNER_H #include "llvm/ADT/Triple.h" #include "llvm/Support/CommandLine.h" diff --git a/tools/bugpoint/bugpoint.cpp b/tools/bugpoint/bugpoint.cpp index c7dae0f..d0bade5 100644 --- a/tools/bugpoint/bugpoint.cpp +++ b/tools/bugpoint/bugpoint.cpp @@ -63,10 +63,6 @@ static cl::list<const PassInfo*, bool, PassNameParser> PassList(cl::desc("Passes available:"), cl::ZeroOrMore); static cl::opt<bool> -StandardCompileOpts("std-compile-opts", - cl::desc("Include the standard compile time optimizations")); - -static cl::opt<bool> StandardLinkOpts("std-link-opts", cl::desc("Include the standard link time optimizations")); @@ -170,17 +166,11 @@ int main(int argc, char **argv) { if (D.addSources(InputFilenames)) return 1; AddToDriver PM(D); - if (StandardCompileOpts) { - PassManagerBuilder Builder; - Builder.OptLevel = 3; - Builder.Inliner = createFunctionInliningPass(); - Builder.populateModulePassManager(PM); - } if (StandardLinkOpts) { PassManagerBuilder Builder; - Builder.populateLTOPassManager(PM, /*Internalize=*/true, - /*RunInliner=*/true); + Builder.Inliner = createFunctionInliningPass(); + Builder.populateLTOPassManager(PM); } if (OptLevelO1 || OptLevelO2 || OptLevelO3) { |