diff options
author | Anton Korobeynikov <asl@math.spbu.ru> | 2008-04-28 20:53:48 +0000 |
---|---|---|
committer | Anton Korobeynikov <asl@math.spbu.ru> | 2008-04-28 20:53:48 +0000 |
commit | 9ef7425a4d44ff129495da2357c98c67162fbeff (patch) | |
tree | 724b2bde81a9b0ca7ef94bc4e8931af9868be6c3 /tools/bugpoint/ToolRunner.cpp | |
parent | 3e2dda63d03b84e558c757fae67ee8fe028b9124 (diff) | |
download | external_llvm-9ef7425a4d44ff129495da2357c98c67162fbeff.zip external_llvm-9ef7425a4d44ff129495da2357c98c67162fbeff.tar.gz external_llvm-9ef7425a4d44ff129495da2357c98c67162fbeff.tar.bz2 |
Add possibility of using arbitrary to to execute stuff from bugpoint.
Patch by Pekka Jääskeläinen!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50373 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/bugpoint/ToolRunner.cpp')
-rw-r--r-- | tools/bugpoint/ToolRunner.cpp | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/tools/bugpoint/ToolRunner.cpp b/tools/bugpoint/ToolRunner.cpp index d1e058e..d25ce6c 100644 --- a/tools/bugpoint/ToolRunner.cpp +++ b/tools/bugpoint/ToolRunner.cpp @@ -174,6 +174,110 @@ AbstractInterpreter *AbstractInterpreter::createLLI(const std::string &ProgPath, return 0; } +//===---------------------------------------------------------------------===// +// 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 +// a simulator that executes the generated binary. +namespace { + class CustomExecutor : public AbstractInterpreter { + std::string ExecutionCommand; + std::vector<std::string> ExecutorArgs; + public: + CustomExecutor( + const std::string &ExecutionCmd, std::vector<std::string> ExecArgs) : + ExecutionCommand(ExecutionCmd), ExecutorArgs(ExecArgs) {} + + virtual int ExecuteProgram(const std::string &Bitcode, + const std::vector<std::string> &Args, + const std::string &InputFile, + const std::string &OutputFile, + const std::vector<std::string> &GCCArgs, + const std::vector<std::string> &SharedLibs = + std::vector<std::string>(), + unsigned Timeout = 0, + unsigned MemoryLimit = 0); + }; +} + +int CustomExecutor::ExecuteProgram(const std::string &Bitcode, + const std::vector<std::string> &Args, + const std::string &InputFile, + const std::string &OutputFile, + const std::vector<std::string> &GCCArgs, + const std::vector<std::string> &SharedLibs, + unsigned Timeout, + unsigned MemoryLimit) { + + std::vector<const char*> ProgramArgs; + ProgramArgs.push_back(ExecutionCommand.c_str()); + + for (std::size_t i = 0; i < ExecutorArgs.size(); ++i) + ProgramArgs.push_back(ExecutorArgs.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 = Args.size(); i != e; ++i) + ProgramArgs.push_back(Args[i].c_str()); + + return RunProgramWithTimeout( + sys::Path(ExecutionCommand), + &ProgramArgs[0], sys::Path(InputFile), sys::Path(OutputFile), + sys::Path(OutputFile), Timeout, MemoryLimit); +} + +// Custom execution environment create method, takes the execution command +// as arguments +AbstractInterpreter *AbstractInterpreter::createCustom( + const std::string &ProgramPath, + std::string &Message, + const std::string &ExecCommandLine) { + + 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); + + while (std::string::npos != pos || std::string::npos != lastPos) { + std::string token = ExecCommandLine.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); + // Find next "non-delimiter" + pos = ExecCommandLine.find_first_of(delimiters, lastPos); + } + + std::string CmdPath = FindExecutable(Command, ProgramPath).toString(); + if (CmdPath.empty()) { + Message = + std::string("Cannot find '") + Command + + "' in executable directory or PATH!\n"; + return 0; + } + + Message = "Found command in: " + CmdPath + "\n"; + + return new CustomExecutor(CmdPath, Args); +} + //===----------------------------------------------------------------------===// // LLC Implementation of AbstractIntepreter interface // |