1bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber//===- ExecutionDriver.cpp - Allow execution of LLVM program --------------===//
2bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber//
389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//                     The LLVM Compiler Infrastructure
489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//
589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// This file is distributed under the University of Illinois Open Source
689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// License. See LICENSE.TXT for details.
789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//
889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//===----------------------------------------------------------------------===//
989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//
1089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// This file contains code used to execute the program utilizing one of the
1189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// various ways of running LLVM bitcode.
1289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//
1389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//===----------------------------------------------------------------------===//
1489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
1589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "BugDriver.h"
1689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "ToolRunner.h"
1720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include "llvm/Support/CommandLine.h"
18bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include "llvm/Support/Debug.h"
19bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include "llvm/Support/FileUtilities.h"
20bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include "llvm/Support/SystemUtils.h"
21bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include "llvm/Support/raw_ostream.h"
22bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber#include <fstream>
23bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
24bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberusing namespace llvm;
25bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
26bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubernamespace {
27f933441648ef6a71dee783d733aac17b9508b452Andreas Huber  // OutputType - Allow the user to specify the way code should be run, to test
28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber  // for miscompilation.
29f933441648ef6a71dee783d733aac17b9508b452Andreas Huber  //
30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber  enum OutputType {
31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    AutoPick, RunLLI, RunJIT, RunLLC, RunLLCIA, RunCBE, CBE_bug, LLC_Safe,
32f933441648ef6a71dee783d733aac17b9508b452Andreas Huber    CompileCustom, Custom
33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber  };
34f933441648ef6a71dee783d733aac17b9508b452Andreas Huber
35f933441648ef6a71dee783d733aac17b9508b452Andreas Huber  cl::opt<double>
36f933441648ef6a71dee783d733aac17b9508b452Andreas Huber  AbsTolerance("abs-tolerance", cl::desc("Absolute error tolerated"),
37f933441648ef6a71dee783d733aac17b9508b452Andreas Huber               cl::init(0.0));
38f933441648ef6a71dee783d733aac17b9508b452Andreas Huber  cl::opt<double>
39bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  RelTolerance("rel-tolerance", cl::desc("Relative error tolerated"),
40e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber               cl::init(0.0));
41e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber
42e3ec3cec3a2e27033249ff82964d2cbd441d9873Andreas Huber  cl::opt<OutputType>
43bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  InterpreterSel(cl::desc("Specify the \"test\" i.e. suspect back-end:"),
44bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                 cl::values(clEnumValN(AutoPick, "auto", "Use best guess"),
45bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                            clEnumValN(RunLLI, "run-int",
464f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber                                       "Execute with the interpreter"),
474f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber                            clEnumValN(RunJIT, "run-jit", "Execute with JIT"),
484f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber                            clEnumValN(RunLLC, "run-llc", "Compile with LLC"),
49bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                            clEnumValN(RunLLCIA, "run-llc-ia",
50bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                                  "Compile with LLC with integrated assembler"),
51bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                            clEnumValN(RunCBE, "run-cbe", "Compile with CBE"),
52bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                            clEnumValN(CBE_bug,"cbe-bug", "Find CBE bugs"),
53bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                            clEnumValN(LLC_Safe, "llc-safe", "Use LLC for all"),
54bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                            clEnumValN(CompileCustom, "compile-custom",
55bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                            "Use -compile-command to define a command to "
56bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                            "compile the bitcode. Useful to avoid linking."),
57bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                            clEnumValN(Custom, "run-custom",
58bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                            "Use -exec-command to define a command to execute "
59bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                            "the bitcode. Useful for cross-compilation."),
60bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                            clEnumValEnd),
61bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                 cl::init(AutoPick));
62bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
63bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  cl::opt<OutputType>
64bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  SafeInterpreterSel(cl::desc("Specify \"safe\" i.e. known-good backend:"),
65bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber              cl::values(clEnumValN(AutoPick, "safe-auto", "Use best guess"),
66bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                         clEnumValN(RunLLC, "safe-run-llc", "Compile with LLC"),
67bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                         clEnumValN(RunCBE, "safe-run-cbe", "Compile with CBE"),
68bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                         clEnumValN(Custom, "safe-run-custom",
69bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                         "Use -exec-command to define a command to execute "
70bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                         "the bitcode. Useful for cross-compilation."),
71bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                         clEnumValEnd),
72bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                     cl::init(AutoPick));
73bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
74bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  cl::opt<std::string>
75bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  SafeInterpreterPath("safe-path",
76bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                   cl::desc("Specify the path to the \"safe\" backend program"),
77bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                   cl::init(""));
78bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
79bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  cl::opt<bool>
80bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  AppendProgramExitCode("append-exit-code",
81bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      cl::desc("Append the exit code to the output so it gets diff'd too"),
82bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      cl::init(false));
83bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
84bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  cl::opt<std::string>
85bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  InputFile("input", cl::init("/dev/null"),
86bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            cl::desc("Filename to pipe in as stdin (default: /dev/null)"));
87bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
88bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  cl::list<std::string>
89bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  AdditionalSOs("additional-so",
90bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                cl::desc("Additional shared objects to load "
91bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                         "into executing programs"));
92bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
93bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  cl::list<std::string>
94bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  AdditionalLinkerArgs("Xlinker",
95bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      cl::desc("Additional arguments to pass to the linker"));
96bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
97bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  cl::opt<std::string>
98bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  CustomCompileCommand("compile-command", cl::init("llc"),
99bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      cl::desc("Command to compile the bitcode (use with -compile-custom) "
100bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber               "(default: llc)"));
101bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
102bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  cl::opt<std::string>
103bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  CustomExecCommand("exec-command", cl::init("simulate"),
104bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      cl::desc("Command to execute the bitcode (use with -run-custom) "
105bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber               "(default: simulate)"));
106bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
107bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
108bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubernamespace llvm {
109bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  // Anything specified after the --args option are taken as arguments to the
110bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  // program being debugged.
111bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  cl::list<std::string>
112bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  InputArgv("args", cl::Positional, cl::desc("<program arguments>..."),
113bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            cl::ZeroOrMore, cl::PositionalEatsArgs);
114bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
115bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  cl::opt<std::string>
116bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  OutputPrefix("output-prefix", cl::init("bugpoint"),
117bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber            cl::desc("Prefix to use for outputs (default: 'bugpoint')"));
118bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
119bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
120bbba88cb1bdc34705d1477208990a06904c022e7Andreas Hubernamespace {
121bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  cl::list<std::string>
122bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  ToolArgv("tool-args", cl::Positional, cl::desc("<tool arguments>..."),
123bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber           cl::ZeroOrMore, cl::PositionalEatsArgs);
124bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
125bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  cl::list<std::string>
126bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  SafeToolArgv("safe-tool-args", cl::Positional,
127bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber               cl::desc("<safe-tool arguments>..."),
128bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber               cl::ZeroOrMore, cl::PositionalEatsArgs);
129bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
130bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  cl::opt<std::string>
131bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  GCCBinary("gcc", cl::init("gcc"),
132bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber              cl::desc("The gcc binary to use. (default 'gcc')"));
133bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
134bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  cl::list<std::string>
135bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  GCCToolArgv("gcc-tool-args", cl::Positional,
136bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber              cl::desc("<gcc-tool arguments>..."),
137bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber              cl::ZeroOrMore, cl::PositionalEatsArgs);
138bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
139bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
140bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber//===----------------------------------------------------------------------===//
141bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber// BugDriver method implementation
142bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber//
143bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
144bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber/// initializeExecutionEnvironment - This method is used to set up the
145bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber/// environment for executing LLVM programs.
1461e73885bceac69f2b08987e36aad651c824fbd65Ram Mohan///
1471e73885bceac69f2b08987e36aad651c824fbd65Ram Mohanbool BugDriver::initializeExecutionEnvironment() {
1481e73885bceac69f2b08987e36aad651c824fbd65Ram Mohan  outs() << "Initializing execution environment: ";
1491e73885bceac69f2b08987e36aad651c824fbd65Ram Mohan
1501e73885bceac69f2b08987e36aad651c824fbd65Ram Mohan  // Create an instance of the AbstractInterpreter interface as specified on
1511e73885bceac69f2b08987e36aad651c824fbd65Ram Mohan  // the command line
152f1a2668f4f09e38722424a6a74f0ea26f49e4110Marco Nelissen  SafeInterpreter = 0;
153f1a2668f4f09e38722424a6a74f0ea26f49e4110Marco Nelissen  std::string Message;
154f1a2668f4f09e38722424a6a74f0ea26f49e4110Marco Nelissen
1551e73885bceac69f2b08987e36aad651c824fbd65Ram Mohan  switch (InterpreterSel) {
156bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  case AutoPick:
157bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    InterpreterSel = RunCBE;
158bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    Interpreter =
1591e73885bceac69f2b08987e36aad651c824fbd65Ram Mohan      AbstractInterpreter::createCBE(getToolName(), Message, GCCBinary,
1601e73885bceac69f2b08987e36aad651c824fbd65Ram Mohan                                     &ToolArgv, &GCCToolArgv);
1611e73885bceac69f2b08987e36aad651c824fbd65Ram Mohan    if (!Interpreter) {
1621e73885bceac69f2b08987e36aad651c824fbd65Ram Mohan      InterpreterSel = RunJIT;
1631e73885bceac69f2b08987e36aad651c824fbd65Ram Mohan      Interpreter = AbstractInterpreter::createJIT(getToolName(), Message,
1641e73885bceac69f2b08987e36aad651c824fbd65Ram Mohan                                                   &ToolArgv);
1651e73885bceac69f2b08987e36aad651c824fbd65Ram Mohan    }
1661e73885bceac69f2b08987e36aad651c824fbd65Ram Mohan    if (!Interpreter) {
1671e73885bceac69f2b08987e36aad651c824fbd65Ram Mohan      InterpreterSel = RunLLC;
1681e73885bceac69f2b08987e36aad651c824fbd65Ram Mohan      Interpreter = AbstractInterpreter::createLLC(getToolName(), Message,
1691e73885bceac69f2b08987e36aad651c824fbd65Ram Mohan                                                   GCCBinary, &ToolArgv,
170bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                                                   &GCCToolArgv);
171bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
172bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (!Interpreter) {
173bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      InterpreterSel = RunLLI;
174bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      Interpreter = AbstractInterpreter::createLLI(getToolName(), Message,
175f1a2668f4f09e38722424a6a74f0ea26f49e4110Marco Nelissen                                                   &ToolArgv);
176f1a2668f4f09e38722424a6a74f0ea26f49e4110Marco Nelissen    }
177f1a2668f4f09e38722424a6a74f0ea26f49e4110Marco Nelissen    if (!Interpreter) {
178f1a2668f4f09e38722424a6a74f0ea26f49e4110Marco Nelissen      InterpreterSel = AutoPick;
179bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      Message = "Sorry, I can't automatically select an interpreter!\n";
180bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
181bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    break;
182bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  case RunLLI:
183bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    Interpreter = AbstractInterpreter::createLLI(getToolName(), Message,
184bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                                                 &ToolArgv);
1858298cd4d7e99648f277215bf981fdef78bc19e45Martin Storsjo    break;
186bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  case RunLLC:
187bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  case RunLLCIA:
188bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  case LLC_Safe:
189bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    Interpreter = AbstractInterpreter::createLLC(getToolName(), Message,
190bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                                                 GCCBinary, &ToolArgv,
191bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                                                 &GCCToolArgv,
192bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                                                 InterpreterSel == RunLLCIA);
193bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    break;
194bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  case RunJIT:
195bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    Interpreter = AbstractInterpreter::createJIT(getToolName(), Message,
196bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                                                 &ToolArgv);
197bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    break;
198bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  case RunCBE:
199bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  case CBE_bug:
200bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    Interpreter = AbstractInterpreter::createCBE(getToolName(), Message,
201bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                                                 GCCBinary, &ToolArgv,
202bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                                                 &GCCToolArgv);
203bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    break;
204bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  case CompileCustom:
205f1a2668f4f09e38722424a6a74f0ea26f49e4110Marco Nelissen    Interpreter =
206f1a2668f4f09e38722424a6a74f0ea26f49e4110Marco Nelissen      AbstractInterpreter::createCustomCompiler(Message, CustomCompileCommand);
207f1a2668f4f09e38722424a6a74f0ea26f49e4110Marco Nelissen    break;
208f1a2668f4f09e38722424a6a74f0ea26f49e4110Marco Nelissen  case Custom:
209bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    Interpreter =
210bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      AbstractInterpreter::createCustomExecutor(Message, CustomExecCommand);
211bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    break;
212bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  default:
213bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    Message = "Sorry, this back-end is not supported by bugpoint right now!\n";
214bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    break;
215bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  }
216bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  if (!Interpreter)
217bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    errs() << Message;
218bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  else // Display informational messages on stdout instead of stderr
219bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    outs() << Message;
220bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
221bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  std::string Path = SafeInterpreterPath;
222bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  if (Path.empty())
223bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    Path = getToolName();
224bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  std::vector<std::string> SafeToolArgs = SafeToolArgv;
225bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  switch (SafeInterpreterSel) {
226bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  case AutoPick:
227bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    // In "cbe-bug" mode, default to using LLC as the "safe" backend.
228bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (!SafeInterpreter &&
229bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        InterpreterSel == CBE_bug) {
230bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      SafeInterpreterSel = RunLLC;
231bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      SafeToolArgs.push_back("--relocation-model=pic");
232bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message,
233bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                                                       GCCBinary,
234bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                                                       &SafeToolArgs,
235bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                                                       &GCCToolArgv);
236bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
237bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
238bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    // In "llc-safe" mode, default to using LLC as the "safe" backend.
239bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (!SafeInterpreter &&
240bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        InterpreterSel == LLC_Safe) {
241bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      SafeInterpreterSel = RunLLC;
242f1a2668f4f09e38722424a6a74f0ea26f49e4110Marco Nelissen      SafeToolArgs.push_back("--relocation-model=pic");
243f1a2668f4f09e38722424a6a74f0ea26f49e4110Marco Nelissen      SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message,
244f1a2668f4f09e38722424a6a74f0ea26f49e4110Marco Nelissen                                                       GCCBinary,
245f1a2668f4f09e38722424a6a74f0ea26f49e4110Marco Nelissen                                                       &SafeToolArgs,
246bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                                                       &GCCToolArgv);
247bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
248bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
249bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    // Pick a backend that's different from the test backend. The JIT and
250bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    // LLC backends share a lot of code, so prefer to use the CBE as the
251bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    // safe back-end when testing them.
252bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (!SafeInterpreter &&
253bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        InterpreterSel != RunCBE) {
254bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      SafeInterpreterSel = RunCBE;
255bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      SafeInterpreter = AbstractInterpreter::createCBE(Path.c_str(), Message,
256bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                                                       GCCBinary,
257bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                                                       &SafeToolArgs,
258bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                                                       &GCCToolArgv);
259bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
260bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (!SafeInterpreter &&
261bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        InterpreterSel != RunLLC &&
262bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber        InterpreterSel != RunJIT) {
2631e73885bceac69f2b08987e36aad651c824fbd65Ram Mohan      SafeInterpreterSel = RunLLC;
2641e73885bceac69f2b08987e36aad651c824fbd65Ram Mohan      SafeToolArgs.push_back("--relocation-model=pic");
2651e73885bceac69f2b08987e36aad651c824fbd65Ram Mohan      SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message,
2661e73885bceac69f2b08987e36aad651c824fbd65Ram Mohan                                                       GCCBinary,
2671e73885bceac69f2b08987e36aad651c824fbd65Ram Mohan                                                       &SafeToolArgs,
2681e73885bceac69f2b08987e36aad651c824fbd65Ram Mohan                                                       &GCCToolArgv);
269f1a2668f4f09e38722424a6a74f0ea26f49e4110Marco Nelissen    }
270f1a2668f4f09e38722424a6a74f0ea26f49e4110Marco Nelissen    if (!SafeInterpreter) {
271f1a2668f4f09e38722424a6a74f0ea26f49e4110Marco Nelissen      SafeInterpreterSel = AutoPick;
2721e73885bceac69f2b08987e36aad651c824fbd65Ram Mohan      Message = "Sorry, I can't automatically select an interpreter!\n";
273bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
274bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    break;
275bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  case RunLLC:
2761e73885bceac69f2b08987e36aad651c824fbd65Ram Mohan  case RunLLCIA:
2771e73885bceac69f2b08987e36aad651c824fbd65Ram Mohan    SafeToolArgs.push_back("--relocation-model=pic");
2781e73885bceac69f2b08987e36aad651c824fbd65Ram Mohan    SafeInterpreter = AbstractInterpreter::createLLC(Path.c_str(), Message,
2791e73885bceac69f2b08987e36aad651c824fbd65Ram Mohan                                                     GCCBinary, &SafeToolArgs,
280bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                                                     &GCCToolArgv,
281bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                                                SafeInterpreterSel == RunLLCIA);
282bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    break;
2831e73885bceac69f2b08987e36aad651c824fbd65Ram Mohan  case RunCBE:
2841e73885bceac69f2b08987e36aad651c824fbd65Ram Mohan    SafeInterpreter = AbstractInterpreter::createCBE(Path.c_str(), Message,
2851e73885bceac69f2b08987e36aad651c824fbd65Ram Mohan                                                     GCCBinary, &SafeToolArgs,
286bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                                                     &GCCToolArgv);
287bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    break;
288bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  case Custom:
289bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    SafeInterpreter =
290bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      AbstractInterpreter::createCustomExecutor(Message, CustomExecCommand);
291f1a2668f4f09e38722424a6a74f0ea26f49e4110Marco Nelissen    break;
292f1a2668f4f09e38722424a6a74f0ea26f49e4110Marco Nelissen  default:
293f1a2668f4f09e38722424a6a74f0ea26f49e4110Marco Nelissen    Message = "Sorry, this back-end is not supported by bugpoint as the "
294f1a2668f4f09e38722424a6a74f0ea26f49e4110Marco Nelissen              "\"safe\" backend right now!\n";
295bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    break;
296bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  }
297bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  if (!SafeInterpreter) { outs() << Message << "\nExiting.\n"; exit(1); }
298bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
299bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  gcc = GCC::create(Message, GCCBinary, &GCCToolArgv);
300bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  if (!gcc) { outs() << Message << "\nExiting.\n"; exit(1); }
301bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
302c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber  // If there was an error creating the selected interpreter, quit with error.
303c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber  return Interpreter == 0;
304c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber}
305c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber
306c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber/// compileProgram - Try to compile the specified module, returning false and
307f1a2668f4f09e38722424a6a74f0ea26f49e4110Marco Nelissen/// setting Error if an error occurs.  This is used for code generation
308f1a2668f4f09e38722424a6a74f0ea26f49e4110Marco Nelissen/// crash testing.
309f1a2668f4f09e38722424a6a74f0ea26f49e4110Marco Nelissen///
310f1a2668f4f09e38722424a6a74f0ea26f49e4110Marco Nelissenvoid BugDriver::compileProgram(Module *M, std::string *Error) const {
311bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  // Emit the program to a bitcode file...
312bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  sys::Path BitcodeFile (OutputPrefix + "-test-program.bc");
313bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  std::string ErrMsg;
314bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  if (BitcodeFile.makeUnique(true, &ErrMsg)) {
315c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber    errs() << ToolName << ": Error making unique filename: " << ErrMsg
316c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber           << "\n";
317c5255ac5b1bd313dcb50159566163b24dce7483fAndreas Huber    exit(1);
318bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  }
319bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  if (writeProgramToFile(BitcodeFile.str(), M)) {
320bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    errs() << ToolName << ": Error emitting bitcode to file '"
321bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber           << BitcodeFile.str() << "'!\n";
322bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    exit(1);
323bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  }
324bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
325bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  // Remove the temporary bitcode file when we are done.
326bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  FileRemover BitcodeFileRemover(BitcodeFile.str(), !SaveTemps);
327bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
328a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber  // Actually compile the program!
329a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber  Interpreter->compileProgram(BitcodeFile.str(), Error, Timeout, MemoryLimit);
330bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
331bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
332a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber
333a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber/// executeProgram - This method runs "Program", capturing the output of the
334a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber/// program to a file, returning the filename of the file.  A recommended
335a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber/// filename may be optionally specified.
3364f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber///
3374f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huberstd::string BugDriver::executeProgram(const Module *Program,
3384f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber                                      std::string OutputFile,
3394f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber                                      std::string BitcodeFile,
3404f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber                                      const std::string &SharedObj,
3414f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber                                      AbstractInterpreter *AI,
3424f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber                                      std::string *Error) const {
3434f1efc098cb5791c3e9f483f2af84aef70d2d0a0Andreas Huber  if (AI == 0) AI = Interpreter;
34484333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber  assert(AI && "Interpreter should have been created already!");
345bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  bool CreatedBitcode = false;
346bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  std::string ErrMsg;
347bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  if (BitcodeFile.empty()) {
348bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    // Emit the program to a bitcode file...
349bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    sys::Path uniqueFilename(OutputPrefix + "-test-program.bc");
350bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (uniqueFilename.makeUnique(true, &ErrMsg)) {
351bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      errs() << ToolName << ": Error making unique filename: "
352bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber             << ErrMsg << "!\n";
353bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      exit(1);
354bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
355bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    BitcodeFile = uniqueFilename.str();
356bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
357bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (writeProgramToFile(BitcodeFile, Program)) {
358bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      errs() << ToolName << ": Error emitting bitcode to file '"
359199a6e3682c2804975ef8b56159bbc31426ef3d4Wei Jia             << BitcodeFile << "'!\n";
360bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      exit(1);
361bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
362bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    CreatedBitcode = true;
363bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  }
364bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
365bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  // Remove the temporary bitcode file when we are done.
366bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  sys::Path BitcodePath(BitcodeFile);
367bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  FileRemover BitcodeFileRemover(BitcodePath.str(),
368bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    CreatedBitcode && !SaveTemps);
369bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
370bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  if (OutputFile.empty()) OutputFile = OutputPrefix + "-execution-output";
371bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
372bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  // Check to see if this is a valid output filename...
373bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  sys::Path uniqueFile(OutputFile);
374bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  if (uniqueFile.makeUnique(true, &ErrMsg)) {
375bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    errs() << ToolName << ": Error making unique filename: "
37655e5218fd53f4da5c1fbad539ed960c04a883b0bWei Jia           << ErrMsg << "\n";
37755e5218fd53f4da5c1fbad539ed960c04a883b0bWei Jia    exit(1);
37855e5218fd53f4da5c1fbad539ed960c04a883b0bWei Jia  }
37955e5218fd53f4da5c1fbad539ed960c04a883b0bWei Jia  OutputFile = uniqueFile.str();
380bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
381bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  // Figure out which shared objects to run, if any.
382bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  std::vector<std::string> SharedObjs(AdditionalSOs);
383bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  if (!SharedObj.empty())
384bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    SharedObjs.push_back(SharedObj);
385bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
386bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  int RetVal = AI->ExecuteProgram(BitcodeFile, InputArgv, InputFile, OutputFile,
387bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                                  Error, AdditionalLinkerArgs, SharedObjs,
388bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                                  Timeout, MemoryLimit);
389a3536c61c6b6c77e199cc207cbf1e5c5b063cf91Wei Jia  if (!Error->empty())
390a3536c61c6b6c77e199cc207cbf1e5c5b063cf91Wei Jia    return OutputFile;
391a3536c61c6b6c77e199cc207cbf1e5c5b063cf91Wei Jia
392a3536c61c6b6c77e199cc207cbf1e5c5b063cf91Wei Jia  if (RetVal == -1) {
393a3536c61c6b6c77e199cc207cbf1e5c5b063cf91Wei Jia    errs() << "<timeout>";
394a3536c61c6b6c77e199cc207cbf1e5c5b063cf91Wei Jia    static bool FirstTimeout = true;
395a3536c61c6b6c77e199cc207cbf1e5c5b063cf91Wei Jia    if (FirstTimeout) {
396a3536c61c6b6c77e199cc207cbf1e5c5b063cf91Wei Jia      outs() << "\n"
397a3536c61c6b6c77e199cc207cbf1e5c5b063cf91Wei Jia "*** Program execution timed out!  This mechanism is designed to handle\n"
39855e5218fd53f4da5c1fbad539ed960c04a883b0bWei Jia "    programs stuck in infinite loops gracefully.  The -timeout option\n"
39955e5218fd53f4da5c1fbad539ed960c04a883b0bWei Jia "    can be used to change the timeout threshold or disable it completely\n"
40055e5218fd53f4da5c1fbad539ed960c04a883b0bWei Jia "    (with -timeout=0).  This message is only displayed once.\n";
40155e5218fd53f4da5c1fbad539ed960c04a883b0bWei Jia      FirstTimeout = false;
40255e5218fd53f4da5c1fbad539ed960c04a883b0bWei Jia    }
40355e5218fd53f4da5c1fbad539ed960c04a883b0bWei Jia  }
40455e5218fd53f4da5c1fbad539ed960c04a883b0bWei Jia
40555e5218fd53f4da5c1fbad539ed960c04a883b0bWei Jia  if (AppendProgramExitCode) {
40655e5218fd53f4da5c1fbad539ed960c04a883b0bWei Jia    std::ofstream outFile(OutputFile.c_str(), std::ios_base::app);
40755e5218fd53f4da5c1fbad539ed960c04a883b0bWei Jia    outFile << "exit " << RetVal << '\n';
40855e5218fd53f4da5c1fbad539ed960c04a883b0bWei Jia    outFile.close();
409bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  }
410bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
411bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  // Return the filename we captured the output to.
412bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  return OutputFile;
413bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
414bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
415bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber/// executeProgramSafely - Used to create reference output with the "safe"
416bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber/// backend, if reference output is not provided.
41729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block///
418bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberstd::string BugDriver::executeProgramSafely(const Module *Program,
419bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                                            std::string OutputFile,
420bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                                            std::string *Error) const {
421bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  return executeProgram(Program, OutputFile, "", "", SafeInterpreter, Error);
422bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
423bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
424bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberstd::string BugDriver::compileSharedObject(const std::string &BitcodeFile,
425bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                                           std::string &Error) {
426bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  assert(Interpreter && "Interpreter should have been created already!");
427bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  sys::Path OutputFile;
428bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
429bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  // Using the known-good backend.
430bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  GCC::FileType FT = SafeInterpreter->OutputCode(BitcodeFile, OutputFile,
431bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                                                 Error);
432bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  if (!Error.empty())
433bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    return "";
434bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
435bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  std::string SharedObjectFile;
436a3536c61c6b6c77e199cc207cbf1e5c5b063cf91Wei Jia  bool Failure = gcc->MakeSharedObject(OutputFile.str(), FT, SharedObjectFile,
437a3536c61c6b6c77e199cc207cbf1e5c5b063cf91Wei Jia                                       AdditionalLinkerArgs, Error);
438a3536c61c6b6c77e199cc207cbf1e5c5b063cf91Wei Jia  if (!Error.empty())
439a3536c61c6b6c77e199cc207cbf1e5c5b063cf91Wei Jia    return "";
440a3536c61c6b6c77e199cc207cbf1e5c5b063cf91Wei Jia  if (Failure)
441a3536c61c6b6c77e199cc207cbf1e5c5b063cf91Wei Jia    exit(1);
442a3536c61c6b6c77e199cc207cbf1e5c5b063cf91Wei Jia
443a3536c61c6b6c77e199cc207cbf1e5c5b063cf91Wei Jia  // Remove the intermediate C file
444a3536c61c6b6c77e199cc207cbf1e5c5b063cf91Wei Jia  OutputFile.eraseFromDisk();
445bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
446bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  return "./" + SharedObjectFile;
447a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber}
448a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber
449a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber/// createReferenceFile - calls compileProgram and then records the output
450bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber/// into ReferenceOutputFile. Returns true if reference file created, false
451a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber/// otherwise. Note: initializeExecutionEnvironment should be called BEFORE
452a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber/// this function.
453bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber///
454a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huberbool BugDriver::createReferenceFile(Module *M, const std::string &Filename) {
455a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber  std::string Error;
456bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  compileProgram(Program, &Error);
457a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber  if (!Error.empty())
45855e5218fd53f4da5c1fbad539ed960c04a883b0bWei Jia    return false;
45955e5218fd53f4da5c1fbad539ed960c04a883b0bWei Jia
46055e5218fd53f4da5c1fbad539ed960c04a883b0bWei Jia  ReferenceOutputFile = executeProgramSafely(Program, Filename, &Error);
46155e5218fd53f4da5c1fbad539ed960c04a883b0bWei Jia  if (!Error.empty()) {
46255e5218fd53f4da5c1fbad539ed960c04a883b0bWei Jia    errs() << Error;
46355e5218fd53f4da5c1fbad539ed960c04a883b0bWei Jia    if (Interpreter != SafeInterpreter) {
464bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      errs() << "*** There is a bug running the \"safe\" backend.  Either"
465a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber             << " debug it (for example with the -run-cbe bugpoint option,"
466a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber             << " if CBE is being used as the \"safe\" backend), or fix the"
467a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber             << " error some other way.\n";
468a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber    }
469a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber    return false;
470a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber  }
471a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber  outs() << "\nReference output is: " << ReferenceOutputFile << "\n\n";
472a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber  return true;
473a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber}
474a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber
475a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber/// diffProgram - This method executes the specified module and diffs the
476a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber/// output against the file specified by ReferenceOutputFile.  If the output
477a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber/// is different, 1 is returned.  If there is a problem with the code
478a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber/// generator (e.g., llc crashes), this will set ErrMsg.
479a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber///
480a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huberbool BugDriver::diffProgram(const Module *Program,
481a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber                            const std::string &BitcodeFile,
482a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber                            const std::string &SharedObject,
483a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber                            bool RemoveBitcode,
484a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber                            std::string *ErrMsg) const {
485a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber  // Execute the program, generating an output file...
486a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber  sys::Path Output(executeProgram(Program, "", BitcodeFile, SharedObject, 0,
487a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber                                  ErrMsg));
488a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber  if (!ErrMsg->empty())
489a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber    return false;
490a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber
491a9605efa3edfae96fa618a4b78f6c2276f941fabAndreas Huber  std::string Error;
492bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  bool FilesDifferent = false;
493bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  if (int Diff = DiffFilesWithTolerance(sys::Path(ReferenceOutputFile),
494bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                                        sys::Path(Output.str()),
495bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber                                        AbsTolerance, RelTolerance, &Error)) {
496bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    if (Diff == 2) {
497bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      errs() << "While diffing output: " << Error << '\n';
498bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber      exit(1);
499bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    }
500bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    FilesDifferent = true;
501bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  }
502bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  else {
503bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    // Remove the generated output if there are no differences.
504bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    Output.eraseFromDisk();
505bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  }
506bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
507bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  // Remove the bitcode file if we are supposed to.
508bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  if (RemoveBitcode)
509bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber    sys::Path(BitcodeFile).eraseFromDisk();
510bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  return FilesDifferent;
511bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
512bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
513bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huberbool BugDriver::isExecutingJIT() {
514bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber  return InterpreterSel == RunJIT;
515bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber}
516bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber
517bbba88cb1bdc34705d1477208990a06904c022e7Andreas Huber