X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=tools%2Fbugpoint%2FExecutionDriver.cpp;h=41b8ccc18e87136dfc1b2000990de0e385fd1148;hb=d912be98f8ebfa99ab9fa2d985d3f4e9cddf2df6;hp=f1601cdb84577c467fa5b848689399b85f7e60f8;hpb=f73311bb646bf970806ba7caba220e6bffff7b49;p=oota-llvm.git diff --git a/tools/bugpoint/ExecutionDriver.cpp b/tools/bugpoint/ExecutionDriver.cpp index f1601cdb845..41b8ccc18e8 100644 --- a/tools/bugpoint/ExecutionDriver.cpp +++ b/tools/bugpoint/ExecutionDriver.cpp @@ -17,6 +17,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/FileUtilities.h" +#include "llvm/Support/Program.h" #include "llvm/Support/SystemUtils.h" #include "llvm/Support/raw_ostream.h" #include @@ -28,8 +29,7 @@ namespace { // for miscompilation. // enum OutputType { - AutoPick, RunLLI, RunJIT, RunLLC, RunLLCIA, RunCBE, CBE_bug, LLC_Safe, - CompileCustom, Custom + AutoPick, RunLLI, RunJIT, RunLLC, RunLLCIA, LLC_Safe, CompileCustom, Custom }; cl::opt @@ -48,8 +48,6 @@ namespace { clEnumValN(RunLLC, "run-llc", "Compile with LLC"), clEnumValN(RunLLCIA, "run-llc-ia", "Compile with LLC with integrated assembler"), - clEnumValN(RunCBE, "run-cbe", "Compile with CBE"), - clEnumValN(CBE_bug,"cbe-bug", "Find CBE bugs"), clEnumValN(LLC_Safe, "llc-safe", "Use LLC for all"), clEnumValN(CompileCustom, "compile-custom", "Use -compile-command to define a command to " @@ -64,7 +62,6 @@ namespace { SafeInterpreterSel(cl::desc("Specify \"safe\" i.e. known-good backend:"), cl::values(clEnumValN(AutoPick, "safe-auto", "Use best guess"), clEnumValN(RunLLC, "safe-run-llc", "Compile with LLC"), - clEnumValN(RunCBE, "safe-run-cbe", "Compile with CBE"), clEnumValN(Custom, "safe-run-custom", "Use -exec-command to define a command to execute " "the bitcode. Useful for cross-compilation."), @@ -128,11 +125,10 @@ namespace { cl::ZeroOrMore, cl::PositionalEatsArgs); cl::opt - GCCBinary("gcc", cl::init("gcc"), - cl::desc("The gcc binary to use. (default 'gcc')")); + CCBinary("gcc", cl::init(""), cl::desc("The gcc binary to use.")); cl::list - GCCToolArgv("gcc-tool-args", cl::Positional, + CCToolArgv("gcc-tool-args", cl::Positional, cl::desc("..."), cl::ZeroOrMore, cl::PositionalEatsArgs); } @@ -149,15 +145,18 @@ bool BugDriver::initializeExecutionEnvironment() { // Create an instance of the AbstractInterpreter interface as specified on // the command line - SafeInterpreter = 0; + SafeInterpreter = nullptr; std::string Message; + if (CCBinary.empty()) { + if (sys::findProgramByName("clang")) + CCBinary = "clang"; + else + CCBinary = "gcc"; + } + switch (InterpreterSel) { case AutoPick: - InterpreterSel = RunCBE; - Interpreter = - AbstractInterpreter::createCBE(getToolName(), Message, GCCBinary, - &ToolArgv, &GCCToolArgv); if (!Interpreter) { InterpreterSel = RunJIT; Interpreter = AbstractInterpreter::createJIT(getToolName(), Message, @@ -166,8 +165,8 @@ bool BugDriver::initializeExecutionEnvironment() { if (!Interpreter) { InterpreterSel = RunLLC; Interpreter = AbstractInterpreter::createLLC(getToolName(), Message, - GCCBinary, &ToolArgv, - &GCCToolArgv); + CCBinary, &ToolArgv, + &CCToolArgv); } if (!Interpreter) { InterpreterSel = RunLLI; @@ -187,20 +186,14 @@ bool BugDriver::initializeExecutionEnvironment() { case RunLLCIA: case LLC_Safe: Interpreter = AbstractInterpreter::createLLC(getToolName(), Message, - GCCBinary, &ToolArgv, - &GCCToolArgv, + CCBinary, &ToolArgv, + &CCToolArgv, InterpreterSel == RunLLCIA); break; case RunJIT: Interpreter = AbstractInterpreter::createJIT(getToolName(), Message, &ToolArgv); break; - case RunCBE: - case CBE_bug: - Interpreter = AbstractInterpreter::createCBE(getToolName(), Message, - GCCBinary, &ToolArgv, - &GCCToolArgv); - break; case CompileCustom: Interpreter = AbstractInterpreter::createCustomCompiler(Message, CustomCompileCommand); @@ -209,9 +202,6 @@ bool BugDriver::initializeExecutionEnvironment() { Interpreter = AbstractInterpreter::createCustomExecutor(Message, CustomExecCommand); break; - default: - Message = "Sorry, this back-end is not supported by bugpoint right now!\n"; - break; } if (!Interpreter) errs() << Message; @@ -224,67 +214,40 @@ bool BugDriver::initializeExecutionEnvironment() { std::vector SafeToolArgs = SafeToolArgv; switch (SafeInterpreterSel) { case AutoPick: - // In "cbe-bug" mode, default to using LLC as the "safe" backend. - if (!SafeInterpreter && - InterpreterSel == CBE_bug) { - SafeInterpreterSel = RunLLC; - SafeToolArgs.push_back("--relocation-model=pic"); - SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message, - GCCBinary, - &SafeToolArgs, - &GCCToolArgv); - } - // In "llc-safe" mode, default to using LLC as the "safe" backend. if (!SafeInterpreter && InterpreterSel == LLC_Safe) { SafeInterpreterSel = RunLLC; SafeToolArgs.push_back("--relocation-model=pic"); SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message, - GCCBinary, + CCBinary, &SafeToolArgs, - &GCCToolArgv); + &CCToolArgv); } - // Pick a backend that's different from the test backend. The JIT and - // LLC backends share a lot of code, so prefer to use the CBE as the - // safe back-end when testing them. - if (!SafeInterpreter && - InterpreterSel != RunCBE) { - SafeInterpreterSel = RunCBE; - SafeInterpreter = AbstractInterpreter::createCBE(Path.c_str(), Message, - GCCBinary, - &SafeToolArgs, - &GCCToolArgv); - } if (!SafeInterpreter && InterpreterSel != RunLLC && InterpreterSel != RunJIT) { SafeInterpreterSel = RunLLC; SafeToolArgs.push_back("--relocation-model=pic"); SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message, - GCCBinary, + CCBinary, &SafeToolArgs, - &GCCToolArgv); + &CCToolArgv); } if (!SafeInterpreter) { SafeInterpreterSel = AutoPick; - Message = "Sorry, I can't automatically select an interpreter!\n"; + Message = "Sorry, I can't automatically select a safe interpreter!\n"; } break; case RunLLC: case RunLLCIA: SafeToolArgs.push_back("--relocation-model=pic"); SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message, - GCCBinary, &SafeToolArgs, - &GCCToolArgv, + CCBinary, &SafeToolArgs, + &CCToolArgv, SafeInterpreterSel == RunLLCIA); break; - case RunCBE: - SafeInterpreter = AbstractInterpreter::createCBE(Path.c_str(), Message, - GCCBinary, &SafeToolArgs, - &GCCToolArgv); - break; case Custom: SafeInterpreter = AbstractInterpreter::createCustomExecutor(Message, CustomExecCommand); @@ -296,11 +259,11 @@ bool BugDriver::initializeExecutionEnvironment() { } if (!SafeInterpreter) { outs() << Message << "\nExiting.\n"; exit(1); } - gcc = GCC::create(Message, GCCBinary, &GCCToolArgv); - if (!gcc) { outs() << Message << "\nExiting.\n"; exit(1); } + cc = CC::create(Message, CCBinary, &CCToolArgv); + if (!cc) { outs() << Message << "\nExiting.\n"; exit(1); } // If there was an error creating the selected interpreter, quit with error. - return Interpreter == 0; + return Interpreter == nullptr; } /// compileProgram - Try to compile the specified module, returning false and @@ -309,21 +272,23 @@ bool BugDriver::initializeExecutionEnvironment() { /// void BugDriver::compileProgram(Module *M, std::string *Error) const { // Emit the program to a bitcode file... - sys::Path BitcodeFile (OutputPrefix + "-test-program.bc"); - std::string ErrMsg; - if (BitcodeFile.makeUnique(true, &ErrMsg)) { - errs() << ToolName << ": Error making unique filename: " << ErrMsg + SmallString<128> BitcodeFile; + int BitcodeFD; + std::error_code EC = sys::fs::createUniqueFile( + OutputPrefix + "-test-program-%%%%%%%.bc", BitcodeFD, BitcodeFile); + if (EC) { + errs() << ToolName << ": Error making unique filename: " << EC.message() << "\n"; exit(1); } - if (writeProgramToFile(BitcodeFile.str(), M)) { - errs() << ToolName << ": Error emitting bitcode to file '" - << BitcodeFile.str() << "'!\n"; + if (writeProgramToFile(BitcodeFile.str(), BitcodeFD, M)) { + errs() << ToolName << ": Error emitting bitcode to file '" << BitcodeFile + << "'!\n"; exit(1); } // Remove the temporary bitcode file when we are done. - FileRemover BitcodeFileRemover(BitcodeFile, !SaveTemps); + FileRemover BitcodeFileRemover(BitcodeFile.str(), !SaveTemps); // Actually compile the program! Interpreter->compileProgram(BitcodeFile.str(), Error, Timeout, MemoryLimit); @@ -340,21 +305,23 @@ std::string BugDriver::executeProgram(const Module *Program, const std::string &SharedObj, AbstractInterpreter *AI, std::string *Error) const { - if (AI == 0) AI = Interpreter; + if (!AI) AI = Interpreter; assert(AI && "Interpreter should have been created already!"); bool CreatedBitcode = false; - std::string ErrMsg; if (BitcodeFile.empty()) { // Emit the program to a bitcode file... - sys::Path uniqueFilename(OutputPrefix + "-test-program.bc"); - if (uniqueFilename.makeUnique(true, &ErrMsg)) { + SmallString<128> UniqueFilename; + int UniqueFD; + std::error_code EC = sys::fs::createUniqueFile( + OutputPrefix + "-test-program-%%%%%%%.bc", UniqueFD, UniqueFilename); + if (EC) { errs() << ToolName << ": Error making unique filename: " - << ErrMsg << "!\n"; + << EC.message() << "!\n"; exit(1); } - BitcodeFile = uniqueFilename.str(); + BitcodeFile = UniqueFilename.str(); - if (writeProgramToFile(BitcodeFile, Program)) { + if (writeProgramToFile(BitcodeFile, UniqueFD, Program)) { errs() << ToolName << ": Error emitting bitcode to file '" << BitcodeFile << "'!\n"; exit(1); @@ -363,19 +330,21 @@ std::string BugDriver::executeProgram(const Module *Program, } // Remove the temporary bitcode file when we are done. - sys::Path BitcodePath(BitcodeFile); - FileRemover BitcodeFileRemover(BitcodePath, CreatedBitcode && !SaveTemps); + std::string BitcodePath(BitcodeFile); + FileRemover BitcodeFileRemover(BitcodePath, + CreatedBitcode && !SaveTemps); - if (OutputFile.empty()) OutputFile = OutputPrefix + "-execution-output"; + if (OutputFile.empty()) OutputFile = OutputPrefix + "-execution-output-%%%%%%%"; // Check to see if this is a valid output filename... - sys::Path uniqueFile(OutputFile); - if (uniqueFile.makeUnique(true, &ErrMsg)) { + SmallString<128> UniqueFile; + std::error_code EC = sys::fs::createUniqueFile(OutputFile, UniqueFile); + if (EC) { errs() << ToolName << ": Error making unique filename: " - << ErrMsg << "\n"; + << EC.message() << "\n"; exit(1); } - OutputFile = uniqueFile.str(); + OutputFile = UniqueFile.str(); // Figure out which shared objects to run, if any. std::vector SharedObjs(AdditionalSOs); @@ -423,16 +392,16 @@ std::string BugDriver::executeProgramSafely(const Module *Program, std::string BugDriver::compileSharedObject(const std::string &BitcodeFile, std::string &Error) { assert(Interpreter && "Interpreter should have been created already!"); - sys::Path OutputFile; + std::string OutputFile; // Using the known-good backend. - GCC::FileType FT = SafeInterpreter->OutputCode(BitcodeFile, OutputFile, + CC::FileType FT = SafeInterpreter->OutputCode(BitcodeFile, OutputFile, Error); if (!Error.empty()) return ""; std::string SharedObjectFile; - bool Failure = gcc->MakeSharedObject(OutputFile.str(), FT, SharedObjectFile, + bool Failure = cc->MakeSharedObject(OutputFile, FT, SharedObjectFile, AdditionalLinkerArgs, Error); if (!Error.empty()) return ""; @@ -440,9 +409,9 @@ std::string BugDriver::compileSharedObject(const std::string &BitcodeFile, exit(1); // Remove the intermediate C file - OutputFile.eraseFromDisk(); + sys::fs::remove(OutputFile); - return "./" + SharedObjectFile; + return SharedObjectFile; } /// createReferenceFile - calls compileProgram and then records the output @@ -461,8 +430,8 @@ bool BugDriver::createReferenceFile(Module *M, const std::string &Filename) { errs() << Error; if (Interpreter != SafeInterpreter) { errs() << "*** There is a bug running the \"safe\" backend. Either" - << " debug it (for example with the -run-cbe bugpoint option," - << " if CBE is being used as the \"safe\" backend), or fix the" + << " debug it (for example with the -run-jit bugpoint option," + << " if JIT is being used as the \"safe\" backend), or fix the" << " error some other way.\n"; } return false; @@ -474,7 +443,7 @@ bool BugDriver::createReferenceFile(Module *M, const std::string &Filename) { /// diffProgram - This method executes the specified module and diffs the /// output against the file specified by ReferenceOutputFile. If the output /// is different, 1 is returned. If there is a problem with the code -/// generator (e.g., llc crashes), this will return -1 and set Error. +/// generator (e.g., llc crashes), this will set ErrMsg. /// bool BugDriver::diffProgram(const Module *Program, const std::string &BitcodeFile, @@ -482,15 +451,15 @@ bool BugDriver::diffProgram(const Module *Program, bool RemoveBitcode, std::string *ErrMsg) const { // Execute the program, generating an output file... - sys::Path Output(executeProgram(Program, "", BitcodeFile, SharedObject, 0, - ErrMsg)); + std::string Output( + executeProgram(Program, "", BitcodeFile, SharedObject, nullptr, ErrMsg)); if (!ErrMsg->empty()) return false; std::string Error; bool FilesDifferent = false; - if (int Diff = DiffFilesWithTolerance(sys::Path(ReferenceOutputFile), - sys::Path(Output.str()), + if (int Diff = DiffFilesWithTolerance(ReferenceOutputFile, + Output, AbsTolerance, RelTolerance, &Error)) { if (Diff == 2) { errs() << "While diffing output: " << Error << '\n'; @@ -500,12 +469,12 @@ bool BugDriver::diffProgram(const Module *Program, } else { // Remove the generated output if there are no differences. - Output.eraseFromDisk(); + sys::fs::remove(Output); } // Remove the bitcode file if we are supposed to. if (RemoveBitcode) - sys::Path(BitcodeFile).eraseFromDisk(); + sys::fs::remove(BitcodeFile); return FilesDifferent; }