Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/tools/bugpoint/BugDriver.h
35230 views
1
//===- BugDriver.h - Top-Level BugPoint class -------------------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This class contains all of the shared state and information that is used by
10
// the BugPoint tool to track down errors in optimizations. This class is the
11
// main driver class that invokes all sub-functionality.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#ifndef LLVM_TOOLS_BUGPOINT_BUGDRIVER_H
16
#define LLVM_TOOLS_BUGPOINT_BUGDRIVER_H
17
18
#include "llvm/IR/ValueMap.h"
19
#include "llvm/Support/Error.h"
20
#include "llvm/Support/FileSystem.h"
21
#include "llvm/Transforms/Utils/ValueMapper.h"
22
#include <memory>
23
#include <string>
24
#include <vector>
25
26
namespace llvm {
27
28
class Module;
29
class GlobalVariable;
30
class Function;
31
class BasicBlock;
32
class AbstractInterpreter;
33
class Instruction;
34
class LLVMContext;
35
36
class CC;
37
38
extern bool DisableSimplifyCFG;
39
40
/// BugpointIsInterrupted - Set to true when the user presses ctrl-c.
41
///
42
extern bool BugpointIsInterrupted;
43
44
class BugDriver {
45
LLVMContext &Context;
46
const char *ToolName; // argv[0] of bugpoint
47
std::string ReferenceOutputFile; // Name of `good' output file
48
std::unique_ptr<Module> Program; // The raw program, linked together
49
std::vector<std::string> PassesToRun;
50
AbstractInterpreter *Interpreter; // How to run the program
51
AbstractInterpreter *SafeInterpreter; // To generate reference output, etc.
52
CC *cc;
53
bool run_find_bugs;
54
unsigned Timeout;
55
unsigned MemoryLimit;
56
bool UseValgrind;
57
58
// FIXME: sort out public/private distinctions...
59
friend class ReducePassList;
60
friend class ReduceMisCodegenFunctions;
61
62
public:
63
BugDriver(const char *toolname, bool find_bugs, unsigned timeout,
64
unsigned memlimit, bool use_valgrind, LLVMContext &ctxt);
65
~BugDriver();
66
67
const char *getToolName() const { return ToolName; }
68
69
LLVMContext &getContext() const { return Context; }
70
71
// Set up methods... these methods are used to copy information about the
72
// command line arguments into instance variables of BugDriver.
73
//
74
bool addSources(const std::vector<std::string> &FileNames);
75
void addPass(std::string p) { PassesToRun.push_back(std::move(p)); }
76
void setPassesToRun(const std::vector<std::string> &PTR) {
77
PassesToRun = PTR;
78
}
79
const std::vector<std::string> &getPassesToRun() const { return PassesToRun; }
80
81
/// run - The top level method that is invoked after all of the instance
82
/// variables are set up from command line arguments. The \p as_child argument
83
/// indicates whether the driver is to run in parent mode or child mode.
84
///
85
Error run();
86
87
/// debugOptimizerCrash - This method is called when some optimizer pass
88
/// crashes on input. It attempts to prune down the testcase to something
89
/// reasonable, and figure out exactly which pass is crashing.
90
///
91
Error debugOptimizerCrash(const std::string &ID = "passes");
92
93
/// debugCodeGeneratorCrash - This method is called when the code generator
94
/// crashes on an input. It attempts to reduce the input as much as possible
95
/// while still causing the code generator to crash.
96
Error debugCodeGeneratorCrash();
97
98
/// debugMiscompilation - This method is used when the passes selected are not
99
/// crashing, but the generated output is semantically different from the
100
/// input.
101
Error debugMiscompilation();
102
103
/// compileSharedObject - This method creates a SharedObject from a given
104
/// BitcodeFile for debugging a code generator.
105
///
106
Expected<std::string> compileSharedObject(const std::string &BitcodeFile);
107
108
/// debugCodeGenerator - This method narrows down a module to a function or
109
/// set of functions, using the CBE as a ``safe'' code generator for other
110
/// functions that are not under consideration.
111
Error debugCodeGenerator();
112
113
/// isExecutingJIT - Returns true if bugpoint is currently testing the JIT
114
///
115
bool isExecutingJIT();
116
117
Module &getProgram() const { return *Program; }
118
119
/// Set the current module to the specified module, returning the old one.
120
std::unique_ptr<Module> swapProgramIn(std::unique_ptr<Module> M);
121
122
AbstractInterpreter *switchToSafeInterpreter() {
123
AbstractInterpreter *Old = Interpreter;
124
Interpreter = (AbstractInterpreter *)SafeInterpreter;
125
return Old;
126
}
127
128
void switchToInterpreter(AbstractInterpreter *AI) { Interpreter = AI; }
129
130
/// If we reduce or update the program somehow, call this method to update
131
/// bugdriver with it. This deletes the old module and sets the specified one
132
/// as the current program.
133
void setNewProgram(std::unique_ptr<Module> M);
134
135
/// Try to compile the specified module. This is used for code generation
136
/// crash testing.
137
Error compileProgram(Module &M) const;
138
139
/// This method runs "Program", capturing the output of the program to a file.
140
/// A recommended filename may be optionally specified.
141
Expected<std::string> executeProgram(const Module &Program,
142
std::string OutputFilename,
143
std::string Bitcode,
144
const std::string &SharedObjects,
145
AbstractInterpreter *AI) const;
146
147
/// Used to create reference output with the "safe" backend, if reference
148
/// output is not provided. If there is a problem with the code generator
149
/// (e.g., llc crashes), this will return false and set Error.
150
Expected<std::string>
151
executeProgramSafely(const Module &Program,
152
const std::string &OutputFile) const;
153
154
/// Calls compileProgram and then records the output into ReferenceOutputFile.
155
/// Returns true if reference file created, false otherwise. Note:
156
/// initializeExecutionEnvironment should be called BEFORE this function.
157
Error createReferenceFile(Module &M, const std::string &Filename =
158
"bugpoint.reference.out-%%%%%%%");
159
160
/// This method executes the specified module and diffs the output against the
161
/// file specified by ReferenceOutputFile. If the output is different, 1 is
162
/// returned. If there is a problem with the code generator (e.g., llc
163
/// crashes), this will return -1 and set Error.
164
Expected<bool> diffProgram(const Module &Program,
165
const std::string &BitcodeFile = "",
166
const std::string &SharedObj = "",
167
bool RemoveBitcode = false) const;
168
169
/// This function is used to output M to a file named "bugpoint-ID.bc".
170
void EmitProgressBitcode(const Module &M, const std::string &ID,
171
bool NoFlyer = false) const;
172
173
/// This method clones the current Program and deletes the specified
174
/// instruction from the cloned module. It then runs a series of cleanup
175
/// passes (ADCE and SimplifyCFG) to eliminate any code which depends on the
176
/// value. The modified module is then returned.
177
///
178
std::unique_ptr<Module> deleteInstructionFromProgram(const Instruction *I,
179
unsigned Simp);
180
181
/// This method clones the current Program and performs a series of cleanups
182
/// intended to get rid of extra cruft on the module. If the
183
/// MayModifySemantics argument is true, then the cleanups is allowed to
184
/// modify how the code behaves.
185
///
186
std::unique_ptr<Module> performFinalCleanups(std::unique_ptr<Module> M,
187
bool MayModifySemantics = false);
188
189
/// Given a module, extract up to one loop from it into a new function. This
190
/// returns null if there are no extractable loops in the program or if the
191
/// loop extractor crashes.
192
std::unique_ptr<Module> extractLoop(Module *M);
193
194
/// Extract all but the specified basic blocks into their own functions. The
195
/// only detail is that M is actually a module cloned from the one the BBs are
196
/// in, so some mapping needs to be performed. If this operation fails for
197
/// some reason (ie the implementation is buggy), this function should return
198
/// null, otherwise it returns a new Module.
199
std::unique_ptr<Module>
200
extractMappedBlocksFromModule(const std::vector<BasicBlock *> &BBs,
201
Module *M);
202
203
/// Carefully run the specified set of pass on the specified/ module,
204
/// returning the transformed module on success, or a null pointer on failure.
205
std::unique_ptr<Module> runPassesOn(Module *M,
206
const std::vector<std::string> &Passes,
207
ArrayRef<std::string> ExtraArgs = {});
208
209
/// runPasses - Run the specified passes on Program, outputting a bitcode
210
/// file and writting the filename into OutputFile if successful. If the
211
/// optimizations fail for some reason (optimizer crashes), return true,
212
/// otherwise return false. If DeleteOutput is set to true, the bitcode is
213
/// deleted on success, and the filename string is undefined. This prints to
214
/// outs() a single line message indicating whether compilation was successful
215
/// or failed, unless Quiet is set. ExtraArgs specifies additional arguments
216
/// to pass to the child bugpoint instance.
217
///
218
bool runPasses(Module &Program, const std::vector<std::string> &PassesToRun,
219
std::string &OutputFilename, bool DeleteOutput = false,
220
bool Quiet = false,
221
ArrayRef<std::string> ExtraArgs = {}) const;
222
223
/// runPasses - Just like the method above, but this just returns true or
224
/// false indicating whether or not the optimizer crashed on the specified
225
/// input (true = crashed). Does not produce any output.
226
///
227
bool runPasses(Module &M, const std::vector<std::string> &PassesToRun) const {
228
std::string Filename;
229
return runPasses(M, PassesToRun, Filename, true);
230
}
231
232
/// Take the specified pass list and create different combinations of passes
233
/// to compile the program with. Compile the program with each set and mark
234
/// test to see if it compiled correctly. If the passes compiled correctly
235
/// output nothing and rearrange the passes into a new order. If the passes
236
/// did not compile correctly, output the command required to recreate the
237
/// failure.
238
Error runManyPasses(const std::vector<std::string> &AllPasses);
239
240
/// This writes the current "Program" to the named bitcode file. If an error
241
/// occurs, true is returned.
242
bool writeProgramToFile(const std::string &Filename, const Module &M) const;
243
bool writeProgramToFile(const std::string &Filename, int FD,
244
const Module &M) const;
245
bool writeProgramToFile(int FD, const Module &M) const;
246
247
private:
248
/// initializeExecutionEnvironment - This method is used to set up the
249
/// environment for executing LLVM programs.
250
///
251
Error initializeExecutionEnvironment();
252
};
253
254
struct DiscardTemp {
255
sys::fs::TempFile &File;
256
~DiscardTemp();
257
};
258
259
/// Given a bitcode or assembly input filename, parse and return it, or return
260
/// null if not possible.
261
///
262
std::unique_ptr<Module> parseInputFile(StringRef InputFilename,
263
LLVMContext &ctxt);
264
265
/// getPassesString - Turn a list of passes into a string which indicates the
266
/// command line options that must be passed to add the passes.
267
///
268
std::string getPassesString(const std::vector<std::string> &Passes);
269
270
/// PrintFunctionList - prints out list of problematic functions
271
///
272
void PrintFunctionList(const std::vector<Function *> &Funcs);
273
274
/// PrintGlobalVariableList - prints out list of problematic global variables
275
///
276
void PrintGlobalVariableList(const std::vector<GlobalVariable *> &GVs);
277
278
// DeleteGlobalInitializer - "Remove" the global variable by deleting its
279
// initializer, making it external.
280
//
281
void DeleteGlobalInitializer(GlobalVariable *GV);
282
283
// DeleteFunctionBody - "Remove" the function by deleting all of it's basic
284
// blocks, making it external.
285
//
286
void DeleteFunctionBody(Function *F);
287
288
/// Given a module and a list of functions in the module, split the functions
289
/// OUT of the specified module, and place them in the new module.
290
std::unique_ptr<Module>
291
SplitFunctionsOutOfModule(Module *M, const std::vector<Function *> &F,
292
ValueToValueMapTy &VMap);
293
294
} // End llvm namespace
295
296
#endif
297
298