mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-01 00:33:09 +00:00
Added bugpoint options: -compile-custom and -compile-command=...
I've been using this mode to narrow down llc unit tests. Example custom compile script: llc "$@" not pygrep.py 'mul\s+r([0-9]), r\1,' < bugpoint-test-program.s git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@125096 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
de86cbdc57
commit
f73311bb64
@ -28,7 +28,8 @@ namespace {
|
|||||||
// for miscompilation.
|
// for miscompilation.
|
||||||
//
|
//
|
||||||
enum OutputType {
|
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>
|
cl::opt<double>
|
||||||
@ -50,6 +51,9 @@ namespace {
|
|||||||
clEnumValN(RunCBE, "run-cbe", "Compile with CBE"),
|
clEnumValN(RunCBE, "run-cbe", "Compile with CBE"),
|
||||||
clEnumValN(CBE_bug,"cbe-bug", "Find CBE bugs"),
|
clEnumValN(CBE_bug,"cbe-bug", "Find CBE bugs"),
|
||||||
clEnumValN(LLC_Safe, "llc-safe", "Use LLC for all"),
|
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",
|
clEnumValN(Custom, "run-custom",
|
||||||
"Use -exec-command to define a command to execute "
|
"Use -exec-command to define a command to execute "
|
||||||
"the bitcode. Useful for cross-compilation."),
|
"the bitcode. Useful for cross-compilation."),
|
||||||
@ -90,6 +94,11 @@ namespace {
|
|||||||
AdditionalLinkerArgs("Xlinker",
|
AdditionalLinkerArgs("Xlinker",
|
||||||
cl::desc("Additional arguments to pass to the linker"));
|
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>
|
cl::opt<std::string>
|
||||||
CustomExecCommand("exec-command", cl::init("simulate"),
|
CustomExecCommand("exec-command", cl::init("simulate"),
|
||||||
cl::desc("Command to execute the bitcode (use with -run-custom) "
|
cl::desc("Command to execute the bitcode (use with -run-custom) "
|
||||||
@ -192,8 +201,13 @@ bool BugDriver::initializeExecutionEnvironment() {
|
|||||||
GCCBinary, &ToolArgv,
|
GCCBinary, &ToolArgv,
|
||||||
&GCCToolArgv);
|
&GCCToolArgv);
|
||||||
break;
|
break;
|
||||||
|
case CompileCustom:
|
||||||
|
Interpreter =
|
||||||
|
AbstractInterpreter::createCustomCompiler(Message, CustomCompileCommand);
|
||||||
|
break;
|
||||||
case Custom:
|
case Custom:
|
||||||
Interpreter = AbstractInterpreter::createCustom(Message, CustomExecCommand);
|
Interpreter =
|
||||||
|
AbstractInterpreter::createCustomExecutor(Message, CustomExecCommand);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Message = "Sorry, this back-end is not supported by bugpoint right now!\n";
|
Message = "Sorry, this back-end is not supported by bugpoint right now!\n";
|
||||||
@ -272,8 +286,8 @@ bool BugDriver::initializeExecutionEnvironment() {
|
|||||||
&GCCToolArgv);
|
&GCCToolArgv);
|
||||||
break;
|
break;
|
||||||
case Custom:
|
case Custom:
|
||||||
SafeInterpreter = AbstractInterpreter::createCustom(Message,
|
SafeInterpreter =
|
||||||
CustomExecCommand);
|
AbstractInterpreter::createCustomExecutor(Message, CustomExecCommand);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Message = "Sorry, this back-end is not supported by bugpoint as the "
|
Message = "Sorry, this back-end is not supported by bugpoint as the "
|
||||||
|
@ -249,6 +249,67 @@ AbstractInterpreter *AbstractInterpreter::createLLI(const char *Argv0,
|
|||||||
return 0;
|
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
|
// Custom execution command implementation of AbstractIntepreter interface
|
||||||
//
|
//
|
||||||
@ -305,51 +366,74 @@ int CustomExecutor::ExecuteProgram(const std::string &Bitcode,
|
|||||||
sys::Path(OutputFile), Timeout, MemoryLimit, Error);
|
sys::Path(OutputFile), Timeout, MemoryLimit, Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Custom execution environment create method, takes the execution command
|
// Tokenize the CommandLine to the command and the args to allow
|
||||||
// as arguments
|
// defining a full command line as the command instead of just the
|
||||||
AbstractInterpreter *AbstractInterpreter::createCustom(
|
// executed program. We cannot just pass the whole string after the command
|
||||||
std::string &Message,
|
// as a single argument because then program sees only a single
|
||||||
const std::string &ExecCommandLine) {
|
// 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::string Command = "";
|
||||||
std::vector<std::string> Args;
|
|
||||||
std::string delimiters = " ";
|
std::string delimiters = " ";
|
||||||
|
|
||||||
// Tokenize the ExecCommandLine to the command and the args to allow
|
std::string::size_type lastPos = CommandLine.find_first_not_of(delimiters, 0);
|
||||||
// defining a full command line as the command instead of just the
|
std::string::size_type pos = CommandLine.find_first_of(delimiters, lastPos);
|
||||||
// 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) {
|
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 == "")
|
if (Command == "")
|
||||||
Command = token;
|
Command = token;
|
||||||
else
|
else
|
||||||
Args.push_back(token);
|
Args.push_back(token);
|
||||||
// Skip delimiters. Note the "not_of"
|
// 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"
|
// 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()) {
|
if (CmdPath.empty()) {
|
||||||
Message =
|
Message =
|
||||||
std::string("Cannot find '") + Command +
|
std::string("Cannot find '") + Command +
|
||||||
"' in PATH!\n";
|
"' in PATH!\n";
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Message = "Found command in: " + CmdPath + "\n";
|
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);
|
return new CustomExecutor(CmdPath, Args);
|
||||||
}
|
}
|
||||||
|
@ -103,8 +103,13 @@ public:
|
|||||||
static AbstractInterpreter* createJIT(const char *Argv0, std::string &Message,
|
static AbstractInterpreter* createJIT(const char *Argv0, std::string &Message,
|
||||||
const std::vector<std::string> *Args=0);
|
const std::vector<std::string> *Args=0);
|
||||||
|
|
||||||
static AbstractInterpreter* createCustom(std::string &Message,
|
static AbstractInterpreter*
|
||||||
const std::string &ExecCommandLine);
|
createCustomCompiler(std::string &Message,
|
||||||
|
const std::string &CompileCommandLine);
|
||||||
|
|
||||||
|
static AbstractInterpreter*
|
||||||
|
createCustomExecutor(std::string &Message,
|
||||||
|
const std::string &ExecCommandLine);
|
||||||
|
|
||||||
|
|
||||||
virtual ~AbstractInterpreter() {}
|
virtual ~AbstractInterpreter() {}
|
||||||
|
Loading…
Reference in New Issue
Block a user