diff options
Diffstat (limited to 'tools/bugpoint')
-rw-r--r-- | tools/bugpoint/ExecutionDriver.cpp | 29 | ||||
-rw-r--r-- | tools/bugpoint/Miscompilation.cpp | 14 | ||||
-rw-r--r-- | tools/bugpoint/ToolRunner.cpp | 57 | ||||
-rw-r--r-- | tools/bugpoint/ToolRunner.h | 27 |
4 files changed, 79 insertions, 48 deletions
diff --git a/tools/bugpoint/ExecutionDriver.cpp b/tools/bugpoint/ExecutionDriver.cpp index 9eb33149692e..57f12d5af824 100644 --- a/tools/bugpoint/ExecutionDriver.cpp +++ b/tools/bugpoint/ExecutionDriver.cpp @@ -118,6 +118,10 @@ namespace { cl::desc("<safe-tool arguments>..."), cl::ZeroOrMore, cl::PositionalEatsArgs); + cl::opt<std::string> + GCCBinary("gcc", cl::init("gcc"), + cl::desc("The gcc binary to use. (default 'gcc')")); + cl::list<std::string> GCCToolArgv("gcc-tool-args", cl::Positional, cl::desc("<gcc-tool arguments>..."), @@ -143,8 +147,8 @@ bool BugDriver::initializeExecutionEnvironment() { case AutoPick: InterpreterSel = RunCBE; Interpreter = - AbstractInterpreter::createCBE(getToolName(), Message, &ToolArgv, - &GCCToolArgv); + AbstractInterpreter::createCBE(getToolName(), Message, GCCBinary, + &ToolArgv, &GCCToolArgv); if (!Interpreter) { InterpreterSel = RunJIT; Interpreter = AbstractInterpreter::createJIT(getToolName(), Message, @@ -153,7 +157,8 @@ bool BugDriver::initializeExecutionEnvironment() { if (!Interpreter) { InterpreterSel = RunLLC; Interpreter = AbstractInterpreter::createLLC(getToolName(), Message, - &ToolArgv, &GCCToolArgv); + GCCBinary, &ToolArgv, + &GCCToolArgv); } if (!Interpreter) { InterpreterSel = RunLLI; @@ -173,7 +178,8 @@ bool BugDriver::initializeExecutionEnvironment() { case RunLLCIA: case LLC_Safe: Interpreter = AbstractInterpreter::createLLC(getToolName(), Message, - &ToolArgv, &GCCToolArgv, + GCCBinary, &ToolArgv, + &GCCToolArgv, InterpreterSel == RunLLCIA); break; case RunJIT: @@ -183,7 +189,8 @@ bool BugDriver::initializeExecutionEnvironment() { case RunCBE: case CBE_bug: Interpreter = AbstractInterpreter::createCBE(getToolName(), Message, - &ToolArgv, &GCCToolArgv); + GCCBinary, &ToolArgv, + &GCCToolArgv); break; case Custom: Interpreter = AbstractInterpreter::createCustom(Message, CustomExecCommand); @@ -209,6 +216,7 @@ bool BugDriver::initializeExecutionEnvironment() { SafeInterpreterSel = RunLLC; SafeToolArgs.push_back("--relocation-model=pic"); SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message, + GCCBinary, &SafeToolArgs, &GCCToolArgv); } @@ -219,6 +227,7 @@ bool BugDriver::initializeExecutionEnvironment() { SafeInterpreterSel = RunLLC; SafeToolArgs.push_back("--relocation-model=pic"); SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message, + GCCBinary, &SafeToolArgs, &GCCToolArgv); } @@ -230,6 +239,7 @@ bool BugDriver::initializeExecutionEnvironment() { InterpreterSel != RunCBE) { SafeInterpreterSel = RunCBE; SafeInterpreter = AbstractInterpreter::createCBE(Path.c_str(), Message, + GCCBinary, &SafeToolArgs, &GCCToolArgv); } @@ -239,6 +249,7 @@ bool BugDriver::initializeExecutionEnvironment() { SafeInterpreterSel = RunLLC; SafeToolArgs.push_back("--relocation-model=pic"); SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message, + GCCBinary, &SafeToolArgs, &GCCToolArgv); } @@ -251,13 +262,13 @@ bool BugDriver::initializeExecutionEnvironment() { case RunLLCIA: SafeToolArgs.push_back("--relocation-model=pic"); SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message, - &SafeToolArgs, + GCCBinary, &SafeToolArgs, &GCCToolArgv, SafeInterpreterSel == RunLLCIA); break; case RunCBE: SafeInterpreter = AbstractInterpreter::createCBE(Path.c_str(), Message, - &SafeToolArgs, + GCCBinary, &SafeToolArgs, &GCCToolArgv); break; case Custom: @@ -271,7 +282,7 @@ bool BugDriver::initializeExecutionEnvironment() { } if (!SafeInterpreter) { outs() << Message << "\nExiting.\n"; exit(1); } - gcc = GCC::create(Message, &GCCToolArgv); + gcc = GCC::create(Message, GCCBinary, &GCCToolArgv); if (!gcc) { outs() << Message << "\nExiting.\n"; exit(1); } // If there was an error creating the selected interpreter, quit with error. @@ -301,7 +312,7 @@ void BugDriver::compileProgram(Module *M, std::string *Error) { FileRemover BitcodeFileRemover(BitcodeFile, !SaveTemps); // Actually compile the program! - Interpreter->compileProgram(BitcodeFile.str(), Error); + Interpreter->compileProgram(BitcodeFile.str(), Error, Timeout, MemoryLimit); } diff --git a/tools/bugpoint/Miscompilation.cpp b/tools/bugpoint/Miscompilation.cpp index 45bb745a9acc..71484a250745 100644 --- a/tools/bugpoint/Miscompilation.cpp +++ b/tools/bugpoint/Miscompilation.cpp @@ -126,7 +126,8 @@ ReduceMiscompilingPasses::doTest(std::vector<const PassInfo*> &Prefix, // Ok, so now we know that the prefix passes work, try running the suffix // passes on the result of the prefix passes. // - Module *PrefixOutput = ParseInputFile(BitcodeResult, BD.getContext()); + OwningPtr<Module> PrefixOutput(ParseInputFile(BitcodeResult, + BD.getContext())); if (PrefixOutput == 0) { errs() << BD.getToolName() << ": Error reading bitcode file '" << BitcodeResult << "'!\n"; @@ -142,7 +143,7 @@ ReduceMiscompilingPasses::doTest(std::vector<const PassInfo*> &Prefix, << "' passes compile correctly after the '" << getPassesString(Prefix) << "' passes: "; - Module *OriginalInput = BD.swapProgramIn(PrefixOutput); + OwningPtr<Module> OriginalInput(BD.swapProgramIn(PrefixOutput.take())); if (BD.runPasses(Suffix, BitcodeResult, false/*delete*/, true/*quiet*/)) { errs() << " Error running this sequence of passes" << " on the input program!\n"; @@ -157,13 +158,13 @@ ReduceMiscompilingPasses::doTest(std::vector<const PassInfo*> &Prefix, return InternalError; if (Diff) { outs() << " nope.\n"; - delete OriginalInput; // We pruned down the original input... return KeepSuffix; } // Otherwise, we must not be running the bad pass anymore. outs() << " yup.\n"; // No miscompilation! - delete BD.swapProgramIn(OriginalInput); // Restore orig program & free test + // Restore orig program & free test. + delete BD.swapProgramIn(OriginalInput.take()); return NoFailure; } @@ -222,15 +223,14 @@ static bool TestMergedProgram(BugDriver &BD, Module *M1, Module *M2, } delete M2; // We are done with this module. - Module *OldProgram = BD.swapProgramIn(M1); + OwningPtr<Module> OldProgram(BD.swapProgramIn(M1)); // Execute the program. If it does not match the expected output, we must // return true. bool Broken = BD.diffProgram("", "", false, &Error); if (!Error.empty()) { // Delete the linked module & restore the original - BD.swapProgramIn(OldProgram); - delete M1; + delete BD.swapProgramIn(OldProgram.take()); } return Broken; } diff --git a/tools/bugpoint/ToolRunner.cpp b/tools/bugpoint/ToolRunner.cpp index 7ade77840237..3149a7a494a9 100644 --- a/tools/bugpoint/ToolRunner.cpp +++ b/tools/bugpoint/ToolRunner.cpp @@ -133,7 +133,9 @@ static int RunProgramRemotelyWithTimeout(const sys::Path &RemoteClientPath, return ReturnCode; } -static std::string ProcessFailure(sys::Path ProgPath, const char** Args) { +static std::string ProcessFailure(sys::Path ProgPath, const char** Args, + unsigned Timeout = 0, + unsigned MemoryLimit = 0) { std::ostringstream OS; OS << "\nError running tool:\n "; for (const char **Arg = Args; *Arg; ++Arg) @@ -148,7 +150,8 @@ static std::string ProcessFailure(sys::Path ProgPath, const char** Args) { exit(1); } RunProgramWithTimeout(ProgPath, Args, sys::Path(""), ErrorFilename, - ErrorFilename); // FIXME: check return code ? + ErrorFilename, Timeout, MemoryLimit); + // FIXME: check return code ? // Print out the error messages generated by GCC if possible... std::ifstream ErrorFile(ErrorFilename.c_str()); @@ -353,7 +356,8 @@ AbstractInterpreter *AbstractInterpreter::createCustom( // LLC Implementation of AbstractIntepreter interface // GCC::FileType LLC::OutputCode(const std::string &Bitcode, - sys::Path &OutputAsmFile, std::string &Error) { + sys::Path &OutputAsmFile, std::string &Error, + unsigned Timeout, unsigned MemoryLimit) { const char *Suffix = (UseIntegratedAssembler ? ".llc.o" : ".llc.s"); sys::Path uniqueFile(Bitcode + Suffix); std::string ErrMsg; @@ -386,14 +390,17 @@ GCC::FileType LLC::OutputCode(const std::string &Bitcode, errs() << "\n"; ); if (RunProgramWithTimeout(sys::Path(LLCPath), &LLCArgs[0], - sys::Path(), sys::Path(), sys::Path())) - Error = ProcessFailure(sys::Path(LLCPath), &LLCArgs[0]); + sys::Path(), sys::Path(), sys::Path(), + Timeout, MemoryLimit)) + Error = ProcessFailure(sys::Path(LLCPath), &LLCArgs[0], + Timeout, MemoryLimit); return UseIntegratedAssembler ? GCC::ObjectFile : GCC::AsmFile; } -void LLC::compileProgram(const std::string &Bitcode, std::string *Error) { +void LLC::compileProgram(const std::string &Bitcode, std::string *Error, + unsigned Timeout, unsigned MemoryLimit) { sys::Path OutputAsmFile; - OutputCode(Bitcode, OutputAsmFile, *Error); + OutputCode(Bitcode, OutputAsmFile, *Error, Timeout, MemoryLimit); OutputAsmFile.eraseFromDisk(); } @@ -408,12 +415,12 @@ int LLC::ExecuteProgram(const std::string &Bitcode, unsigned MemoryLimit) { sys::Path OutputAsmFile; - GCC::FileType FileKind = OutputCode(Bitcode, OutputAsmFile, *Error); + GCC::FileType FileKind = OutputCode(Bitcode, OutputAsmFile, *Error, Timeout, + MemoryLimit); FileRemover OutFileRemover(OutputAsmFile, !SaveTemps); std::vector<std::string> GCCArgs(ArgsForGCC); GCCArgs.insert(GCCArgs.end(), SharedLibs.begin(), SharedLibs.end()); - GCCArgs.insert(GCCArgs.end(), gccArgs.begin(), gccArgs.end()); // Assuming LLC worked, compile the result with GCC and run it. return gcc->ExecuteProgram(OutputAsmFile.str(), Args, FileKind, @@ -425,6 +432,7 @@ int LLC::ExecuteProgram(const std::string &Bitcode, /// LLC *AbstractInterpreter::createLLC(const char *Argv0, std::string &Message, + const std::string &GCCBinary, const std::vector<std::string> *Args, const std::vector<std::string> *GCCArgs, bool UseIntegratedAssembler) { @@ -436,12 +444,12 @@ LLC *AbstractInterpreter::createLLC(const char *Argv0, } Message = "Found llc: " + LLCPath + "\n"; - GCC *gcc = GCC::create(Message, GCCArgs); + GCC *gcc = GCC::create(Message, GCCBinary, GCCArgs); if (!gcc) { errs() << Message << "\n"; exit(1); } - return new LLC(LLCPath, gcc, Args, GCCArgs, UseIntegratedAssembler); + return new LLC(LLCPath, gcc, Args, UseIntegratedAssembler); } //===---------------------------------------------------------------------===// @@ -528,7 +536,8 @@ AbstractInterpreter *AbstractInterpreter::createJIT(const char *Argv0, } GCC::FileType CBE::OutputCode(const std::string &Bitcode, - sys::Path &OutputCFile, std::string &Error) { + sys::Path &OutputCFile, std::string &Error, + unsigned Timeout, unsigned MemoryLimit) { sys::Path uniqueFile(Bitcode+".cbe.c"); std::string ErrMsg; if (uniqueFile.makeUnique(true, &ErrMsg)) { @@ -556,14 +565,15 @@ GCC::FileType CBE::OutputCode(const std::string &Bitcode, errs() << "\n"; ); if (RunProgramWithTimeout(LLCPath, &LLCArgs[0], sys::Path(), sys::Path(), - sys::Path())) - Error = ProcessFailure(LLCPath, &LLCArgs[0]); + sys::Path(), Timeout, MemoryLimit)) + Error = ProcessFailure(LLCPath, &LLCArgs[0], Timeout, MemoryLimit); return GCC::CFile; } -void CBE::compileProgram(const std::string &Bitcode, std::string *Error) { +void CBE::compileProgram(const std::string &Bitcode, std::string *Error, + unsigned Timeout, unsigned MemoryLimit) { sys::Path OutputCFile; - OutputCode(Bitcode, OutputCFile, *Error); + OutputCode(Bitcode, OutputCFile, *Error, Timeout, MemoryLimit); OutputCFile.eraseFromDisk(); } @@ -577,7 +587,7 @@ int CBE::ExecuteProgram(const std::string &Bitcode, unsigned Timeout, unsigned MemoryLimit) { sys::Path OutputCFile; - OutputCode(Bitcode, OutputCFile, *Error); + OutputCode(Bitcode, OutputCFile, *Error, Timeout, MemoryLimit); FileRemover CFileRemove(OutputCFile, !SaveTemps); @@ -593,6 +603,7 @@ int CBE::ExecuteProgram(const std::string &Bitcode, /// CBE *AbstractInterpreter::createCBE(const char *Argv0, std::string &Message, + const std::string &GCCBinary, const std::vector<std::string> *Args, const std::vector<std::string> *GCCArgs) { sys::Path LLCPath = @@ -604,7 +615,7 @@ CBE *AbstractInterpreter::createCBE(const char *Argv0, } Message = "Found llc: " + LLCPath.str() + "\n"; - GCC *gcc = GCC::create(Message, GCCArgs); + GCC *gcc = GCC::create(Message, GCCBinary, GCCArgs); if (!gcc) { errs() << Message << "\n"; exit(1); @@ -619,10 +630,9 @@ CBE *AbstractInterpreter::createCBE(const char *Argv0, static bool IsARMArchitecture(std::vector<std::string> Args) { for (std::vector<std::string>::const_iterator I = Args.begin(), E = Args.end(); I != E; ++I) { - StringRef S(*I); - if (!S.equals_lower("-arch")) { + if (StringRef(*I).equals_lower("-arch")) { ++I; - if (I != E && !S.substr(0, strlen("arm")).equals_lower("arm")) + if (I != E && StringRef(*I).substr(0, strlen("arm")).equals_lower("arm")) return true; } } @@ -852,10 +862,11 @@ int GCC::MakeSharedObject(const std::string &InputFile, FileType fileType, /// create - Try to find the `gcc' executable /// GCC *GCC::create(std::string &Message, + const std::string &GCCBinary, const std::vector<std::string> *Args) { - sys::Path GCCPath = sys::Program::FindProgramByName("gcc"); + sys::Path GCCPath = sys::Program::FindProgramByName(GCCBinary); if (GCCPath.isEmpty()) { - Message = "Cannot find `gcc' in executable directory or PATH!\n"; + Message = "Cannot find `"+ GCCBinary +"' in executable directory or PATH!\n"; return 0; } diff --git a/tools/bugpoint/ToolRunner.h b/tools/bugpoint/ToolRunner.h index cba10f214a90..d966fc0ea444 100644 --- a/tools/bugpoint/ToolRunner.h +++ b/tools/bugpoint/ToolRunner.h @@ -49,6 +49,7 @@ public: enum FileType { AsmFile, ObjectFile, CFile }; static GCC *create(std::string &Message, + const std::string &GCCBinary, const std::vector<std::string> *Args); /// ExecuteProgram - Execute the program specified by "ProgramFile" (which is @@ -87,9 +88,11 @@ public: class AbstractInterpreter { public: static CBE *createCBE(const char *Argv0, std::string &Message, + const std::string &GCCBinary, const std::vector<std::string> *Args = 0, const std::vector<std::string> *GCCArgs = 0); static LLC *createLLC(const char *Argv0, std::string &Message, + const std::string &GCCBinary, const std::vector<std::string> *Args = 0, const std::vector<std::string> *GCCArgs = 0, bool UseIntegratedAssembler = false); @@ -109,14 +112,17 @@ public: /// compileProgram - Compile the specified program from bitcode to executable /// code. This does not produce any output, it is only used when debugging /// the code generator. It returns false if the code generator fails. - virtual void compileProgram(const std::string &Bitcode, std::string *Error) {} + virtual void compileProgram(const std::string &Bitcode, std::string *Error, + unsigned Timeout = 0, unsigned MemoryLimit = 0) {} /// OutputCode - Compile the specified program from bitcode to code /// understood by the GCC driver (either C or asm). If the code generator /// fails, it sets Error, otherwise, this function returns the type of code /// emitted. virtual GCC::FileType OutputCode(const std::string &Bitcode, - sys::Path &OutFile, std::string &Error) { + sys::Path &OutFile, std::string &Error, + unsigned Timeout = 0, + unsigned MemoryLimit = 0) { Error = "OutputCode not supported by this AbstractInterpreter!"; return GCC::AsmFile; } @@ -158,7 +164,8 @@ public: /// compileProgram - Compile the specified program from bitcode to executable /// code. This does not produce any output, it is only used when debugging /// the code generator. Returns false if the code generator fails. - virtual void compileProgram(const std::string &Bitcode, std::string *Error); + virtual void compileProgram(const std::string &Bitcode, std::string *Error, + unsigned Timeout = 0, unsigned MemoryLimit = 0); virtual int ExecuteProgram(const std::string &Bitcode, const std::vector<std::string> &Args, @@ -177,7 +184,9 @@ public: /// fails, it sets Error, otherwise, this function returns the type of code /// emitted. virtual GCC::FileType OutputCode(const std::string &Bitcode, - sys::Path &OutFile, std::string &Error); + sys::Path &OutFile, std::string &Error, + unsigned Timeout = 0, + unsigned MemoryLimit = 0); }; @@ -187,26 +196,24 @@ public: class LLC : public AbstractInterpreter { std::string LLCPath; // The path to the LLC executable. std::vector<std::string> ToolArgs; // Extra args to pass to LLC. - std::vector<std::string> gccArgs; // Extra args to pass to GCC. GCC *gcc; bool UseIntegratedAssembler; public: LLC(const std::string &llcPath, GCC *Gcc, const std::vector<std::string> *Args, - const std::vector<std::string> *GCCArgs, bool useIntegratedAssembler) : LLCPath(llcPath), gcc(Gcc), UseIntegratedAssembler(useIntegratedAssembler) { ToolArgs.clear(); if (Args) ToolArgs = *Args; - if (GCCArgs) gccArgs = *GCCArgs; } ~LLC() { delete gcc; } /// compileProgram - Compile the specified program from bitcode to executable /// code. This does not produce any output, it is only used when debugging /// the code generator. Returns false if the code generator fails. - virtual void compileProgram(const std::string &Bitcode, std::string *Error); + virtual void compileProgram(const std::string &Bitcode, std::string *Error, + unsigned Timeout = 0, unsigned MemoryLimit = 0); virtual int ExecuteProgram(const std::string &Bitcode, const std::vector<std::string> &Args, @@ -225,7 +232,9 @@ public: /// fails, it sets Error, otherwise, this function returns the type of code /// emitted. virtual GCC::FileType OutputCode(const std::string &Bitcode, - sys::Path &OutFile, std::string &Error); + sys::Path &OutFile, std::string &Error, + unsigned Timeout = 0, + unsigned MemoryLimit = 0); }; } // End llvm namespace |