bugpoint.cpp revision 212793
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"
18193323Sed#include "llvm/LinkAllPasses.h"
19195340Sed#include "llvm/LLVMContext.h"
20193323Sed#include "llvm/Support/PassNameParser.h"
21193323Sed#include "llvm/Support/CommandLine.h"
22193323Sed#include "llvm/Support/ManagedStatic.h"
23193323Sed#include "llvm/Support/PluginLoader.h"
24193323Sed#include "llvm/Support/PrettyStackTrace.h"
25198090Srdivacky#include "llvm/Support/StandardPasses.h"
26193323Sed#include "llvm/System/Process.h"
27193323Sed#include "llvm/System/Signals.h"
28205407Srdivacky#include "llvm/System/Valgrind.h"
29193323Sed#include "llvm/LinkAllVMCore.h"
30193323Sedusing namespace llvm;
31193323Sed
32193323Sedstatic cl::opt<bool>
33193323SedFindBugs("find-bugs", cl::desc("Run many different optimization sequences "
34193323Sed                               "on program to find bugs"), cl::init(false));
35193323Sed
36193323Sedstatic cl::list<std::string>
37193323SedInputFilenames(cl::Positional, cl::OneOrMore,
38193323Sed               cl::desc("<input llvm ll/bc files>"));
39193323Sed
40193323Sedstatic cl::opt<unsigned>
41193323SedTimeoutValue("timeout", cl::init(300), cl::value_desc("seconds"),
42193323Sed             cl::desc("Number of seconds program is allowed to run before it "
43193323Sed                      "is killed (default is 300s), 0 disables timeout"));
44193323Sed
45205407Srdivackystatic cl::opt<int>
46205407SrdivackyMemoryLimit("mlimit", cl::init(-1), cl::value_desc("MBytes"),
47205407Srdivacky             cl::desc("Maximum amount of memory to use. 0 disables check."
48205407Srdivacky                      " Defaults to 100MB (800MB under valgrind)."));
49193323Sed
50205407Srdivackystatic cl::opt<bool>
51205407SrdivackyUseValgrind("enable-valgrind",
52205407Srdivacky            cl::desc("Run optimizations through valgrind"));
53205407Srdivacky
54193323Sed// The AnalysesList is automatically populated with registered Passes by the
55193323Sed// PassNameParser.
56193323Sed//
57193323Sedstatic cl::list<const PassInfo*, bool, PassNameParser>
58193323SedPassList(cl::desc("Passes available:"), cl::ZeroOrMore);
59193323Sed
60198090Srdivackystatic cl::opt<bool>
61198090SrdivackyStandardCompileOpts("std-compile-opts",
62198090Srdivacky                   cl::desc("Include the standard compile time optimizations"));
63198090Srdivacky
64198090Srdivackystatic cl::opt<bool>
65198090SrdivackyStandardLinkOpts("std-link-opts",
66198090Srdivacky                 cl::desc("Include the standard link time optimizations"));
67198090Srdivacky
68198090Srdivackystatic cl::opt<std::string>
69198090SrdivackyOverrideTriple("mtriple", cl::desc("Override target triple for module"));
70198090Srdivacky
71193323Sed/// BugpointIsInterrupted - Set to true when the user presses ctrl-c.
72193323Sedbool llvm::BugpointIsInterrupted = false;
73193323Sed
74193323Sedstatic void BugpointInterruptFunction() {
75193323Sed  BugpointIsInterrupted = true;
76193323Sed}
77193323Sed
78198090Srdivacky// Hack to capture a pass list.
79198090Srdivackynamespace {
80198090Srdivacky  class AddToDriver : public PassManager {
81198090Srdivacky    BugDriver &D;
82198090Srdivacky  public:
83198090Srdivacky    AddToDriver(BugDriver &_D) : D(_D) {}
84198090Srdivacky
85198090Srdivacky    virtual void add(Pass *P) {
86212793Sdim      const void *ID = P->getPassID();
87212793Sdim      const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(ID);
88212793Sdim      D.addPass(PI->getPassArgument());
89198090Srdivacky    }
90198090Srdivacky  };
91198090Srdivacky}
92198090Srdivacky
93193323Sedint main(int argc, char **argv) {
94193323Sed  llvm::sys::PrintStackTraceOnErrorSignal();
95193323Sed  llvm::PrettyStackTraceProgram X(argc, argv);
96193323Sed  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
97193323Sed  cl::ParseCommandLineOptions(argc, argv,
98193323Sed                              "LLVM automatic testcase reducer. See\nhttp://"
99193323Sed                              "llvm.org/cmds/bugpoint.html"
100193323Sed                              " for more information.\n");
101193323Sed  sys::SetInterruptFunction(BugpointInterruptFunction);
102195340Sed
103198090Srdivacky  LLVMContext& Context = getGlobalContext();
104198090Srdivacky  // If we have an override, set it and then track the triple we want Modules
105198090Srdivacky  // to use.
106198090Srdivacky  if (!OverrideTriple.empty()) {
107212793Sdim    TargetTriple.setTriple(Triple::normalize(OverrideTriple));
108212793Sdim    outs() << "Override triple set to '" << TargetTriple.getTriple() << "'\n";
109198090Srdivacky  }
110198090Srdivacky
111205407Srdivacky  if (MemoryLimit < 0) {
112205407Srdivacky    // Set the default MemoryLimit.  Be sure to update the flag's description if
113205407Srdivacky    // you change this.
114205407Srdivacky    if (sys::RunningOnValgrind() || UseValgrind)
115205407Srdivacky      MemoryLimit = 800;
116205407Srdivacky    else
117205407Srdivacky      MemoryLimit = 100;
118205407Srdivacky  }
119205407Srdivacky
120212793Sdim  BugDriver D(argv[0], FindBugs, TimeoutValue, MemoryLimit,
121205407Srdivacky              UseValgrind, Context);
122193323Sed  if (D.addSources(InputFilenames)) return 1;
123198090Srdivacky
124198090Srdivacky  AddToDriver PM(D);
125198090Srdivacky  if (StandardCompileOpts) {
126198090Srdivacky    createStandardModulePasses(&PM, 3,
127198090Srdivacky                               /*OptimizeSize=*/ false,
128198090Srdivacky                               /*UnitAtATime=*/ true,
129198090Srdivacky                               /*UnrollLoops=*/ true,
130198090Srdivacky                               /*SimplifyLibCalls=*/ true,
131198090Srdivacky                               /*HaveExceptions=*/ true,
132198090Srdivacky                               createFunctionInliningPass());
133198090Srdivacky  }
134198090Srdivacky
135198090Srdivacky  if (StandardLinkOpts)
136198090Srdivacky    createStandardLTOPasses(&PM, /*Internalize=*/true,
137198090Srdivacky                            /*RunInliner=*/true,
138198090Srdivacky                            /*VerifyEach=*/false);
139198090Srdivacky
140193323Sed
141212793Sdim  for (std::vector<const PassInfo*>::iterator I = PassList.begin(),
142212793Sdim         E = PassList.end();
143212793Sdim       I != E; ++I) {
144212793Sdim    const PassInfo* PI = *I;
145212793Sdim    D.addPass(PI->getPassArgument());
146212793Sdim  }
147212793Sdim
148193323Sed  // Bugpoint has the ability of generating a plethora of core files, so to
149193323Sed  // avoid filling up the disk, we prevent it
150193323Sed  sys::Process::PreventCoreFiles();
151193323Sed
152207618Srdivacky  std::string Error;
153207618Srdivacky  bool Failure = D.run(Error);
154207618Srdivacky  if (!Error.empty()) {
155207618Srdivacky    errs() << Error;
156207618Srdivacky    return 1;
157193323Sed  }
158207618Srdivacky  return Failure;
159193323Sed}
160