1*9880d681SAndroid Build Coastguard Worker //===- ExecutionDriver.cpp - Allow execution of LLVM program --------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file contains code used to execute the program utilizing one of the
11*9880d681SAndroid Build Coastguard Worker // various ways of running LLVM bitcode.
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker
15*9880d681SAndroid Build Coastguard Worker #include "BugDriver.h"
16*9880d681SAndroid Build Coastguard Worker #include "ToolRunner.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/FileUtilities.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Program.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/SystemUtils.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
23*9880d681SAndroid Build Coastguard Worker #include <fstream>
24*9880d681SAndroid Build Coastguard Worker
25*9880d681SAndroid Build Coastguard Worker using namespace llvm;
26*9880d681SAndroid Build Coastguard Worker
27*9880d681SAndroid Build Coastguard Worker namespace {
28*9880d681SAndroid Build Coastguard Worker // OutputType - Allow the user to specify the way code should be run, to test
29*9880d681SAndroid Build Coastguard Worker // for miscompilation.
30*9880d681SAndroid Build Coastguard Worker //
31*9880d681SAndroid Build Coastguard Worker enum OutputType {
32*9880d681SAndroid Build Coastguard Worker AutoPick, RunLLI, RunJIT, RunLLC, RunLLCIA, LLC_Safe, CompileCustom, Custom
33*9880d681SAndroid Build Coastguard Worker };
34*9880d681SAndroid Build Coastguard Worker
35*9880d681SAndroid Build Coastguard Worker cl::opt<double>
36*9880d681SAndroid Build Coastguard Worker AbsTolerance("abs-tolerance", cl::desc("Absolute error tolerated"),
37*9880d681SAndroid Build Coastguard Worker cl::init(0.0));
38*9880d681SAndroid Build Coastguard Worker cl::opt<double>
39*9880d681SAndroid Build Coastguard Worker RelTolerance("rel-tolerance", cl::desc("Relative error tolerated"),
40*9880d681SAndroid Build Coastguard Worker cl::init(0.0));
41*9880d681SAndroid Build Coastguard Worker
42*9880d681SAndroid Build Coastguard Worker cl::opt<OutputType>
43*9880d681SAndroid Build Coastguard Worker InterpreterSel(cl::desc("Specify the \"test\" i.e. suspect back-end:"),
44*9880d681SAndroid Build Coastguard Worker cl::values(clEnumValN(AutoPick, "auto", "Use best guess"),
45*9880d681SAndroid Build Coastguard Worker clEnumValN(RunLLI, "run-int",
46*9880d681SAndroid Build Coastguard Worker "Execute with the interpreter"),
47*9880d681SAndroid Build Coastguard Worker clEnumValN(RunJIT, "run-jit", "Execute with JIT"),
48*9880d681SAndroid Build Coastguard Worker clEnumValN(RunLLC, "run-llc", "Compile with LLC"),
49*9880d681SAndroid Build Coastguard Worker clEnumValN(RunLLCIA, "run-llc-ia",
50*9880d681SAndroid Build Coastguard Worker "Compile with LLC with integrated assembler"),
51*9880d681SAndroid Build Coastguard Worker clEnumValN(LLC_Safe, "llc-safe", "Use LLC for all"),
52*9880d681SAndroid Build Coastguard Worker clEnumValN(CompileCustom, "compile-custom",
53*9880d681SAndroid Build Coastguard Worker "Use -compile-command to define a command to "
54*9880d681SAndroid Build Coastguard Worker "compile the bitcode. Useful to avoid linking."),
55*9880d681SAndroid Build Coastguard Worker clEnumValN(Custom, "run-custom",
56*9880d681SAndroid Build Coastguard Worker "Use -exec-command to define a command to execute "
57*9880d681SAndroid Build Coastguard Worker "the bitcode. Useful for cross-compilation."),
58*9880d681SAndroid Build Coastguard Worker clEnumValEnd),
59*9880d681SAndroid Build Coastguard Worker cl::init(AutoPick));
60*9880d681SAndroid Build Coastguard Worker
61*9880d681SAndroid Build Coastguard Worker cl::opt<OutputType>
62*9880d681SAndroid Build Coastguard Worker SafeInterpreterSel(cl::desc("Specify \"safe\" i.e. known-good backend:"),
63*9880d681SAndroid Build Coastguard Worker cl::values(clEnumValN(AutoPick, "safe-auto", "Use best guess"),
64*9880d681SAndroid Build Coastguard Worker clEnumValN(RunLLC, "safe-run-llc", "Compile with LLC"),
65*9880d681SAndroid Build Coastguard Worker clEnumValN(Custom, "safe-run-custom",
66*9880d681SAndroid Build Coastguard Worker "Use -exec-command to define a command to execute "
67*9880d681SAndroid Build Coastguard Worker "the bitcode. Useful for cross-compilation."),
68*9880d681SAndroid Build Coastguard Worker clEnumValEnd),
69*9880d681SAndroid Build Coastguard Worker cl::init(AutoPick));
70*9880d681SAndroid Build Coastguard Worker
71*9880d681SAndroid Build Coastguard Worker cl::opt<std::string>
72*9880d681SAndroid Build Coastguard Worker SafeInterpreterPath("safe-path",
73*9880d681SAndroid Build Coastguard Worker cl::desc("Specify the path to the \"safe\" backend program"),
74*9880d681SAndroid Build Coastguard Worker cl::init(""));
75*9880d681SAndroid Build Coastguard Worker
76*9880d681SAndroid Build Coastguard Worker cl::opt<bool>
77*9880d681SAndroid Build Coastguard Worker AppendProgramExitCode("append-exit-code",
78*9880d681SAndroid Build Coastguard Worker cl::desc("Append the exit code to the output so it gets diff'd too"),
79*9880d681SAndroid Build Coastguard Worker cl::init(false));
80*9880d681SAndroid Build Coastguard Worker
81*9880d681SAndroid Build Coastguard Worker cl::opt<std::string>
82*9880d681SAndroid Build Coastguard Worker InputFile("input", cl::init("/dev/null"),
83*9880d681SAndroid Build Coastguard Worker cl::desc("Filename to pipe in as stdin (default: /dev/null)"));
84*9880d681SAndroid Build Coastguard Worker
85*9880d681SAndroid Build Coastguard Worker cl::list<std::string>
86*9880d681SAndroid Build Coastguard Worker AdditionalSOs("additional-so",
87*9880d681SAndroid Build Coastguard Worker cl::desc("Additional shared objects to load "
88*9880d681SAndroid Build Coastguard Worker "into executing programs"));
89*9880d681SAndroid Build Coastguard Worker
90*9880d681SAndroid Build Coastguard Worker cl::list<std::string>
91*9880d681SAndroid Build Coastguard Worker AdditionalLinkerArgs("Xlinker",
92*9880d681SAndroid Build Coastguard Worker cl::desc("Additional arguments to pass to the linker"));
93*9880d681SAndroid Build Coastguard Worker
94*9880d681SAndroid Build Coastguard Worker cl::opt<std::string>
95*9880d681SAndroid Build Coastguard Worker CustomCompileCommand("compile-command", cl::init("llc"),
96*9880d681SAndroid Build Coastguard Worker cl::desc("Command to compile the bitcode (use with -compile-custom) "
97*9880d681SAndroid Build Coastguard Worker "(default: llc)"));
98*9880d681SAndroid Build Coastguard Worker
99*9880d681SAndroid Build Coastguard Worker cl::opt<std::string>
100*9880d681SAndroid Build Coastguard Worker CustomExecCommand("exec-command", cl::init("simulate"),
101*9880d681SAndroid Build Coastguard Worker cl::desc("Command to execute the bitcode (use with -run-custom) "
102*9880d681SAndroid Build Coastguard Worker "(default: simulate)"));
103*9880d681SAndroid Build Coastguard Worker }
104*9880d681SAndroid Build Coastguard Worker
105*9880d681SAndroid Build Coastguard Worker namespace llvm {
106*9880d681SAndroid Build Coastguard Worker // Anything specified after the --args option are taken as arguments to the
107*9880d681SAndroid Build Coastguard Worker // program being debugged.
108*9880d681SAndroid Build Coastguard Worker cl::list<std::string>
109*9880d681SAndroid Build Coastguard Worker InputArgv("args", cl::Positional, cl::desc("<program arguments>..."),
110*9880d681SAndroid Build Coastguard Worker cl::ZeroOrMore, cl::PositionalEatsArgs);
111*9880d681SAndroid Build Coastguard Worker
112*9880d681SAndroid Build Coastguard Worker cl::opt<std::string>
113*9880d681SAndroid Build Coastguard Worker OutputPrefix("output-prefix", cl::init("bugpoint"),
114*9880d681SAndroid Build Coastguard Worker cl::desc("Prefix to use for outputs (default: 'bugpoint')"));
115*9880d681SAndroid Build Coastguard Worker }
116*9880d681SAndroid Build Coastguard Worker
117*9880d681SAndroid Build Coastguard Worker namespace {
118*9880d681SAndroid Build Coastguard Worker cl::list<std::string>
119*9880d681SAndroid Build Coastguard Worker ToolArgv("tool-args", cl::Positional, cl::desc("<tool arguments>..."),
120*9880d681SAndroid Build Coastguard Worker cl::ZeroOrMore, cl::PositionalEatsArgs);
121*9880d681SAndroid Build Coastguard Worker
122*9880d681SAndroid Build Coastguard Worker cl::list<std::string>
123*9880d681SAndroid Build Coastguard Worker SafeToolArgv("safe-tool-args", cl::Positional,
124*9880d681SAndroid Build Coastguard Worker cl::desc("<safe-tool arguments>..."),
125*9880d681SAndroid Build Coastguard Worker cl::ZeroOrMore, cl::PositionalEatsArgs);
126*9880d681SAndroid Build Coastguard Worker
127*9880d681SAndroid Build Coastguard Worker cl::opt<std::string>
128*9880d681SAndroid Build Coastguard Worker CCBinary("gcc", cl::init(""), cl::desc("The gcc binary to use."));
129*9880d681SAndroid Build Coastguard Worker
130*9880d681SAndroid Build Coastguard Worker cl::list<std::string>
131*9880d681SAndroid Build Coastguard Worker CCToolArgv("gcc-tool-args", cl::Positional,
132*9880d681SAndroid Build Coastguard Worker cl::desc("<gcc-tool arguments>..."),
133*9880d681SAndroid Build Coastguard Worker cl::ZeroOrMore, cl::PositionalEatsArgs);
134*9880d681SAndroid Build Coastguard Worker }
135*9880d681SAndroid Build Coastguard Worker
136*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
137*9880d681SAndroid Build Coastguard Worker // BugDriver method implementation
138*9880d681SAndroid Build Coastguard Worker //
139*9880d681SAndroid Build Coastguard Worker
140*9880d681SAndroid Build Coastguard Worker /// initializeExecutionEnvironment - This method is used to set up the
141*9880d681SAndroid Build Coastguard Worker /// environment for executing LLVM programs.
142*9880d681SAndroid Build Coastguard Worker ///
initializeExecutionEnvironment()143*9880d681SAndroid Build Coastguard Worker bool BugDriver::initializeExecutionEnvironment() {
144*9880d681SAndroid Build Coastguard Worker outs() << "Initializing execution environment: ";
145*9880d681SAndroid Build Coastguard Worker
146*9880d681SAndroid Build Coastguard Worker // Create an instance of the AbstractInterpreter interface as specified on
147*9880d681SAndroid Build Coastguard Worker // the command line
148*9880d681SAndroid Build Coastguard Worker SafeInterpreter = nullptr;
149*9880d681SAndroid Build Coastguard Worker std::string Message;
150*9880d681SAndroid Build Coastguard Worker
151*9880d681SAndroid Build Coastguard Worker if (CCBinary.empty()) {
152*9880d681SAndroid Build Coastguard Worker if (sys::findProgramByName("clang"))
153*9880d681SAndroid Build Coastguard Worker CCBinary = "clang";
154*9880d681SAndroid Build Coastguard Worker else
155*9880d681SAndroid Build Coastguard Worker CCBinary = "gcc";
156*9880d681SAndroid Build Coastguard Worker }
157*9880d681SAndroid Build Coastguard Worker
158*9880d681SAndroid Build Coastguard Worker switch (InterpreterSel) {
159*9880d681SAndroid Build Coastguard Worker case AutoPick:
160*9880d681SAndroid Build Coastguard Worker if (!Interpreter) {
161*9880d681SAndroid Build Coastguard Worker InterpreterSel = RunJIT;
162*9880d681SAndroid Build Coastguard Worker Interpreter = AbstractInterpreter::createJIT(getToolName(), Message,
163*9880d681SAndroid Build Coastguard Worker &ToolArgv);
164*9880d681SAndroid Build Coastguard Worker }
165*9880d681SAndroid Build Coastguard Worker if (!Interpreter) {
166*9880d681SAndroid Build Coastguard Worker InterpreterSel = RunLLC;
167*9880d681SAndroid Build Coastguard Worker Interpreter = AbstractInterpreter::createLLC(getToolName(), Message,
168*9880d681SAndroid Build Coastguard Worker CCBinary, &ToolArgv,
169*9880d681SAndroid Build Coastguard Worker &CCToolArgv);
170*9880d681SAndroid Build Coastguard Worker }
171*9880d681SAndroid Build Coastguard Worker if (!Interpreter) {
172*9880d681SAndroid Build Coastguard Worker InterpreterSel = RunLLI;
173*9880d681SAndroid Build Coastguard Worker Interpreter = AbstractInterpreter::createLLI(getToolName(), Message,
174*9880d681SAndroid Build Coastguard Worker &ToolArgv);
175*9880d681SAndroid Build Coastguard Worker }
176*9880d681SAndroid Build Coastguard Worker if (!Interpreter) {
177*9880d681SAndroid Build Coastguard Worker InterpreterSel = AutoPick;
178*9880d681SAndroid Build Coastguard Worker Message = "Sorry, I can't automatically select an interpreter!\n";
179*9880d681SAndroid Build Coastguard Worker }
180*9880d681SAndroid Build Coastguard Worker break;
181*9880d681SAndroid Build Coastguard Worker case RunLLI:
182*9880d681SAndroid Build Coastguard Worker Interpreter = AbstractInterpreter::createLLI(getToolName(), Message,
183*9880d681SAndroid Build Coastguard Worker &ToolArgv);
184*9880d681SAndroid Build Coastguard Worker break;
185*9880d681SAndroid Build Coastguard Worker case RunLLC:
186*9880d681SAndroid Build Coastguard Worker case RunLLCIA:
187*9880d681SAndroid Build Coastguard Worker case LLC_Safe:
188*9880d681SAndroid Build Coastguard Worker Interpreter = AbstractInterpreter::createLLC(getToolName(), Message,
189*9880d681SAndroid Build Coastguard Worker CCBinary, &ToolArgv,
190*9880d681SAndroid Build Coastguard Worker &CCToolArgv,
191*9880d681SAndroid Build Coastguard Worker InterpreterSel == RunLLCIA);
192*9880d681SAndroid Build Coastguard Worker break;
193*9880d681SAndroid Build Coastguard Worker case RunJIT:
194*9880d681SAndroid Build Coastguard Worker Interpreter = AbstractInterpreter::createJIT(getToolName(), Message,
195*9880d681SAndroid Build Coastguard Worker &ToolArgv);
196*9880d681SAndroid Build Coastguard Worker break;
197*9880d681SAndroid Build Coastguard Worker case CompileCustom:
198*9880d681SAndroid Build Coastguard Worker Interpreter =
199*9880d681SAndroid Build Coastguard Worker AbstractInterpreter::createCustomCompiler(Message, CustomCompileCommand);
200*9880d681SAndroid Build Coastguard Worker break;
201*9880d681SAndroid Build Coastguard Worker case Custom:
202*9880d681SAndroid Build Coastguard Worker Interpreter =
203*9880d681SAndroid Build Coastguard Worker AbstractInterpreter::createCustomExecutor(Message, CustomExecCommand);
204*9880d681SAndroid Build Coastguard Worker break;
205*9880d681SAndroid Build Coastguard Worker }
206*9880d681SAndroid Build Coastguard Worker if (!Interpreter)
207*9880d681SAndroid Build Coastguard Worker errs() << Message;
208*9880d681SAndroid Build Coastguard Worker else // Display informational messages on stdout instead of stderr
209*9880d681SAndroid Build Coastguard Worker outs() << Message;
210*9880d681SAndroid Build Coastguard Worker
211*9880d681SAndroid Build Coastguard Worker std::string Path = SafeInterpreterPath;
212*9880d681SAndroid Build Coastguard Worker if (Path.empty())
213*9880d681SAndroid Build Coastguard Worker Path = getToolName();
214*9880d681SAndroid Build Coastguard Worker std::vector<std::string> SafeToolArgs = SafeToolArgv;
215*9880d681SAndroid Build Coastguard Worker switch (SafeInterpreterSel) {
216*9880d681SAndroid Build Coastguard Worker case AutoPick:
217*9880d681SAndroid Build Coastguard Worker // In "llc-safe" mode, default to using LLC as the "safe" backend.
218*9880d681SAndroid Build Coastguard Worker if (!SafeInterpreter &&
219*9880d681SAndroid Build Coastguard Worker InterpreterSel == LLC_Safe) {
220*9880d681SAndroid Build Coastguard Worker SafeInterpreterSel = RunLLC;
221*9880d681SAndroid Build Coastguard Worker SafeToolArgs.push_back("--relocation-model=pic");
222*9880d681SAndroid Build Coastguard Worker SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message,
223*9880d681SAndroid Build Coastguard Worker CCBinary,
224*9880d681SAndroid Build Coastguard Worker &SafeToolArgs,
225*9880d681SAndroid Build Coastguard Worker &CCToolArgv);
226*9880d681SAndroid Build Coastguard Worker }
227*9880d681SAndroid Build Coastguard Worker
228*9880d681SAndroid Build Coastguard Worker if (!SafeInterpreter &&
229*9880d681SAndroid Build Coastguard Worker InterpreterSel != RunLLC &&
230*9880d681SAndroid Build Coastguard Worker InterpreterSel != RunJIT) {
231*9880d681SAndroid Build Coastguard Worker SafeInterpreterSel = RunLLC;
232*9880d681SAndroid Build Coastguard Worker SafeToolArgs.push_back("--relocation-model=pic");
233*9880d681SAndroid Build Coastguard Worker SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message,
234*9880d681SAndroid Build Coastguard Worker CCBinary,
235*9880d681SAndroid Build Coastguard Worker &SafeToolArgs,
236*9880d681SAndroid Build Coastguard Worker &CCToolArgv);
237*9880d681SAndroid Build Coastguard Worker }
238*9880d681SAndroid Build Coastguard Worker if (!SafeInterpreter) {
239*9880d681SAndroid Build Coastguard Worker SafeInterpreterSel = AutoPick;
240*9880d681SAndroid Build Coastguard Worker Message = "Sorry, I can't automatically select a safe interpreter!\n";
241*9880d681SAndroid Build Coastguard Worker }
242*9880d681SAndroid Build Coastguard Worker break;
243*9880d681SAndroid Build Coastguard Worker case RunLLC:
244*9880d681SAndroid Build Coastguard Worker case RunLLCIA:
245*9880d681SAndroid Build Coastguard Worker SafeToolArgs.push_back("--relocation-model=pic");
246*9880d681SAndroid Build Coastguard Worker SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message,
247*9880d681SAndroid Build Coastguard Worker CCBinary, &SafeToolArgs,
248*9880d681SAndroid Build Coastguard Worker &CCToolArgv,
249*9880d681SAndroid Build Coastguard Worker SafeInterpreterSel == RunLLCIA);
250*9880d681SAndroid Build Coastguard Worker break;
251*9880d681SAndroid Build Coastguard Worker case Custom:
252*9880d681SAndroid Build Coastguard Worker SafeInterpreter =
253*9880d681SAndroid Build Coastguard Worker AbstractInterpreter::createCustomExecutor(Message, CustomExecCommand);
254*9880d681SAndroid Build Coastguard Worker break;
255*9880d681SAndroid Build Coastguard Worker default:
256*9880d681SAndroid Build Coastguard Worker Message = "Sorry, this back-end is not supported by bugpoint as the "
257*9880d681SAndroid Build Coastguard Worker "\"safe\" backend right now!\n";
258*9880d681SAndroid Build Coastguard Worker break;
259*9880d681SAndroid Build Coastguard Worker }
260*9880d681SAndroid Build Coastguard Worker if (!SafeInterpreter) { outs() << Message << "\nExiting.\n"; exit(1); }
261*9880d681SAndroid Build Coastguard Worker
262*9880d681SAndroid Build Coastguard Worker cc = CC::create(Message, CCBinary, &CCToolArgv);
263*9880d681SAndroid Build Coastguard Worker if (!cc) { outs() << Message << "\nExiting.\n"; exit(1); }
264*9880d681SAndroid Build Coastguard Worker
265*9880d681SAndroid Build Coastguard Worker // If there was an error creating the selected interpreter, quit with error.
266*9880d681SAndroid Build Coastguard Worker return Interpreter == nullptr;
267*9880d681SAndroid Build Coastguard Worker }
268*9880d681SAndroid Build Coastguard Worker
269*9880d681SAndroid Build Coastguard Worker /// compileProgram - Try to compile the specified module, returning false and
270*9880d681SAndroid Build Coastguard Worker /// setting Error if an error occurs. This is used for code generation
271*9880d681SAndroid Build Coastguard Worker /// crash testing.
272*9880d681SAndroid Build Coastguard Worker ///
compileProgram(Module * M,std::string * Error) const273*9880d681SAndroid Build Coastguard Worker void BugDriver::compileProgram(Module *M, std::string *Error) const {
274*9880d681SAndroid Build Coastguard Worker // Emit the program to a bitcode file...
275*9880d681SAndroid Build Coastguard Worker SmallString<128> BitcodeFile;
276*9880d681SAndroid Build Coastguard Worker int BitcodeFD;
277*9880d681SAndroid Build Coastguard Worker std::error_code EC = sys::fs::createUniqueFile(
278*9880d681SAndroid Build Coastguard Worker OutputPrefix + "-test-program-%%%%%%%.bc", BitcodeFD, BitcodeFile);
279*9880d681SAndroid Build Coastguard Worker if (EC) {
280*9880d681SAndroid Build Coastguard Worker errs() << ToolName << ": Error making unique filename: " << EC.message()
281*9880d681SAndroid Build Coastguard Worker << "\n";
282*9880d681SAndroid Build Coastguard Worker exit(1);
283*9880d681SAndroid Build Coastguard Worker }
284*9880d681SAndroid Build Coastguard Worker if (writeProgramToFile(BitcodeFile.str(), BitcodeFD, M)) {
285*9880d681SAndroid Build Coastguard Worker errs() << ToolName << ": Error emitting bitcode to file '" << BitcodeFile
286*9880d681SAndroid Build Coastguard Worker << "'!\n";
287*9880d681SAndroid Build Coastguard Worker exit(1);
288*9880d681SAndroid Build Coastguard Worker }
289*9880d681SAndroid Build Coastguard Worker
290*9880d681SAndroid Build Coastguard Worker // Remove the temporary bitcode file when we are done.
291*9880d681SAndroid Build Coastguard Worker FileRemover BitcodeFileRemover(BitcodeFile.str(), !SaveTemps);
292*9880d681SAndroid Build Coastguard Worker
293*9880d681SAndroid Build Coastguard Worker // Actually compile the program!
294*9880d681SAndroid Build Coastguard Worker Interpreter->compileProgram(BitcodeFile.str(), Error, Timeout, MemoryLimit);
295*9880d681SAndroid Build Coastguard Worker }
296*9880d681SAndroid Build Coastguard Worker
297*9880d681SAndroid Build Coastguard Worker
298*9880d681SAndroid Build Coastguard Worker /// executeProgram - This method runs "Program", capturing the output of the
299*9880d681SAndroid Build Coastguard Worker /// program to a file, returning the filename of the file. A recommended
300*9880d681SAndroid Build Coastguard Worker /// filename may be optionally specified.
301*9880d681SAndroid Build Coastguard Worker ///
executeProgram(const Module * Program,std::string OutputFile,std::string BitcodeFile,const std::string & SharedObj,AbstractInterpreter * AI,std::string * Error) const302*9880d681SAndroid Build Coastguard Worker std::string BugDriver::executeProgram(const Module *Program,
303*9880d681SAndroid Build Coastguard Worker std::string OutputFile,
304*9880d681SAndroid Build Coastguard Worker std::string BitcodeFile,
305*9880d681SAndroid Build Coastguard Worker const std::string &SharedObj,
306*9880d681SAndroid Build Coastguard Worker AbstractInterpreter *AI,
307*9880d681SAndroid Build Coastguard Worker std::string *Error) const {
308*9880d681SAndroid Build Coastguard Worker if (!AI) AI = Interpreter;
309*9880d681SAndroid Build Coastguard Worker assert(AI && "Interpreter should have been created already!");
310*9880d681SAndroid Build Coastguard Worker bool CreatedBitcode = false;
311*9880d681SAndroid Build Coastguard Worker if (BitcodeFile.empty()) {
312*9880d681SAndroid Build Coastguard Worker // Emit the program to a bitcode file...
313*9880d681SAndroid Build Coastguard Worker SmallString<128> UniqueFilename;
314*9880d681SAndroid Build Coastguard Worker int UniqueFD;
315*9880d681SAndroid Build Coastguard Worker std::error_code EC = sys::fs::createUniqueFile(
316*9880d681SAndroid Build Coastguard Worker OutputPrefix + "-test-program-%%%%%%%.bc", UniqueFD, UniqueFilename);
317*9880d681SAndroid Build Coastguard Worker if (EC) {
318*9880d681SAndroid Build Coastguard Worker errs() << ToolName << ": Error making unique filename: "
319*9880d681SAndroid Build Coastguard Worker << EC.message() << "!\n";
320*9880d681SAndroid Build Coastguard Worker exit(1);
321*9880d681SAndroid Build Coastguard Worker }
322*9880d681SAndroid Build Coastguard Worker BitcodeFile = UniqueFilename.str();
323*9880d681SAndroid Build Coastguard Worker
324*9880d681SAndroid Build Coastguard Worker if (writeProgramToFile(BitcodeFile, UniqueFD, Program)) {
325*9880d681SAndroid Build Coastguard Worker errs() << ToolName << ": Error emitting bitcode to file '"
326*9880d681SAndroid Build Coastguard Worker << BitcodeFile << "'!\n";
327*9880d681SAndroid Build Coastguard Worker exit(1);
328*9880d681SAndroid Build Coastguard Worker }
329*9880d681SAndroid Build Coastguard Worker CreatedBitcode = true;
330*9880d681SAndroid Build Coastguard Worker }
331*9880d681SAndroid Build Coastguard Worker
332*9880d681SAndroid Build Coastguard Worker // Remove the temporary bitcode file when we are done.
333*9880d681SAndroid Build Coastguard Worker std::string BitcodePath(BitcodeFile);
334*9880d681SAndroid Build Coastguard Worker FileRemover BitcodeFileRemover(BitcodePath,
335*9880d681SAndroid Build Coastguard Worker CreatedBitcode && !SaveTemps);
336*9880d681SAndroid Build Coastguard Worker
337*9880d681SAndroid Build Coastguard Worker if (OutputFile.empty()) OutputFile = OutputPrefix + "-execution-output-%%%%%%%";
338*9880d681SAndroid Build Coastguard Worker
339*9880d681SAndroid Build Coastguard Worker // Check to see if this is a valid output filename...
340*9880d681SAndroid Build Coastguard Worker SmallString<128> UniqueFile;
341*9880d681SAndroid Build Coastguard Worker std::error_code EC = sys::fs::createUniqueFile(OutputFile, UniqueFile);
342*9880d681SAndroid Build Coastguard Worker if (EC) {
343*9880d681SAndroid Build Coastguard Worker errs() << ToolName << ": Error making unique filename: "
344*9880d681SAndroid Build Coastguard Worker << EC.message() << "\n";
345*9880d681SAndroid Build Coastguard Worker exit(1);
346*9880d681SAndroid Build Coastguard Worker }
347*9880d681SAndroid Build Coastguard Worker OutputFile = UniqueFile.str();
348*9880d681SAndroid Build Coastguard Worker
349*9880d681SAndroid Build Coastguard Worker // Figure out which shared objects to run, if any.
350*9880d681SAndroid Build Coastguard Worker std::vector<std::string> SharedObjs(AdditionalSOs);
351*9880d681SAndroid Build Coastguard Worker if (!SharedObj.empty())
352*9880d681SAndroid Build Coastguard Worker SharedObjs.push_back(SharedObj);
353*9880d681SAndroid Build Coastguard Worker
354*9880d681SAndroid Build Coastguard Worker int RetVal = AI->ExecuteProgram(BitcodeFile, InputArgv, InputFile, OutputFile,
355*9880d681SAndroid Build Coastguard Worker Error, AdditionalLinkerArgs, SharedObjs,
356*9880d681SAndroid Build Coastguard Worker Timeout, MemoryLimit);
357*9880d681SAndroid Build Coastguard Worker if (!Error->empty())
358*9880d681SAndroid Build Coastguard Worker return OutputFile;
359*9880d681SAndroid Build Coastguard Worker
360*9880d681SAndroid Build Coastguard Worker if (RetVal == -1) {
361*9880d681SAndroid Build Coastguard Worker errs() << "<timeout>";
362*9880d681SAndroid Build Coastguard Worker static bool FirstTimeout = true;
363*9880d681SAndroid Build Coastguard Worker if (FirstTimeout) {
364*9880d681SAndroid Build Coastguard Worker outs() << "\n"
365*9880d681SAndroid Build Coastguard Worker "*** Program execution timed out! This mechanism is designed to handle\n"
366*9880d681SAndroid Build Coastguard Worker " programs stuck in infinite loops gracefully. The -timeout option\n"
367*9880d681SAndroid Build Coastguard Worker " can be used to change the timeout threshold or disable it completely\n"
368*9880d681SAndroid Build Coastguard Worker " (with -timeout=0). This message is only displayed once.\n";
369*9880d681SAndroid Build Coastguard Worker FirstTimeout = false;
370*9880d681SAndroid Build Coastguard Worker }
371*9880d681SAndroid Build Coastguard Worker }
372*9880d681SAndroid Build Coastguard Worker
373*9880d681SAndroid Build Coastguard Worker if (AppendProgramExitCode) {
374*9880d681SAndroid Build Coastguard Worker std::ofstream outFile(OutputFile.c_str(), std::ios_base::app);
375*9880d681SAndroid Build Coastguard Worker outFile << "exit " << RetVal << '\n';
376*9880d681SAndroid Build Coastguard Worker outFile.close();
377*9880d681SAndroid Build Coastguard Worker }
378*9880d681SAndroid Build Coastguard Worker
379*9880d681SAndroid Build Coastguard Worker // Return the filename we captured the output to.
380*9880d681SAndroid Build Coastguard Worker return OutputFile;
381*9880d681SAndroid Build Coastguard Worker }
382*9880d681SAndroid Build Coastguard Worker
383*9880d681SAndroid Build Coastguard Worker /// executeProgramSafely - Used to create reference output with the "safe"
384*9880d681SAndroid Build Coastguard Worker /// backend, if reference output is not provided.
385*9880d681SAndroid Build Coastguard Worker ///
executeProgramSafely(const Module * Program,const std::string & OutputFile,std::string * Error) const386*9880d681SAndroid Build Coastguard Worker std::string BugDriver::executeProgramSafely(const Module *Program,
387*9880d681SAndroid Build Coastguard Worker const std::string &OutputFile,
388*9880d681SAndroid Build Coastguard Worker std::string *Error) const {
389*9880d681SAndroid Build Coastguard Worker return executeProgram(Program, OutputFile, "", "", SafeInterpreter, Error);
390*9880d681SAndroid Build Coastguard Worker }
391*9880d681SAndroid Build Coastguard Worker
compileSharedObject(const std::string & BitcodeFile,std::string & Error)392*9880d681SAndroid Build Coastguard Worker std::string BugDriver::compileSharedObject(const std::string &BitcodeFile,
393*9880d681SAndroid Build Coastguard Worker std::string &Error) {
394*9880d681SAndroid Build Coastguard Worker assert(Interpreter && "Interpreter should have been created already!");
395*9880d681SAndroid Build Coastguard Worker std::string OutputFile;
396*9880d681SAndroid Build Coastguard Worker
397*9880d681SAndroid Build Coastguard Worker // Using the known-good backend.
398*9880d681SAndroid Build Coastguard Worker CC::FileType FT = SafeInterpreter->OutputCode(BitcodeFile, OutputFile,
399*9880d681SAndroid Build Coastguard Worker Error);
400*9880d681SAndroid Build Coastguard Worker if (!Error.empty())
401*9880d681SAndroid Build Coastguard Worker return "";
402*9880d681SAndroid Build Coastguard Worker
403*9880d681SAndroid Build Coastguard Worker std::string SharedObjectFile;
404*9880d681SAndroid Build Coastguard Worker bool Failure = cc->MakeSharedObject(OutputFile, FT, SharedObjectFile,
405*9880d681SAndroid Build Coastguard Worker AdditionalLinkerArgs, Error);
406*9880d681SAndroid Build Coastguard Worker if (!Error.empty())
407*9880d681SAndroid Build Coastguard Worker return "";
408*9880d681SAndroid Build Coastguard Worker if (Failure)
409*9880d681SAndroid Build Coastguard Worker exit(1);
410*9880d681SAndroid Build Coastguard Worker
411*9880d681SAndroid Build Coastguard Worker // Remove the intermediate C file
412*9880d681SAndroid Build Coastguard Worker sys::fs::remove(OutputFile);
413*9880d681SAndroid Build Coastguard Worker
414*9880d681SAndroid Build Coastguard Worker return SharedObjectFile;
415*9880d681SAndroid Build Coastguard Worker }
416*9880d681SAndroid Build Coastguard Worker
417*9880d681SAndroid Build Coastguard Worker /// createReferenceFile - calls compileProgram and then records the output
418*9880d681SAndroid Build Coastguard Worker /// into ReferenceOutputFile. Returns true if reference file created, false
419*9880d681SAndroid Build Coastguard Worker /// otherwise. Note: initializeExecutionEnvironment should be called BEFORE
420*9880d681SAndroid Build Coastguard Worker /// this function.
421*9880d681SAndroid Build Coastguard Worker ///
createReferenceFile(Module * M,const std::string & Filename)422*9880d681SAndroid Build Coastguard Worker bool BugDriver::createReferenceFile(Module *M, const std::string &Filename) {
423*9880d681SAndroid Build Coastguard Worker std::string Error;
424*9880d681SAndroid Build Coastguard Worker compileProgram(Program, &Error);
425*9880d681SAndroid Build Coastguard Worker if (!Error.empty())
426*9880d681SAndroid Build Coastguard Worker return false;
427*9880d681SAndroid Build Coastguard Worker
428*9880d681SAndroid Build Coastguard Worker ReferenceOutputFile = executeProgramSafely(Program, Filename, &Error);
429*9880d681SAndroid Build Coastguard Worker if (!Error.empty()) {
430*9880d681SAndroid Build Coastguard Worker errs() << Error;
431*9880d681SAndroid Build Coastguard Worker if (Interpreter != SafeInterpreter) {
432*9880d681SAndroid Build Coastguard Worker errs() << "*** There is a bug running the \"safe\" backend. Either"
433*9880d681SAndroid Build Coastguard Worker << " debug it (for example with the -run-jit bugpoint option,"
434*9880d681SAndroid Build Coastguard Worker << " if JIT is being used as the \"safe\" backend), or fix the"
435*9880d681SAndroid Build Coastguard Worker << " error some other way.\n";
436*9880d681SAndroid Build Coastguard Worker }
437*9880d681SAndroid Build Coastguard Worker return false;
438*9880d681SAndroid Build Coastguard Worker }
439*9880d681SAndroid Build Coastguard Worker outs() << "\nReference output is: " << ReferenceOutputFile << "\n\n";
440*9880d681SAndroid Build Coastguard Worker return true;
441*9880d681SAndroid Build Coastguard Worker }
442*9880d681SAndroid Build Coastguard Worker
443*9880d681SAndroid Build Coastguard Worker /// diffProgram - This method executes the specified module and diffs the
444*9880d681SAndroid Build Coastguard Worker /// output against the file specified by ReferenceOutputFile. If the output
445*9880d681SAndroid Build Coastguard Worker /// is different, 1 is returned. If there is a problem with the code
446*9880d681SAndroid Build Coastguard Worker /// generator (e.g., llc crashes), this will set ErrMsg.
447*9880d681SAndroid Build Coastguard Worker ///
diffProgram(const Module * Program,const std::string & BitcodeFile,const std::string & SharedObject,bool RemoveBitcode,std::string * ErrMsg) const448*9880d681SAndroid Build Coastguard Worker bool BugDriver::diffProgram(const Module *Program,
449*9880d681SAndroid Build Coastguard Worker const std::string &BitcodeFile,
450*9880d681SAndroid Build Coastguard Worker const std::string &SharedObject,
451*9880d681SAndroid Build Coastguard Worker bool RemoveBitcode,
452*9880d681SAndroid Build Coastguard Worker std::string *ErrMsg) const {
453*9880d681SAndroid Build Coastguard Worker // Execute the program, generating an output file...
454*9880d681SAndroid Build Coastguard Worker std::string Output(
455*9880d681SAndroid Build Coastguard Worker executeProgram(Program, "", BitcodeFile, SharedObject, nullptr, ErrMsg));
456*9880d681SAndroid Build Coastguard Worker if (!ErrMsg->empty())
457*9880d681SAndroid Build Coastguard Worker return false;
458*9880d681SAndroid Build Coastguard Worker
459*9880d681SAndroid Build Coastguard Worker std::string Error;
460*9880d681SAndroid Build Coastguard Worker bool FilesDifferent = false;
461*9880d681SAndroid Build Coastguard Worker if (int Diff = DiffFilesWithTolerance(ReferenceOutputFile,
462*9880d681SAndroid Build Coastguard Worker Output,
463*9880d681SAndroid Build Coastguard Worker AbsTolerance, RelTolerance, &Error)) {
464*9880d681SAndroid Build Coastguard Worker if (Diff == 2) {
465*9880d681SAndroid Build Coastguard Worker errs() << "While diffing output: " << Error << '\n';
466*9880d681SAndroid Build Coastguard Worker exit(1);
467*9880d681SAndroid Build Coastguard Worker }
468*9880d681SAndroid Build Coastguard Worker FilesDifferent = true;
469*9880d681SAndroid Build Coastguard Worker }
470*9880d681SAndroid Build Coastguard Worker else {
471*9880d681SAndroid Build Coastguard Worker // Remove the generated output if there are no differences.
472*9880d681SAndroid Build Coastguard Worker sys::fs::remove(Output);
473*9880d681SAndroid Build Coastguard Worker }
474*9880d681SAndroid Build Coastguard Worker
475*9880d681SAndroid Build Coastguard Worker // Remove the bitcode file if we are supposed to.
476*9880d681SAndroid Build Coastguard Worker if (RemoveBitcode)
477*9880d681SAndroid Build Coastguard Worker sys::fs::remove(BitcodeFile);
478*9880d681SAndroid Build Coastguard Worker return FilesDifferent;
479*9880d681SAndroid Build Coastguard Worker }
480*9880d681SAndroid Build Coastguard Worker
isExecutingJIT()481*9880d681SAndroid Build Coastguard Worker bool BugDriver::isExecutingJIT() {
482*9880d681SAndroid Build Coastguard Worker return InterpreterSel == RunJIT;
483*9880d681SAndroid Build Coastguard Worker }
484*9880d681SAndroid Build Coastguard Worker
485