summaryrefslogtreecommitdiffstats
path: root/tools/bugpoint
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2011-02-20 12:57:14 +0000
committerdim <dim@FreeBSD.org>2011-02-20 12:57:14 +0000
commitcbb70ce070d220642b038ea101d9c0f9fbf860d6 (patch)
treed2b61ce94e654cb01a254d2195259db5f9cc3f3c /tools/bugpoint
parent4ace901e87dac5bbbac78ed325e75462e48e386e (diff)
downloadFreeBSD-src-cbb70ce070d220642b038ea101d9c0f9fbf860d6.zip
FreeBSD-src-cbb70ce070d220642b038ea101d9c0f9fbf860d6.tar.gz
Vendor import of llvm trunk r126079:
http://llvm.org/svn/llvm-project/llvm/trunk@126079
Diffstat (limited to 'tools/bugpoint')
-rw-r--r--tools/bugpoint/BugDriver.cpp2
-rw-r--r--tools/bugpoint/BugDriver.h3
-rw-r--r--tools/bugpoint/CrashDebugger.cpp8
-rw-r--r--tools/bugpoint/ExecutionDriver.cpp44
-rw-r--r--tools/bugpoint/ExtractFunction.cpp12
-rw-r--r--tools/bugpoint/Miscompilation.cpp12
-rw-r--r--tools/bugpoint/OptimizerDriver.cpp28
-rw-r--r--tools/bugpoint/ToolRunner.cpp206
-rw-r--r--tools/bugpoint/ToolRunner.h13
-rw-r--r--tools/bugpoint/bugpoint.cpp31
10 files changed, 247 insertions, 112 deletions
diff --git a/tools/bugpoint/BugDriver.cpp b/tools/bugpoint/BugDriver.cpp
index 6966671..1cbf632 100644
--- a/tools/bugpoint/BugDriver.cpp
+++ b/tools/bugpoint/BugDriver.cpp
@@ -23,7 +23,7 @@
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Host.h"
+#include "llvm/Support/Host.h"
#include <memory>
using namespace llvm;
diff --git a/tools/bugpoint/BugDriver.h b/tools/bugpoint/BugDriver.h
index e48806a..cc78489 100644
--- a/tools/bugpoint/BugDriver.h
+++ b/tools/bugpoint/BugDriver.h
@@ -17,6 +17,7 @@
#define BUGDRIVER_H
#include "llvm/ADT/ValueMap.h"
+#include "llvm/Transforms/Utils/ValueMapper.h"
#include <vector>
#include <string>
@@ -322,7 +323,7 @@ void DeleteFunctionBody(Function *F);
/// module, split the functions OUT of the specified module, and place them in
/// the new module.
Module *SplitFunctionsOutOfModule(Module *M, const std::vector<Function*> &F,
- ValueMap<const Value*, Value*> &VMap);
+ ValueToValueMapTy &VMap);
} // End llvm namespace
diff --git a/tools/bugpoint/CrashDebugger.cpp b/tools/bugpoint/CrashDebugger.cpp
index 57dc1c8..f19ef62 100644
--- a/tools/bugpoint/CrashDebugger.cpp
+++ b/tools/bugpoint/CrashDebugger.cpp
@@ -130,7 +130,7 @@ bool
ReduceCrashingGlobalVariables::TestGlobalVariables(
std::vector<GlobalVariable*> &GVs) {
// Clone the program to try hacking it apart...
- ValueMap<const Value*, Value*> VMap;
+ ValueToValueMapTy VMap;
Module *M = CloneModule(BD.getProgram(), VMap);
// Convert list to set for fast lookup...
@@ -204,7 +204,7 @@ bool ReduceCrashingFunctions::TestFuncs(std::vector<Function*> &Funcs) {
return false;
// Clone the program to try hacking it apart...
- ValueMap<const Value*, Value*> VMap;
+ ValueToValueMapTy VMap;
Module *M = CloneModule(BD.getProgram(), VMap);
// Convert list to set for fast lookup...
@@ -271,7 +271,7 @@ namespace {
bool ReduceCrashingBlocks::TestBlocks(std::vector<const BasicBlock*> &BBs) {
// Clone the program to try hacking it apart...
- ValueMap<const Value*, Value*> VMap;
+ ValueToValueMapTy VMap;
Module *M = CloneModule(BD.getProgram(), VMap);
// Convert list to set for fast lookup...
@@ -381,7 +381,7 @@ namespace {
bool ReduceCrashingInstructions::TestInsts(std::vector<const Instruction*>
&Insts) {
// Clone the program to try hacking it apart...
- ValueMap<const Value*, Value*> VMap;
+ ValueToValueMapTy VMap;
Module *M = CloneModule(BD.getProgram(), VMap);
// Convert list to set for fast lookup...
diff --git a/tools/bugpoint/ExecutionDriver.cpp b/tools/bugpoint/ExecutionDriver.cpp
index 7312484..f1601cd 100644
--- a/tools/bugpoint/ExecutionDriver.cpp
+++ b/tools/bugpoint/ExecutionDriver.cpp
@@ -28,7 +28,8 @@ namespace {
// for miscompilation.
//
enum OutputType {
- AutoPick, RunLLI, RunJIT, RunLLC, RunLLCIA, RunCBE, CBE_bug, LLC_Safe,Custom
+ AutoPick, RunLLI, RunJIT, RunLLC, RunLLCIA, RunCBE, CBE_bug, LLC_Safe,
+ CompileCustom, Custom
};
cl::opt<double>
@@ -50,6 +51,9 @@ namespace {
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 "
+ "compile the bitcode. Useful to avoid linking."),
clEnumValN(Custom, "run-custom",
"Use -exec-command to define a command to execute "
"the bitcode. Useful for cross-compilation."),
@@ -87,10 +91,15 @@ namespace {
"into executing programs"));
cl::list<std::string>
- AdditionalLinkerArgs("Xlinker",
+ AdditionalLinkerArgs("Xlinker",
cl::desc("Additional arguments to pass to the linker"));
cl::opt<std::string>
+ CustomCompileCommand("compile-command", cl::init("llc"),
+ cl::desc("Command to compile the bitcode (use with -compile-custom) "
+ "(default: llc)"));
+
+ cl::opt<std::string>
CustomExecCommand("exec-command", cl::init("simulate"),
cl::desc("Command to execute the bitcode (use with -run-custom) "
"(default: simulate)"));
@@ -119,7 +128,7 @@ namespace {
cl::ZeroOrMore, cl::PositionalEatsArgs);
cl::opt<std::string>
- GCCBinary("gcc", cl::init("gcc"),
+ GCCBinary("gcc", cl::init("gcc"),
cl::desc("The gcc binary to use. (default 'gcc')"));
cl::list<std::string>
@@ -157,7 +166,7 @@ bool BugDriver::initializeExecutionEnvironment() {
if (!Interpreter) {
InterpreterSel = RunLLC;
Interpreter = AbstractInterpreter::createLLC(getToolName(), Message,
- GCCBinary, &ToolArgv,
+ GCCBinary, &ToolArgv,
&GCCToolArgv);
}
if (!Interpreter) {
@@ -178,7 +187,7 @@ bool BugDriver::initializeExecutionEnvironment() {
case RunLLCIA:
case LLC_Safe:
Interpreter = AbstractInterpreter::createLLC(getToolName(), Message,
- GCCBinary, &ToolArgv,
+ GCCBinary, &ToolArgv,
&GCCToolArgv,
InterpreterSel == RunLLCIA);
break;
@@ -189,11 +198,16 @@ bool BugDriver::initializeExecutionEnvironment() {
case RunCBE:
case CBE_bug:
Interpreter = AbstractInterpreter::createCBE(getToolName(), Message,
- GCCBinary, &ToolArgv,
+ GCCBinary, &ToolArgv,
&GCCToolArgv);
break;
+ case CompileCustom:
+ Interpreter =
+ AbstractInterpreter::createCustomCompiler(Message, CustomCompileCommand);
+ break;
case Custom:
- Interpreter = AbstractInterpreter::createCustom(Message, CustomExecCommand);
+ Interpreter =
+ AbstractInterpreter::createCustomExecutor(Message, CustomExecCommand);
break;
default:
Message = "Sorry, this back-end is not supported by bugpoint right now!\n";
@@ -216,7 +230,7 @@ bool BugDriver::initializeExecutionEnvironment() {
SafeInterpreterSel = RunLLC;
SafeToolArgs.push_back("--relocation-model=pic");
SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message,
- GCCBinary,
+ GCCBinary,
&SafeToolArgs,
&GCCToolArgv);
}
@@ -227,7 +241,7 @@ bool BugDriver::initializeExecutionEnvironment() {
SafeInterpreterSel = RunLLC;
SafeToolArgs.push_back("--relocation-model=pic");
SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message,
- GCCBinary,
+ GCCBinary,
&SafeToolArgs,
&GCCToolArgv);
}
@@ -249,7 +263,7 @@ bool BugDriver::initializeExecutionEnvironment() {
SafeInterpreterSel = RunLLC;
SafeToolArgs.push_back("--relocation-model=pic");
SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message,
- GCCBinary,
+ GCCBinary,
&SafeToolArgs,
&GCCToolArgv);
}
@@ -272,8 +286,8 @@ bool BugDriver::initializeExecutionEnvironment() {
&GCCToolArgv);
break;
case Custom:
- SafeInterpreter = AbstractInterpreter::createCustom(Message,
- CustomExecCommand);
+ SafeInterpreter =
+ AbstractInterpreter::createCustomExecutor(Message, CustomExecCommand);
break;
default:
Message = "Sorry, this back-end is not supported by bugpoint as the "
@@ -281,7 +295,7 @@ bool BugDriver::initializeExecutionEnvironment() {
break;
}
if (!SafeInterpreter) { outs() << Message << "\nExiting.\n"; exit(1); }
-
+
gcc = GCC::create(Message, GCCBinary, &GCCToolArgv);
if (!gcc) { outs() << Message << "\nExiting.\n"; exit(1); }
@@ -298,7 +312,7 @@ void BugDriver::compileProgram(Module *M, std::string *Error) const {
sys::Path BitcodeFile (OutputPrefix + "-test-program.bc");
std::string ErrMsg;
if (BitcodeFile.makeUnique(true, &ErrMsg)) {
- errs() << ToolName << ": Error making unique filename: " << ErrMsg
+ errs() << ToolName << ": Error making unique filename: " << ErrMsg
<< "\n";
exit(1);
}
@@ -432,7 +446,7 @@ std::string BugDriver::compileSharedObject(const std::string &BitcodeFile,
}
/// createReferenceFile - calls compileProgram and then records the output
-/// into ReferenceOutputFile. Returns true if reference file created, false
+/// into ReferenceOutputFile. Returns true if reference file created, false
/// otherwise. Note: initializeExecutionEnvironment should be called BEFORE
/// this function.
///
diff --git a/tools/bugpoint/ExtractFunction.cpp b/tools/bugpoint/ExtractFunction.cpp
index 524f130..593765c 100644
--- a/tools/bugpoint/ExtractFunction.cpp
+++ b/tools/bugpoint/ExtractFunction.cpp
@@ -29,9 +29,9 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileUtilities.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Path.h"
-#include "llvm/System/Signals.h"
+#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Signals.h"
#include <set>
using namespace llvm;
@@ -193,7 +193,7 @@ static Constant *GetTorInit(std::vector<std::pair<Function*, int> > &TorList) {
/// static ctors/dtors, we need to add an llvm.global_[cd]tors global to M2, and
/// prune appropriate entries out of M1s list.
static void SplitStaticCtorDtor(const char *GlobalName, Module *M1, Module *M2,
- ValueMap<const Value*, Value*> &VMap) {
+ ValueToValueMapTy &VMap) {
GlobalVariable *GV = M1->getNamedGlobal(GlobalName);
if (!GV || GV->isDeclaration() || GV->hasLocalLinkage() ||
!GV->use_empty()) return;
@@ -256,7 +256,7 @@ static void SplitStaticCtorDtor(const char *GlobalName, Module *M1, Module *M2,
Module *
llvm::SplitFunctionsOutOfModule(Module *M,
const std::vector<Function*> &F,
- ValueMap<const Value*, Value*> &VMap) {
+ ValueToValueMapTy &VMap) {
// Make sure functions & globals are all external so that linkage
// between the two modules will work.
for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
@@ -268,7 +268,7 @@ llvm::SplitFunctionsOutOfModule(Module *M,
I->setLinkage(GlobalValue::ExternalLinkage);
}
- ValueMap<const Value*, Value*> NewVMap;
+ ValueToValueMapTy NewVMap;
Module *New = CloneModule(M, NewVMap);
// Make sure global initializers exist only in the safe module (CBE->.so)
diff --git a/tools/bugpoint/Miscompilation.cpp b/tools/bugpoint/Miscompilation.cpp
index 3f2b696..3a5f143 100644
--- a/tools/bugpoint/Miscompilation.cpp
+++ b/tools/bugpoint/Miscompilation.cpp
@@ -261,7 +261,7 @@ bool ReduceMiscompilingFunctions::TestFuncs(const std::vector<Function*> &Funcs,
// a function, we want to continue with the original function. Otherwise
// we can conclude that a function triggers the bug when in fact one
// needs a larger set of original functions to do so.
- ValueMap<const Value*, Value*> VMap;
+ ValueToValueMapTy VMap;
Module *Clone = CloneModule(BD.getProgram(), VMap);
Module *Orig = BD.swapProgramIn(Clone);
@@ -310,7 +310,7 @@ static bool ExtractLoops(BugDriver &BD,
while (1) {
if (BugpointIsInterrupted) return MadeChange;
- ValueMap<const Value*, Value*> VMap;
+ ValueToValueMapTy VMap;
Module *ToNotOptimize = CloneModule(BD.getProgram(), VMap);
Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize,
MiscompiledFunctions,
@@ -476,7 +476,7 @@ bool ReduceMiscompiledBlocks::TestFuncs(const std::vector<BasicBlock*> &BBs,
outs() << '\n';
// Split the module into the two halves of the program we want.
- ValueMap<const Value*, Value*> VMap;
+ ValueToValueMapTy VMap;
Module *Clone = CloneModule(BD.getProgram(), VMap);
Module *Orig = BD.swapProgramIn(Clone);
std::vector<Function*> FuncsOnClone;
@@ -551,7 +551,7 @@ static bool ExtractBlocks(BugDriver &BD,
return false;
}
- ValueMap<const Value*, Value*> VMap;
+ ValueToValueMapTy VMap;
Module *ProgClone = CloneModule(BD.getProgram(), VMap);
Module *ToExtract = SplitFunctionsOutOfModule(ProgClone,
MiscompiledFunctions,
@@ -738,7 +738,7 @@ void BugDriver::debugMiscompilation(std::string *Error) {
// Output a bunch of bitcode files for the user...
outs() << "Outputting reduced bitcode files which expose the problem:\n";
- ValueMap<const Value*, Value*> VMap;
+ ValueToValueMapTy VMap;
Module *ToNotOptimize = CloneModule(getProgram(), VMap);
Module *ToOptimize = SplitFunctionsOutOfModule(ToNotOptimize,
MiscompiledFunctions,
@@ -1011,7 +1011,7 @@ bool BugDriver::debugCodeGenerator(std::string *Error) {
return true;
// Split the module into the two halves of the program we want.
- ValueMap<const Value*, Value*> VMap;
+ ValueToValueMapTy VMap;
Module *ToNotCodeGen = CloneModule(getProgram(), VMap);
Module *ToCodeGen = SplitFunctionsOutOfModule(ToNotCodeGen, Funcs, VMap);
diff --git a/tools/bugpoint/OptimizerDriver.cpp b/tools/bugpoint/OptimizerDriver.cpp
index 3600ca6..2471cc1 100644
--- a/tools/bugpoint/OptimizerDriver.cpp
+++ b/tools/bugpoint/OptimizerDriver.cpp
@@ -15,10 +15,6 @@
//
//===----------------------------------------------------------------------===//
-// Note: as a short term hack, the old Unix-specific code and platform-
-// independent code co-exist via conditional compilation until it is verified
-// that the new code works correctly on Unix.
-
#include "BugDriver.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
@@ -29,9 +25,9 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/SystemUtils.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Path.h"
-#include "llvm/System/Program.h"
+#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Program.h"
#define DONT_GET_PLUGIN_LOADER_OPTION
#include "llvm/Support/PluginLoader.h"
@@ -130,12 +126,12 @@ bool BugDriver::runPasses(Module *Program,
<< ErrMsg << "\n";
return(1);
}
-
+
std::string ErrInfo;
tool_output_file InFile(inputFilename.c_str(), ErrInfo,
raw_fd_ostream::F_Binary);
-
-
+
+
if (!ErrInfo.empty()) {
errs() << "Error opening bitcode file: " << inputFilename.str() << "\n";
return 1;
@@ -147,11 +143,19 @@ bool BugDriver::runPasses(Module *Program,
InFile.os().clear_error();
return 1;
}
+
+ sys::Path tool = PrependMainExecutablePath("opt", getToolName(),
+ (void*)"opt");
+ if (tool.empty()) {
+ errs() << "Cannot find `opt' in executable directory!\n";
+ return 1;
+ }
+
+ // Ok, everything that could go wrong before running opt is done.
InFile.keep();
// setup the child process' arguments
SmallVector<const char*, 8> Args;
- sys::Path tool = FindExecutable("opt", getToolName(), (void*)"opt");
std::string Opt = tool.str();
if (UseValgrind) {
Args.push_back("valgrind");
@@ -192,7 +196,7 @@ bool BugDriver::runPasses(Module *Program,
prog = sys::Program::FindProgramByName("valgrind");
else
prog = tool;
-
+
// Redirect stdout and stderr to nowhere if SilencePasses is given
sys::Path Nowhere;
const sys::Path *Redirects[3] = {0, &Nowhere, &Nowhere};
diff --git a/tools/bugpoint/ToolRunner.cpp b/tools/bugpoint/ToolRunner.cpp
index 36dbe14..37cc902 100644
--- a/tools/bugpoint/ToolRunner.cpp
+++ b/tools/bugpoint/ToolRunner.cpp
@@ -13,7 +13,7 @@
#define DEBUG_TYPE "toolrunner"
#include "ToolRunner.h"
-#include "llvm/System/Program.h"
+#include "llvm/Support/Program.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileUtilities.h"
@@ -59,7 +59,8 @@ static int RunProgramWithTimeout(const sys::Path &ProgramPath,
const sys::Path &StdOutFile,
const sys::Path &StdErrFile,
unsigned NumSeconds = 0,
- unsigned MemoryLimit = 0) {
+ unsigned MemoryLimit = 0,
+ std::string *ErrMsg = 0) {
const sys::Path* redirects[3];
redirects[0] = &StdInFile;
redirects[1] = &StdOutFile;
@@ -76,7 +77,7 @@ static int RunProgramWithTimeout(const sys::Path &ProgramPath,
return
sys::Program::ExecuteAndWait(ProgramPath, Args, 0, redirects,
- NumSeconds, MemoryLimit);
+ NumSeconds, MemoryLimit, ErrMsg);
}
/// RunProgramRemotelyWithTimeout - This function runs the given program
@@ -141,7 +142,7 @@ static std::string ProcessFailure(sys::Path ProgPath, const char** Args,
for (const char **Arg = Args; *Arg; ++Arg)
OS << " " << *Arg;
OS << "\n";
-
+
// Rerun the compiler, capturing any error messages to print them.
sys::Path ErrorFilename("bugpoint.program_error_messages");
std::string ErrMsg;
@@ -206,7 +207,8 @@ int LLI::ExecuteProgram(const std::string &Bitcode,
LLIArgs.push_back(LLIPath.c_str());
LLIArgs.push_back("-force-interpreter=true");
- for (std::vector<std::string>::const_iterator i = SharedLibs.begin(), e = SharedLibs.end(); i != e; ++i) {
+ for (std::vector<std::string>::const_iterator i = SharedLibs.begin(),
+ e = SharedLibs.end(); i != e; ++i) {
LLIArgs.push_back("-load");
LLIArgs.push_back((*i).c_str());
}
@@ -229,7 +231,7 @@ int LLI::ExecuteProgram(const std::string &Bitcode,
);
return RunProgramWithTimeout(sys::Path(LLIPath), &LLIArgs[0],
sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
- Timeout, MemoryLimit);
+ Timeout, MemoryLimit, Error);
}
// LLI create method - Try to find the LLI executable
@@ -237,21 +239,82 @@ AbstractInterpreter *AbstractInterpreter::createLLI(const char *Argv0,
std::string &Message,
const std::vector<std::string> *ToolArgs) {
std::string LLIPath =
- FindExecutable("lli", Argv0, (void *)(intptr_t)&createLLI).str();
+ PrependMainExecutablePath("lli", Argv0, (void *)(intptr_t)&createLLI).str();
if (!LLIPath.empty()) {
Message = "Found lli: " + LLIPath + "\n";
return new LLI(LLIPath, ToolArgs);
}
- Message = "Cannot find `lli' in executable directory or PATH!\n";
+ Message = "Cannot find `lli' in executable directory!\n";
return 0;
}
//===---------------------------------------------------------------------===//
+// Custom compiler command implementation of AbstractIntepreter interface
+//
+// Allows using a custom command for compiling the bitcode, thus allows, for
+// example, to compile a bitcode fragment without linking or executing, then
+// using a custom wrapper script to check for compiler errors.
+namespace {
+ class CustomCompiler : public AbstractInterpreter {
+ std::string CompilerCommand;
+ std::vector<std::string> CompilerArgs;
+ public:
+ CustomCompiler(
+ const std::string &CompilerCmd, std::vector<std::string> CompArgs) :
+ CompilerCommand(CompilerCmd), CompilerArgs(CompArgs) {}
+
+ 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,
+ const std::string &InputFile,
+ const std::string &OutputFile,
+ std::string *Error,
+ const std::vector<std::string> &GCCArgs =
+ std::vector<std::string>(),
+ const std::vector<std::string> &SharedLibs =
+ std::vector<std::string>(),
+ unsigned Timeout = 0,
+ unsigned MemoryLimit = 0) {
+ *Error = "Execution not supported with -compile-custom";
+ return -1;
+ }
+ };
+}
+
+void CustomCompiler::compileProgram(const std::string &Bitcode,
+ std::string *Error,
+ unsigned Timeout,
+ unsigned MemoryLimit) {
+
+ std::vector<const char*> ProgramArgs;
+ ProgramArgs.push_back(CompilerCommand.c_str());
+
+ for (std::size_t i = 0; i < CompilerArgs.size(); ++i)
+ ProgramArgs.push_back(CompilerArgs.at(i).c_str());
+ ProgramArgs.push_back(Bitcode.c_str());
+ ProgramArgs.push_back(0);
+
+ // Add optional parameters to the running program from Argv
+ for (unsigned i = 0, e = CompilerArgs.size(); i != e; ++i)
+ ProgramArgs.push_back(CompilerArgs[i].c_str());
+
+ if (RunProgramWithTimeout( sys::Path(CompilerCommand), &ProgramArgs[0],
+ sys::Path(), sys::Path(), sys::Path(),
+ Timeout, MemoryLimit, Error))
+ *Error = ProcessFailure(sys::Path(CompilerCommand), &ProgramArgs[0],
+ Timeout, MemoryLimit);
+}
+
+//===---------------------------------------------------------------------===//
// Custom execution command implementation of AbstractIntepreter interface
//
// Allows using a custom command for executing the bitcode, thus allows,
-// for example, to invoke a cross compiler for code generation followed by
+// for example, to invoke a cross compiler for code generation followed by
// a simulator that executes the generated binary.
namespace {
class CustomExecutor : public AbstractInterpreter {
@@ -299,55 +362,78 @@ int CustomExecutor::ExecuteProgram(const std::string &Bitcode,
return RunProgramWithTimeout(
sys::Path(ExecutionCommand),
- &ProgramArgs[0], sys::Path(InputFile), sys::Path(OutputFile),
- sys::Path(OutputFile), Timeout, MemoryLimit);
+ &ProgramArgs[0], sys::Path(InputFile), sys::Path(OutputFile),
+ sys::Path(OutputFile), Timeout, MemoryLimit, Error);
}
-// Custom execution environment create method, takes the execution command
-// as arguments
-AbstractInterpreter *AbstractInterpreter::createCustom(
- std::string &Message,
- const std::string &ExecCommandLine) {
+// Tokenize the CommandLine to the command and the args to allow
+// defining a full command line as the command instead of just the
+// executed program. We cannot just pass the whole string after the command
+// as a single argument because then program sees only a single
+// command line argument (with spaces in it: "foo bar" instead
+// of "foo" and "bar").
+//
+// code borrowed from:
+// http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html
+static void lexCommand(std::string &Message, const std::string &CommandLine,
+ std::string &CmdPath, std::vector<std::string> Args) {
std::string Command = "";
- std::vector<std::string> Args;
std::string delimiters = " ";
- // Tokenize the ExecCommandLine to the command and the args to allow
- // defining a full command line as the command instead of just the
- // executed program. We cannot just pass the whole string after the command
- // as a single argument because then program sees only a single
- // command line argument (with spaces in it: "foo bar" instead
- // of "foo" and "bar").
-
- // code borrowed from:
- // http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html
- std::string::size_type lastPos =
- ExecCommandLine.find_first_not_of(delimiters, 0);
- std::string::size_type pos =
- ExecCommandLine.find_first_of(delimiters, lastPos);
+ std::string::size_type lastPos = CommandLine.find_first_not_of(delimiters, 0);
+ std::string::size_type pos = CommandLine.find_first_of(delimiters, lastPos);
while (std::string::npos != pos || std::string::npos != lastPos) {
- std::string token = ExecCommandLine.substr(lastPos, pos - lastPos);
+ std::string token = CommandLine.substr(lastPos, pos - lastPos);
if (Command == "")
Command = token;
else
Args.push_back(token);
// Skip delimiters. Note the "not_of"
- lastPos = ExecCommandLine.find_first_not_of(delimiters, pos);
+ lastPos = CommandLine.find_first_not_of(delimiters, pos);
// Find next "non-delimiter"
- pos = ExecCommandLine.find_first_of(delimiters, lastPos);
+ pos = CommandLine.find_first_of(delimiters, lastPos);
}
- std::string CmdPath = sys::Program::FindProgramByName(Command).str();
+ CmdPath = sys::Program::FindProgramByName(Command).str();
if (CmdPath.empty()) {
- Message =
- std::string("Cannot find '") + Command +
- "' in executable directory or PATH!\n";
- return 0;
+ Message =
+ std::string("Cannot find '") + Command +
+ "' in PATH!\n";
+ return;
}
Message = "Found command in: " + CmdPath + "\n";
+}
+
+// Custom execution environment create method, takes the execution command
+// as arguments
+AbstractInterpreter *AbstractInterpreter::createCustomCompiler(
+ std::string &Message,
+ const std::string &CompileCommandLine) {
+
+ std::string CmdPath;
+ std::vector<std::string> Args;
+ lexCommand(Message, CompileCommandLine, CmdPath, Args);
+ if (CmdPath.empty())
+ return 0;
+
+ return new CustomCompiler(CmdPath, Args);
+}
+
+// Custom execution environment create method, takes the execution command
+// as arguments
+AbstractInterpreter *AbstractInterpreter::createCustomExecutor(
+ std::string &Message,
+ const std::string &ExecCommandLine) {
+
+
+ std::string CmdPath;
+ std::vector<std::string> Args;
+ lexCommand(Message, ExecCommandLine, CmdPath, Args);
+ if (CmdPath.empty())
+ return 0;
return new CustomExecutor(CmdPath, Args);
}
@@ -355,7 +441,7 @@ AbstractInterpreter *AbstractInterpreter::createCustom(
//===----------------------------------------------------------------------===//
// LLC Implementation of AbstractIntepreter interface
//
-GCC::FileType LLC::OutputCode(const std::string &Bitcode,
+GCC::FileType LLC::OutputCode(const std::string &Bitcode,
sys::Path &OutputAsmFile, std::string &Error,
unsigned Timeout, unsigned MemoryLimit) {
const char *Suffix = (UseIntegratedAssembler ? ".llc.o" : ".llc.s");
@@ -376,10 +462,10 @@ GCC::FileType LLC::OutputCode(const std::string &Bitcode,
LLCArgs.push_back("-o");
LLCArgs.push_back(OutputAsmFile.c_str()); // Output to the Asm file
LLCArgs.push_back(Bitcode.c_str()); // This is the input bitcode
-
+
if (UseIntegratedAssembler)
LLCArgs.push_back("-filetype=obj");
-
+
LLCArgs.push_back (0);
outs() << (UseIntegratedAssembler ? "<llc-ia>" : "<llc>");
@@ -394,7 +480,7 @@ GCC::FileType LLC::OutputCode(const std::string &Bitcode,
Timeout, MemoryLimit))
Error = ProcessFailure(sys::Path(LLCPath), &LLCArgs[0],
Timeout, MemoryLimit);
- return UseIntegratedAssembler ? GCC::ObjectFile : GCC::AsmFile;
+ return UseIntegratedAssembler ? GCC::ObjectFile : GCC::AsmFile;
}
void LLC::compileProgram(const std::string &Bitcode, std::string *Error,
@@ -437,9 +523,9 @@ LLC *AbstractInterpreter::createLLC(const char *Argv0,
const std::vector<std::string> *GCCArgs,
bool UseIntegratedAssembler) {
std::string LLCPath =
- FindExecutable("llc", Argv0, (void *)(intptr_t)&createLLC).str();
+ PrependMainExecutablePath("llc", Argv0, (void *)(intptr_t)&createLLC).str();
if (LLCPath.empty()) {
- Message = "Cannot find `llc' in executable directory or PATH!\n";
+ Message = "Cannot find `llc' in executable directory!\n";
return 0;
}
@@ -474,7 +560,7 @@ namespace {
const std::vector<std::string> &GCCArgs =
std::vector<std::string>(),
const std::vector<std::string> &SharedLibs =
- std::vector<std::string>(),
+ std::vector<std::string>(),
unsigned Timeout = 0,
unsigned MemoryLimit = 0);
};
@@ -517,7 +603,7 @@ int JIT::ExecuteProgram(const std::string &Bitcode,
DEBUG(errs() << "\nSending output to " << OutputFile << "\n");
return RunProgramWithTimeout(sys::Path(LLIPath), &JITArgs[0],
sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
- Timeout, MemoryLimit);
+ Timeout, MemoryLimit, Error);
}
/// createJIT - Try to find the LLI executable
@@ -525,13 +611,13 @@ int JIT::ExecuteProgram(const std::string &Bitcode,
AbstractInterpreter *AbstractInterpreter::createJIT(const char *Argv0,
std::string &Message, const std::vector<std::string> *Args) {
std::string LLIPath =
- FindExecutable("lli", Argv0, (void *)(intptr_t)&createJIT).str();
+ PrependMainExecutablePath("lli", Argv0, (void *)(intptr_t)&createJIT).str();
if (!LLIPath.empty()) {
Message = "Found lli: " + LLIPath + "\n";
return new JIT(LLIPath, Args);
}
- Message = "Cannot find `lli' in executable directory or PATH!\n";
+ Message = "Cannot find `lli' in executable directory!\n";
return 0;
}
@@ -603,14 +689,14 @@ int CBE::ExecuteProgram(const std::string &Bitcode,
///
CBE *AbstractInterpreter::createCBE(const char *Argv0,
std::string &Message,
- const std::string &GCCBinary,
+ const std::string &GCCBinary,
const std::vector<std::string> *Args,
const std::vector<std::string> *GCCArgs) {
sys::Path LLCPath =
- FindExecutable("llc", Argv0, (void *)(intptr_t)&createCBE);
+ PrependMainExecutablePath("llc", Argv0, (void *)(intptr_t)&createCBE);
if (LLCPath.isEmpty()) {
Message =
- "Cannot find `llc' in executable directory or PATH!\n";
+ "Cannot find `llc' in executable directory!\n";
return 0;
}
@@ -677,9 +763,9 @@ int GCC::ExecuteProgram(const std::string &ProgramFile,
GCCArgs.push_back("-force_cpusubtype_ALL");
}
}
-
+
GCCArgs.push_back(ProgramFile.c_str()); // Specify the input filename.
-
+
GCCArgs.push_back("-x");
GCCArgs.push_back("none");
GCCArgs.push_back("-o");
@@ -771,7 +857,7 @@ int GCC::ExecuteProgram(const std::string &ProgramFile,
DEBUG(errs() << "<run locally>");
return RunProgramWithTimeout(OutputBinary, &ProgramArgs[0],
sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
- Timeout, MemoryLimit);
+ Timeout, MemoryLimit, Error);
} else {
outs() << "<run remotely>"; outs().flush();
return RunProgramRemotelyWithTimeout(sys::Path(RemoteClientPath),
@@ -793,7 +879,7 @@ int GCC::MakeSharedObject(const std::string &InputFile, FileType fileType,
OutputFile = uniqueFilename.str();
std::vector<const char*> GCCArgs;
-
+
GCCArgs.push_back(GCCPath.c_str());
if (TargetTriple.getArch() == Triple::x86)
@@ -816,7 +902,7 @@ int GCC::MakeSharedObject(const std::string &InputFile, FileType fileType,
GCCArgs.push_back("-G"); // Compile a shared library, `-G' for Sparc
else if (TargetTriple.getOS() == Triple::Darwin) {
// link all source files into a single module in data segment, rather than
- // generating blocks. dynamic_lookup requires that you set
+ // generating blocks. dynamic_lookup requires that you set
// MACOSX_DEPLOYMENT_TARGET=10.3 in your env. FIXME: it would be better for
// bugpoint to just pass that in the environment of GCC.
GCCArgs.push_back("-single_module");
@@ -837,8 +923,8 @@ int GCC::MakeSharedObject(const std::string &InputFile, FileType fileType,
GCCArgs.push_back(OutputFile.c_str()); // Output to the right filename.
GCCArgs.push_back("-O2"); // Optimize the program a bit.
-
-
+
+
// Add any arguments intended for GCC. We locate them here because this is
// most likely -L and -l options that need to come before other libraries but
// after the source. Other options won't be sensitive to placement on the
@@ -847,7 +933,7 @@ int GCC::MakeSharedObject(const std::string &InputFile, FileType fileType,
GCCArgs.push_back(ArgsForGCC[i].c_str());
GCCArgs.push_back(0); // NULL terminator
-
+
outs() << "<gcc>"; outs().flush();
DEBUG(errs() << "\nAbout to run:\t";
@@ -870,7 +956,7 @@ GCC *GCC::create(std::string &Message,
const std::vector<std::string> *Args) {
sys::Path GCCPath = sys::Program::FindProgramByName(GCCBinary);
if (GCCPath.isEmpty()) {
- Message = "Cannot find `"+ GCCBinary +"' in executable directory or PATH!\n";
+ Message = "Cannot find `"+ GCCBinary +"' in PATH!\n";
return 0;
}
diff --git a/tools/bugpoint/ToolRunner.h b/tools/bugpoint/ToolRunner.h
index cda0ddf..cfa8acf 100644
--- a/tools/bugpoint/ToolRunner.h
+++ b/tools/bugpoint/ToolRunner.h
@@ -21,7 +21,7 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/SystemUtils.h"
-#include "llvm/System/Path.h"
+#include "llvm/Support/Path.h"
#include <exception>
#include <vector>
@@ -66,7 +66,7 @@ public:
const std::string &OutputFile,
std::string *Error = 0,
const std::vector<std::string> &GCCArgs =
- std::vector<std::string>(),
+ std::vector<std::string>(),
unsigned Timeout = 0,
unsigned MemoryLimit = 0);
@@ -103,8 +103,13 @@ public:
static AbstractInterpreter* createJIT(const char *Argv0, std::string &Message,
const std::vector<std::string> *Args=0);
- static AbstractInterpreter* createCustom(std::string &Message,
- const std::string &ExecCommandLine);
+ static AbstractInterpreter*
+ createCustomCompiler(std::string &Message,
+ const std::string &CompileCommandLine);
+
+ static AbstractInterpreter*
+ createCustomExecutor(std::string &Message,
+ const std::string &ExecCommandLine);
virtual ~AbstractInterpreter() {}
diff --git a/tools/bugpoint/bugpoint.cpp b/tools/bugpoint/bugpoint.cpp
index 79cf563..f9c9e18 100644
--- a/tools/bugpoint/bugpoint.cpp
+++ b/tools/bugpoint/bugpoint.cpp
@@ -23,10 +23,14 @@
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/StandardPasses.h"
-#include "llvm/System/Process.h"
-#include "llvm/System/Signals.h"
-#include "llvm/System/Valgrind.h"
+#include "llvm/Support/Process.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/Valgrind.h"
#include "llvm/LinkAllVMCore.h"
+
+//Enable this macro to debug bugpoint itself.
+//#define DEBUG_BUGPOINT 1
+
using namespace llvm;
static cl::opt<bool>
@@ -71,9 +75,11 @@ OverrideTriple("mtriple", cl::desc("Override target triple for module"));
/// BugpointIsInterrupted - Set to true when the user presses ctrl-c.
bool llvm::BugpointIsInterrupted = false;
+#ifndef DEBUG_BUGPOINT
static void BugpointInterruptFunction() {
BugpointIsInterrupted = true;
}
+#endif
// Hack to capture a pass list.
namespace {
@@ -91,14 +97,31 @@ namespace {
}
int main(int argc, char **argv) {
+#ifndef DEBUG_BUGPOINT
llvm::sys::PrintStackTraceOnErrorSignal();
llvm::PrettyStackTraceProgram X(argc, argv);
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
+#endif
+
+ // Initialize passes
+ PassRegistry &Registry = *PassRegistry::getPassRegistry();
+ initializeCore(Registry);
+ initializeScalarOpts(Registry);
+ initializeIPO(Registry);
+ initializeAnalysis(Registry);
+ initializeIPA(Registry);
+ initializeTransformUtils(Registry);
+ initializeInstCombine(Registry);
+ initializeInstrumentation(Registry);
+ initializeTarget(Registry);
+
cl::ParseCommandLineOptions(argc, argv,
"LLVM automatic testcase reducer. See\nhttp://"
"llvm.org/cmds/bugpoint.html"
" for more information.\n");
+#ifndef DEBUG_BUGPOINT
sys::SetInterruptFunction(BugpointInterruptFunction);
+#endif
LLVMContext& Context = getGlobalContext();
// If we have an override, set it and then track the triple we want Modules
@@ -147,7 +170,9 @@ int main(int argc, char **argv) {
// Bugpoint has the ability of generating a plethora of core files, so to
// avoid filling up the disk, we prevent it
+#ifndef DEBUG_BUGPOINT
sys::Process::PreventCoreFiles();
+#endif
std::string Error;
bool Failure = D.run(Error);
OpenPOWER on IntegriCloud