mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-25 16:24:23 +00:00
Add a new -cbe-bug mode, which works just like -run-llc, except that it uses
LLC as the reference compiler to reduce testcases for bugs in GCC. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30400 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -30,7 +30,6 @@ class Instruction;
|
|||||||
|
|
||||||
class DebugCrashes;
|
class DebugCrashes;
|
||||||
|
|
||||||
class CBE;
|
|
||||||
class GCC;
|
class GCC;
|
||||||
|
|
||||||
extern bool DisableSimplifyCFG;
|
extern bool DisableSimplifyCFG;
|
||||||
@ -45,7 +44,7 @@ class BugDriver {
|
|||||||
Module *Program; // The raw program, linked together
|
Module *Program; // The raw program, linked together
|
||||||
std::vector<const PassInfo*> PassesToRun;
|
std::vector<const PassInfo*> PassesToRun;
|
||||||
AbstractInterpreter *Interpreter; // How to run the program
|
AbstractInterpreter *Interpreter; // How to run the program
|
||||||
CBE *cbe;
|
AbstractInterpreter *cbe;
|
||||||
GCC *gcc;
|
GCC *gcc;
|
||||||
bool run_as_child;
|
bool run_as_child;
|
||||||
bool run_find_bugs;
|
bool run_find_bugs;
|
||||||
|
@ -28,7 +28,7 @@ namespace {
|
|||||||
// for miscompilation.
|
// for miscompilation.
|
||||||
//
|
//
|
||||||
enum OutputType {
|
enum OutputType {
|
||||||
AutoPick, RunLLI, RunJIT, RunLLC, RunCBE
|
AutoPick, RunLLI, RunJIT, RunLLC, RunCBE, CBE_bug
|
||||||
};
|
};
|
||||||
|
|
||||||
cl::opt<double>
|
cl::opt<double>
|
||||||
@ -46,6 +46,7 @@ namespace {
|
|||||||
clEnumValN(RunJIT, "run-jit", "Execute with JIT"),
|
clEnumValN(RunJIT, "run-jit", "Execute with JIT"),
|
||||||
clEnumValN(RunLLC, "run-llc", "Compile with LLC"),
|
clEnumValN(RunLLC, "run-llc", "Compile with LLC"),
|
||||||
clEnumValN(RunCBE, "run-cbe", "Compile with CBE"),
|
clEnumValN(RunCBE, "run-cbe", "Compile with CBE"),
|
||||||
|
clEnumValN(CBE_bug,"cbe-bug", "Find CBE bugs"),
|
||||||
clEnumValEnd),
|
clEnumValEnd),
|
||||||
cl::init(AutoPick));
|
cl::init(AutoPick));
|
||||||
|
|
||||||
@ -133,8 +134,9 @@ bool BugDriver::initializeExecutionEnvironment() {
|
|||||||
&ToolArgv);
|
&ToolArgv);
|
||||||
break;
|
break;
|
||||||
case RunCBE:
|
case RunCBE:
|
||||||
Interpreter = cbe = AbstractInterpreter::createCBE(getToolName(), Message,
|
case CBE_bug:
|
||||||
&ToolArgv);
|
Interpreter = AbstractInterpreter::createCBE(getToolName(), Message,
|
||||||
|
&ToolArgv);
|
||||||
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";
|
||||||
@ -143,10 +145,19 @@ bool BugDriver::initializeExecutionEnvironment() {
|
|||||||
std::cerr << Message;
|
std::cerr << Message;
|
||||||
|
|
||||||
// Initialize auxiliary tools for debugging
|
// Initialize auxiliary tools for debugging
|
||||||
if (!cbe) {
|
if (InterpreterSel == RunCBE) {
|
||||||
|
// We already created a CBE, reuse it.
|
||||||
|
cbe = Interpreter;
|
||||||
|
} else if (InterpreterSel == CBE_bug) {
|
||||||
|
// We want to debug the CBE itself. Use LLC as the 'known-good' compiler.
|
||||||
|
std::vector<std::string> ToolArgs;
|
||||||
|
ToolArgs.push_back("--relocation-model=pic");
|
||||||
|
cbe = AbstractInterpreter::createLLC(getToolName(), Message, &ToolArgs);
|
||||||
|
} else {
|
||||||
cbe = AbstractInterpreter::createCBE(getToolName(), Message, &ToolArgv);
|
cbe = AbstractInterpreter::createCBE(getToolName(), Message, &ToolArgv);
|
||||||
if (!cbe) { std::cout << Message << "\nExiting.\n"; exit(1); }
|
|
||||||
}
|
}
|
||||||
|
if (!cbe) { std::cout << Message << "\nExiting.\n"; exit(1); }
|
||||||
|
|
||||||
gcc = GCC::create(getToolName(), Message);
|
gcc = GCC::create(getToolName(), Message);
|
||||||
if (!gcc) { std::cout << Message << "\nExiting.\n"; exit(1); }
|
if (!gcc) { std::cout << Message << "\nExiting.\n"; exit(1); }
|
||||||
|
|
||||||
@ -237,7 +248,8 @@ std::string BugDriver::executeProgram(std::string OutputFile,
|
|||||||
// compile the program. If so, we should pass the user's -Xlinker options
|
// compile the program. If so, we should pass the user's -Xlinker options
|
||||||
// as the GCCArgs.
|
// as the GCCArgs.
|
||||||
int RetVal = 0;
|
int RetVal = 0;
|
||||||
if (InterpreterSel == RunLLC || InterpreterSel == RunCBE)
|
if (InterpreterSel == RunLLC || InterpreterSel == RunCBE ||
|
||||||
|
InterpreterSel == CBE_bug)
|
||||||
RetVal = AI->ExecuteProgram(BytecodeFile, InputArgv, InputFile,
|
RetVal = AI->ExecuteProgram(BytecodeFile, InputArgv, InputFile,
|
||||||
OutputFile, AdditionalLinkerArgs, SharedObjs,
|
OutputFile, AdditionalLinkerArgs, SharedObjs,
|
||||||
Timeout);
|
Timeout);
|
||||||
@ -271,8 +283,7 @@ std::string BugDriver::executeProgram(std::string OutputFile,
|
|||||||
///
|
///
|
||||||
std::string BugDriver::executeProgramWithCBE(std::string OutputFile) {
|
std::string BugDriver::executeProgramWithCBE(std::string OutputFile) {
|
||||||
bool ProgramExitedNonzero;
|
bool ProgramExitedNonzero;
|
||||||
std::string outFN = executeProgram(OutputFile, "", "",
|
std::string outFN = executeProgram(OutputFile, "", "", cbe,
|
||||||
(AbstractInterpreter*)cbe,
|
|
||||||
&ProgramExitedNonzero);
|
&ProgramExitedNonzero);
|
||||||
if (ProgramExitedNonzero) {
|
if (ProgramExitedNonzero) {
|
||||||
std::cerr
|
std::cerr
|
||||||
@ -285,28 +296,18 @@ std::string BugDriver::executeProgramWithCBE(std::string OutputFile) {
|
|||||||
|
|
||||||
std::string BugDriver::compileSharedObject(const std::string &BytecodeFile) {
|
std::string BugDriver::compileSharedObject(const std::string &BytecodeFile) {
|
||||||
assert(Interpreter && "Interpreter should have been created already!");
|
assert(Interpreter && "Interpreter should have been created already!");
|
||||||
sys::Path OutputCFile;
|
sys::Path OutputFile;
|
||||||
|
|
||||||
// Using CBE
|
// Using CBE
|
||||||
cbe->OutputC(BytecodeFile, OutputCFile);
|
GCC::FileType FT = cbe->OutputCode(BytecodeFile, OutputFile);
|
||||||
|
|
||||||
#if 0 /* This is an alternative, as yet unimplemented */
|
|
||||||
// Using LLC
|
|
||||||
std::string Message;
|
|
||||||
LLC *llc = createLLCtool(Message);
|
|
||||||
if (llc->OutputAsm(BytecodeFile, OutputFile)) {
|
|
||||||
std::cerr << "Could not generate asm code with `llc', exiting.\n";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
std::string SharedObjectFile;
|
std::string SharedObjectFile;
|
||||||
if (gcc->MakeSharedObject(OutputCFile.toString(), GCC::CFile,
|
if (gcc->MakeSharedObject(OutputFile.toString(), FT,
|
||||||
SharedObjectFile, AdditionalLinkerArgs))
|
SharedObjectFile, AdditionalLinkerArgs))
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
||||||
// Remove the intermediate C file
|
// Remove the intermediate C file
|
||||||
OutputCFile.eraseFromDisk();
|
OutputFile.eraseFromDisk();
|
||||||
|
|
||||||
return "./" + SharedObjectFile;
|
return "./" + SharedObjectFile;
|
||||||
}
|
}
|
||||||
@ -316,7 +317,7 @@ std::string BugDriver::compileSharedObject(const std::string &BytecodeFile) {
|
|||||||
/// otherwise. Note: initializeExecutionEnvironment should be called BEFORE
|
/// otherwise. Note: initializeExecutionEnvironment should be called BEFORE
|
||||||
/// this function.
|
/// this function.
|
||||||
///
|
///
|
||||||
bool BugDriver::createReferenceFile(Module *M, const std::string &Filename){
|
bool BugDriver::createReferenceFile(Module *M, const std::string &Filename) {
|
||||||
try {
|
try {
|
||||||
compileProgram(Program);
|
compileProgram(Program);
|
||||||
} catch (ToolExecutionError &TEE) {
|
} catch (ToolExecutionError &TEE) {
|
||||||
|
@ -37,6 +37,13 @@ static int RunProgramWithTimeout(const sys::Path &ProgramPath,
|
|||||||
redirects[0] = &StdInFile;
|
redirects[0] = &StdInFile;
|
||||||
redirects[1] = &StdOutFile;
|
redirects[1] = &StdOutFile;
|
||||||
redirects[2] = &StdErrFile;
|
redirects[2] = &StdErrFile;
|
||||||
|
|
||||||
|
{
|
||||||
|
std::cerr << "RUN:";
|
||||||
|
for (unsigned i = 0; Args[i]; ++i)
|
||||||
|
std::cerr << " " << Args[i];
|
||||||
|
std::cerr << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
sys::Program::ExecuteAndWait(ProgramPath, Args, 0, redirects, NumSeconds);
|
sys::Program::ExecuteAndWait(ProgramPath, Args, 0, redirects, NumSeconds);
|
||||||
@ -155,7 +162,8 @@ AbstractInterpreter *AbstractInterpreter::createLLI(const std::string &ProgPath,
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// LLC Implementation of AbstractIntepreter interface
|
// LLC Implementation of AbstractIntepreter interface
|
||||||
//
|
//
|
||||||
void LLC::OutputAsm(const std::string &Bytecode, sys::Path &OutputAsmFile) {
|
GCC::FileType LLC::OutputCode(const std::string &Bytecode,
|
||||||
|
sys::Path &OutputAsmFile) {
|
||||||
sys::Path uniqueFile(Bytecode+".llc.s");
|
sys::Path uniqueFile(Bytecode+".llc.s");
|
||||||
std::string ErrMsg;
|
std::string ErrMsg;
|
||||||
if (uniqueFile.makeUnique(true, &ErrMsg)) {
|
if (uniqueFile.makeUnique(true, &ErrMsg)) {
|
||||||
@ -185,11 +193,13 @@ void LLC::OutputAsm(const std::string &Bytecode, sys::Path &OutputAsmFile) {
|
|||||||
if (RunProgramWithTimeout(sys::Path(LLCPath), &LLCArgs[0],
|
if (RunProgramWithTimeout(sys::Path(LLCPath), &LLCArgs[0],
|
||||||
sys::Path(), sys::Path(), sys::Path()))
|
sys::Path(), sys::Path(), sys::Path()))
|
||||||
ProcessFailure(sys::Path(LLCPath), &LLCArgs[0]);
|
ProcessFailure(sys::Path(LLCPath), &LLCArgs[0]);
|
||||||
|
|
||||||
|
return GCC::AsmFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLC::compileProgram(const std::string &Bytecode) {
|
void LLC::compileProgram(const std::string &Bytecode) {
|
||||||
sys::Path OutputAsmFile;
|
sys::Path OutputAsmFile;
|
||||||
OutputAsm(Bytecode, OutputAsmFile);
|
OutputCode(Bytecode, OutputAsmFile);
|
||||||
OutputAsmFile.eraseFromDisk();
|
OutputAsmFile.eraseFromDisk();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,7 +212,7 @@ int LLC::ExecuteProgram(const std::string &Bytecode,
|
|||||||
unsigned Timeout) {
|
unsigned Timeout) {
|
||||||
|
|
||||||
sys::Path OutputAsmFile;
|
sys::Path OutputAsmFile;
|
||||||
OutputAsm(Bytecode, OutputAsmFile);
|
OutputCode(Bytecode, OutputAsmFile);
|
||||||
FileRemover OutFileRemover(OutputAsmFile);
|
FileRemover OutFileRemover(OutputAsmFile);
|
||||||
|
|
||||||
std::vector<std::string> GCCArgs(ArgsForGCC);
|
std::vector<std::string> GCCArgs(ArgsForGCC);
|
||||||
@ -313,7 +323,8 @@ AbstractInterpreter *AbstractInterpreter::createJIT(const std::string &ProgPath,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBE::OutputC(const std::string &Bytecode, sys::Path& OutputCFile) {
|
GCC::FileType CBE::OutputCode(const std::string &Bytecode,
|
||||||
|
sys::Path &OutputCFile) {
|
||||||
sys::Path uniqueFile(Bytecode+".cbe.c");
|
sys::Path uniqueFile(Bytecode+".cbe.c");
|
||||||
std::string ErrMsg;
|
std::string ErrMsg;
|
||||||
if (uniqueFile.makeUnique(true, &ErrMsg)) {
|
if (uniqueFile.makeUnique(true, &ErrMsg)) {
|
||||||
@ -344,11 +355,12 @@ void CBE::OutputC(const std::string &Bytecode, sys::Path& OutputCFile) {
|
|||||||
if (RunProgramWithTimeout(LLCPath, &LLCArgs[0], sys::Path(), sys::Path(),
|
if (RunProgramWithTimeout(LLCPath, &LLCArgs[0], sys::Path(), sys::Path(),
|
||||||
sys::Path()))
|
sys::Path()))
|
||||||
ProcessFailure(LLCPath, &LLCArgs[0]);
|
ProcessFailure(LLCPath, &LLCArgs[0]);
|
||||||
|
return GCC::CFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBE::compileProgram(const std::string &Bytecode) {
|
void CBE::compileProgram(const std::string &Bytecode) {
|
||||||
sys::Path OutputCFile;
|
sys::Path OutputCFile;
|
||||||
OutputC(Bytecode, OutputCFile);
|
OutputCode(Bytecode, OutputCFile);
|
||||||
OutputCFile.eraseFromDisk();
|
OutputCFile.eraseFromDisk();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,7 +372,7 @@ int CBE::ExecuteProgram(const std::string &Bytecode,
|
|||||||
const std::vector<std::string> &SharedLibs,
|
const std::vector<std::string> &SharedLibs,
|
||||||
unsigned Timeout) {
|
unsigned Timeout) {
|
||||||
sys::Path OutputCFile;
|
sys::Path OutputCFile;
|
||||||
OutputC(Bytecode, OutputCFile);
|
OutputCode(Bytecode, OutputCFile);
|
||||||
|
|
||||||
FileRemover CFileRemove(OutputCFile);
|
FileRemover CFileRemove(OutputCFile);
|
||||||
|
|
||||||
|
@ -104,6 +104,15 @@ public:
|
|||||||
/// thrown, otherwise, this function will just return.
|
/// thrown, otherwise, this function will just return.
|
||||||
virtual void compileProgram(const std::string &Bytecode) {}
|
virtual void compileProgram(const std::string &Bytecode) {}
|
||||||
|
|
||||||
|
/// OutputCode - Compile the specified program from bytecode to code
|
||||||
|
/// understood by the GCC driver (either C or asm). If the code generator
|
||||||
|
/// fails, an exception should be thrown, otherwise, this function returns the
|
||||||
|
/// type of code emitted.
|
||||||
|
virtual GCC::FileType OutputCode(const std::string &Bytecode,
|
||||||
|
sys::Path &OutFile) {
|
||||||
|
throw std::string("OutputCode not supported by this AbstractInterpreter!");
|
||||||
|
}
|
||||||
|
|
||||||
/// ExecuteProgram - Run the specified bytecode file, emitting output to the
|
/// ExecuteProgram - Run the specified bytecode file, emitting output to the
|
||||||
/// specified filename. This returns the exit code of the program.
|
/// specified filename. This returns the exit code of the program.
|
||||||
///
|
///
|
||||||
@ -149,11 +158,12 @@ public:
|
|||||||
std::vector<std::string>(),
|
std::vector<std::string>(),
|
||||||
unsigned Timeout = 0);
|
unsigned Timeout = 0);
|
||||||
|
|
||||||
// Sometimes we just want to go half-way and only generate the .c file, not
|
/// OutputCode - Compile the specified program from bytecode to code
|
||||||
// necessarily compile it with GCC and run the program. This throws an
|
/// understood by the GCC driver (either C or asm). If the code generator
|
||||||
// exception if LLC crashes.
|
/// fails, an exception should be thrown, otherwise, this function returns the
|
||||||
//
|
/// type of code emitted.
|
||||||
virtual void OutputC(const std::string &Bytecode, sys::Path& OutputCFile);
|
virtual GCC::FileType OutputCode(const std::string &Bytecode,
|
||||||
|
sys::Path &OutFile);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -188,11 +198,9 @@ public:
|
|||||||
std::vector<std::string>(),
|
std::vector<std::string>(),
|
||||||
unsigned Timeout = 0);
|
unsigned Timeout = 0);
|
||||||
|
|
||||||
// Sometimes we just want to go half-way and only generate the .s file,
|
virtual GCC::FileType OutputCode(const std::string &Bytecode,
|
||||||
// not necessarily compile it all the way and run the program. This throws
|
sys::Path &OutFile);
|
||||||
// an exception if execution of LLC fails.
|
|
||||||
//
|
|
||||||
void OutputAsm(const std::string &Bytecode, sys::Path &OutputAsmFile);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
Reference in New Issue
Block a user