bugpoint.cpp revision 314564
1193323Sed//===- bugpoint.cpp - The LLVM Bugpoint utility ---------------------------===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// This program is an automated compiler debugger tool.  It is used to narrow
11193323Sed// down miscompilations and crash problems to a specific pass in the compiler,
12193323Sed// and the specific Module or Function input that is causing the problem.
13193323Sed//
14193323Sed//===----------------------------------------------------------------------===//
15193323Sed
16193323Sed#include "BugDriver.h"
17193323Sed#include "ToolRunner.h"
18249423Sdim#include "llvm/IR/LLVMContext.h"
19288943Sdim#include "llvm/IR/LegacyPassManager.h"
20276479Sdim#include "llvm/IR/LegacyPassNameParser.h"
21249423Sdim#include "llvm/LinkAllIR.h"
22193323Sed#include "llvm/LinkAllPasses.h"
23193323Sed#include "llvm/Support/CommandLine.h"
24193323Sed#include "llvm/Support/ManagedStatic.h"
25193323Sed#include "llvm/Support/PluginLoader.h"
26193323Sed#include "llvm/Support/PrettyStackTrace.h"
27218885Sdim#include "llvm/Support/Process.h"
28218885Sdim#include "llvm/Support/Signals.h"
29218885Sdim#include "llvm/Support/Valgrind.h"
30314564Sdim#include "llvm/Transforms/IPO/AlwaysInliner.h"
31226584Sdim#include "llvm/Transforms/IPO/PassManagerBuilder.h"
32218885Sdim
33314564Sdim// Enable this macro to debug bugpoint itself.
34218885Sdim//#define DEBUG_BUGPOINT 1
35218885Sdim
36193323Sedusing namespace llvm;
37193323Sed
38276479Sdimstatic cl::opt<bool>
39314564Sdim    FindBugs("find-bugs", cl::desc("Run many different optimization sequences "
40314564Sdim                                   "on program to find bugs"),
41314564Sdim             cl::init(false));
42193323Sed
43193323Sedstatic cl::list<std::string>
44314564Sdim    InputFilenames(cl::Positional, cl::OneOrMore,
45314564Sdim                   cl::desc("<input llvm ll/bc files>"));
46193323Sed
47314564Sdimstatic cl::opt<unsigned> TimeoutValue(
48314564Sdim    "timeout", cl::init(300), cl::value_desc("seconds"),
49314564Sdim    cl::desc("Number of seconds program is allowed to run before it "
50314564Sdim             "is killed (default is 300s), 0 disables timeout"));
51193323Sed
52205407Srdivackystatic cl::opt<int>
53314564Sdim    MemoryLimit("mlimit", cl::init(-1), cl::value_desc("MBytes"),
54314564Sdim                cl::desc("Maximum amount of memory to use. 0 disables check."
55314564Sdim                         " Defaults to 400MB (800MB under valgrind)."));
56193323Sed
57205407Srdivackystatic cl::opt<bool>
58314564Sdim    UseValgrind("enable-valgrind",
59314564Sdim                cl::desc("Run optimizations through valgrind"));
60205407Srdivacky
61193323Sed// The AnalysesList is automatically populated with registered Passes by the
62193323Sed// PassNameParser.
63193323Sed//
64314564Sdimstatic cl::list<const PassInfo *, bool, PassNameParser>
65314564Sdim    PassList(cl::desc("Passes available:"), cl::ZeroOrMore);
66193323Sed
67198090Srdivackystatic cl::opt<bool>
68314564Sdim    StandardLinkOpts("std-link-opts",
69314564Sdim                     cl::desc("Include the standard link time optimizations"));
70198090Srdivacky
71223013Sdimstatic cl::opt<bool>
72314564Sdim    OptLevelO1("O1", cl::desc("Optimization level 1. Identical to 'opt -O1'"));
73223013Sdim
74223013Sdimstatic cl::opt<bool>
75314564Sdim    OptLevelO2("O2", cl::desc("Optimization level 2. Identical to 'opt -O2'"));
76223013Sdim
77314564Sdimstatic cl::opt<bool> OptLevelOs(
78314564Sdim    "Os",
79314564Sdim    cl::desc(
80314564Sdim        "Like -O2 with extra optimizations for size. Similar to clang -Os"));
81314564Sdim
82223013Sdimstatic cl::opt<bool>
83314564Sdim    OptLevelO3("O3", cl::desc("Optimization level 3. Identical to 'opt -O3'"));
84223013Sdim
85198090Srdivackystatic cl::opt<std::string>
86314564Sdim    OverrideTriple("mtriple", cl::desc("Override target triple for module"));
87198090Srdivacky
88193323Sed/// BugpointIsInterrupted - Set to true when the user presses ctrl-c.
89193323Sedbool llvm::BugpointIsInterrupted = false;
90193323Sed
91218885Sdim#ifndef DEBUG_BUGPOINT
92314564Sdimstatic void BugpointInterruptFunction() { BugpointIsInterrupted = true; }
93218885Sdim#endif
94193323Sed
95198090Srdivacky// Hack to capture a pass list.
96198090Srdivackynamespace {
97314564Sdimclass AddToDriver : public legacy::FunctionPassManager {
98314564Sdim  BugDriver &D;
99276479Sdim
100314564Sdimpublic:
101314564Sdim  AddToDriver(BugDriver &_D) : FunctionPassManager(nullptr), D(_D) {}
102314564Sdim
103314564Sdim  void add(Pass *P) override {
104314564Sdim    const void *ID = P->getPassID();
105314564Sdim    const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(ID);
106314564Sdim    D.addPass(PI->getPassArgument());
107314564Sdim  }
108314564Sdim};
109198090Srdivacky}
110198090Srdivacky
111276479Sdim#ifdef LINK_POLLY_INTO_TOOLS
112276479Sdimnamespace polly {
113276479Sdimvoid initializePollyPasses(llvm::PassRegistry &Registry);
114276479Sdim}
115276479Sdim#endif
116276479Sdim
117193323Sedint main(int argc, char **argv) {
118218885Sdim#ifndef DEBUG_BUGPOINT
119309124Sdim  llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
120193323Sed  llvm::PrettyStackTraceProgram X(argc, argv);
121314564Sdim  llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
122218885Sdim#endif
123276479Sdim
124218885Sdim  // Initialize passes
125218885Sdim  PassRegistry &Registry = *PassRegistry::getPassRegistry();
126218885Sdim  initializeCore(Registry);
127218885Sdim  initializeScalarOpts(Registry);
128249423Sdim  initializeObjCARCOpts(Registry);
129234353Sdim  initializeVectorization(Registry);
130218885Sdim  initializeIPO(Registry);
131218885Sdim  initializeAnalysis(Registry);
132218885Sdim  initializeTransformUtils(Registry);
133218885Sdim  initializeInstCombine(Registry);
134218885Sdim  initializeInstrumentation(Registry);
135218885Sdim  initializeTarget(Registry);
136276479Sdim
137276479Sdim#ifdef LINK_POLLY_INTO_TOOLS
138276479Sdim  polly::initializePollyPasses(Registry);
139276479Sdim#endif
140276479Sdim
141193323Sed  cl::ParseCommandLineOptions(argc, argv,
142193323Sed                              "LLVM automatic testcase reducer. See\nhttp://"
143193323Sed                              "llvm.org/cmds/bugpoint.html"
144193323Sed                              " for more information.\n");
145218885Sdim#ifndef DEBUG_BUGPOINT
146193323Sed  sys::SetInterruptFunction(BugpointInterruptFunction);
147218885Sdim#endif
148195340Sed
149309124Sdim  LLVMContext Context;
150198090Srdivacky  // If we have an override, set it and then track the triple we want Modules
151198090Srdivacky  // to use.
152198090Srdivacky  if (!OverrideTriple.empty()) {
153212793Sdim    TargetTriple.setTriple(Triple::normalize(OverrideTriple));
154212793Sdim    outs() << "Override triple set to '" << TargetTriple.getTriple() << "'\n";
155198090Srdivacky  }
156198090Srdivacky
157205407Srdivacky  if (MemoryLimit < 0) {
158205407Srdivacky    // Set the default MemoryLimit.  Be sure to update the flag's description if
159205407Srdivacky    // you change this.
160205407Srdivacky    if (sys::RunningOnValgrind() || UseValgrind)
161205407Srdivacky      MemoryLimit = 800;
162205407Srdivacky    else
163288943Sdim      MemoryLimit = 400;
164205407Srdivacky  }
165205407Srdivacky
166314564Sdim  BugDriver D(argv[0], FindBugs, TimeoutValue, MemoryLimit, UseValgrind,
167314564Sdim              Context);
168314564Sdim  if (D.addSources(InputFilenames))
169314564Sdim    return 1;
170276479Sdim
171198090Srdivacky  AddToDriver PM(D);
172276479Sdim
173223013Sdim  if (StandardLinkOpts) {
174223013Sdim    PassManagerBuilder Builder;
175280031Sdim    Builder.Inliner = createFunctionInliningPass();
176280031Sdim    Builder.populateLTOPassManager(PM);
177223013Sdim  }
178198090Srdivacky
179223013Sdim  if (OptLevelO1 || OptLevelO2 || OptLevelO3) {
180223013Sdim    PassManagerBuilder Builder;
181223013Sdim    if (OptLevelO1)
182314564Sdim      Builder.Inliner = createAlwaysInlinerLegacyPass();
183314564Sdim    else if (OptLevelOs || OptLevelO2)
184314564Sdim      Builder.Inliner = createFunctionInliningPass(2, OptLevelOs ? 1 : 0);
185223013Sdim    else
186223013Sdim      Builder.Inliner = createFunctionInliningPass(275);
187223013Sdim    Builder.populateFunctionPassManager(PM);
188223013Sdim    Builder.populateModulePassManager(PM);
189223013Sdim  }
190223013Sdim
191296417Sdim  for (const PassInfo *PI : PassList)
192212793Sdim    D.addPass(PI->getPassArgument());
193212793Sdim
194314564Sdim// Bugpoint has the ability of generating a plethora of core files, so to
195314564Sdim// avoid filling up the disk, we prevent it
196218885Sdim#ifndef DEBUG_BUGPOINT
197193323Sed  sys::Process::PreventCoreFiles();
198218885Sdim#endif
199193323Sed
200314564Sdim  if (Error E = D.run()) {
201314564Sdim    errs() << toString(std::move(E));
202207618Srdivacky    return 1;
203193323Sed  }
204314564Sdim  return 0;
205193323Sed}
206