xref: /aosp_15_r20/external/llvm/tools/bugpoint/ExecutionDriver.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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