bugpoint.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. //===- bugpoint.cpp - The LLVM Bugpoint utility ---------------------------===//
  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 program is an automated compiler debugger tool. It is used to narrow
  10. // down miscompilations and crash problems to a specific pass in the compiler,
  11. // and the specific Module or Function input that is causing the problem.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "BugDriver.h"
  15. #include "ToolRunner.h"
  16. #include "llvm/Config/llvm-config.h"
  17. #include "llvm/IR/LLVMContext.h"
  18. #include "llvm/IR/LegacyPassManager.h"
  19. #include "llvm/IR/LegacyPassNameParser.h"
  20. #include "llvm/InitializePasses.h"
  21. #include "llvm/LinkAllIR.h"
  22. #include "llvm/LinkAllPasses.h"
  23. #include "llvm/Passes/PassPlugin.h"
  24. #include "llvm/Support/CommandLine.h"
  25. #include "llvm/Support/InitLLVM.h"
  26. #include "llvm/Support/PluginLoader.h"
  27. #include "llvm/Support/PrettyStackTrace.h"
  28. #include "llvm/Support/Process.h"
  29. #include "llvm/Support/TargetSelect.h"
  30. #include "llvm/Support/Valgrind.h"
  31. #include "llvm/Transforms/IPO/AlwaysInliner.h"
  32. #include "llvm/Transforms/IPO/PassManagerBuilder.h"
  33. // Enable this macro to debug bugpoint itself.
  34. //#define DEBUG_BUGPOINT 1
  35. using namespace llvm;
  36. static cl::opt<bool>
  37. FindBugs("find-bugs", cl::desc("Run many different optimization sequences "
  38. "on program to find bugs"),
  39. cl::init(false));
  40. static cl::list<std::string>
  41. InputFilenames(cl::Positional, cl::OneOrMore,
  42. cl::desc("<input llvm ll/bc files>"));
  43. static cl::opt<unsigned> TimeoutValue(
  44. "timeout", cl::init(300), cl::value_desc("seconds"),
  45. cl::desc("Number of seconds program is allowed to run before it "
  46. "is killed (default is 300s), 0 disables timeout"));
  47. static cl::opt<int> MemoryLimit(
  48. "mlimit", cl::init(-1), cl::value_desc("MBytes"),
  49. cl::desc("Maximum amount of memory to use. 0 disables check. Defaults to "
  50. "400MB (800MB under valgrind, 0 with sanitizers)."));
  51. static cl::opt<bool>
  52. UseValgrind("enable-valgrind",
  53. cl::desc("Run optimizations through valgrind"));
  54. // The AnalysesList is automatically populated with registered Passes by the
  55. // PassNameParser.
  56. //
  57. static cl::list<const PassInfo *, bool, PassNameParser>
  58. PassList(cl::desc("Passes available:"));
  59. static cl::opt<bool>
  60. OptLevelO1("O1", cl::desc("Optimization level 1. Identical to 'opt -O1'"));
  61. static cl::opt<bool>
  62. OptLevelO2("O2", cl::desc("Optimization level 2. Identical to 'opt -O2'"));
  63. static cl::opt<bool> OptLevelOs(
  64. "Os",
  65. cl::desc(
  66. "Like -O2 with extra optimizations for size. Similar to clang -Os"));
  67. static cl::opt<bool>
  68. OptLevelOz("Oz",
  69. cl::desc("Like -Os but reduces code size further. Similar to clang -Oz"));
  70. static cl::opt<bool>
  71. OptLevelO3("O3", cl::desc("Optimization level 3. Identical to 'opt -O3'"));
  72. static cl::opt<std::string>
  73. OverrideTriple("mtriple", cl::desc("Override target triple for module"));
  74. /// BugpointIsInterrupted - Set to true when the user presses ctrl-c.
  75. bool llvm::BugpointIsInterrupted = false;
  76. #ifndef DEBUG_BUGPOINT
  77. static void BugpointInterruptFunction() { BugpointIsInterrupted = true; }
  78. #endif
  79. // Hack to capture a pass list.
  80. namespace {
  81. class AddToDriver : public legacy::FunctionPassManager {
  82. BugDriver &D;
  83. public:
  84. AddToDriver(BugDriver &_D) : FunctionPassManager(nullptr), D(_D) {}
  85. void add(Pass *P) override {
  86. const void *ID = P->getPassID();
  87. const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(ID);
  88. D.addPass(std::string(PI->getPassArgument()));
  89. }
  90. };
  91. }
  92. // This routine adds optimization passes based on selected optimization level,
  93. // OptLevel.
  94. //
  95. // OptLevel - Optimization Level
  96. static void AddOptimizationPasses(legacy::FunctionPassManager &FPM,
  97. unsigned OptLevel,
  98. unsigned SizeLevel) {
  99. PassManagerBuilder Builder;
  100. Builder.OptLevel = OptLevel;
  101. Builder.SizeLevel = SizeLevel;
  102. if (OptLevel > 1)
  103. Builder.Inliner = createFunctionInliningPass(OptLevel, SizeLevel, false);
  104. else
  105. Builder.Inliner = createAlwaysInlinerLegacyPass();
  106. Builder.populateFunctionPassManager(FPM);
  107. Builder.populateModulePassManager(FPM);
  108. }
  109. #define HANDLE_EXTENSION(Ext) \
  110. llvm::PassPluginLibraryInfo get##Ext##PluginInfo();
  111. #include "llvm/Support/Extension.def"
  112. int main(int argc, char **argv) {
  113. #ifndef DEBUG_BUGPOINT
  114. InitLLVM X(argc, argv);
  115. #endif
  116. // Initialize passes
  117. PassRegistry &Registry = *PassRegistry::getPassRegistry();
  118. initializeCore(Registry);
  119. initializeScalarOpts(Registry);
  120. initializeVectorization(Registry);
  121. initializeIPO(Registry);
  122. initializeAnalysis(Registry);
  123. initializeTransformUtils(Registry);
  124. initializeInstCombine(Registry);
  125. initializeTarget(Registry);
  126. if (std::getenv("bar") == (char*) -1) {
  127. InitializeAllTargets();
  128. InitializeAllTargetMCs();
  129. InitializeAllAsmPrinters();
  130. InitializeAllAsmParsers();
  131. }
  132. cl::ParseCommandLineOptions(argc, argv,
  133. "LLVM automatic testcase reducer. See\nhttp://"
  134. "llvm.org/cmds/bugpoint.html"
  135. " for more information.\n");
  136. #ifndef DEBUG_BUGPOINT
  137. sys::SetInterruptFunction(BugpointInterruptFunction);
  138. #endif
  139. LLVMContext Context;
  140. // If we have an override, set it and then track the triple we want Modules
  141. // to use.
  142. if (!OverrideTriple.empty()) {
  143. TargetTriple.setTriple(Triple::normalize(OverrideTriple));
  144. outs() << "Override triple set to '" << TargetTriple.getTriple() << "'\n";
  145. }
  146. if (MemoryLimit < 0) {
  147. // Set the default MemoryLimit. Be sure to update the flag's description if
  148. // you change this.
  149. if (sys::RunningOnValgrind() || UseValgrind)
  150. MemoryLimit = 800;
  151. else
  152. MemoryLimit = 400;
  153. #if (LLVM_ADDRESS_SANITIZER_BUILD || LLVM_MEMORY_SANITIZER_BUILD || \
  154. LLVM_THREAD_SANITIZER_BUILD)
  155. // Starting from kernel 4.9 memory allocated with mmap is counted against
  156. // RLIMIT_DATA. Sanitizers need to allocate tens of terabytes for shadow.
  157. MemoryLimit = 0;
  158. #endif
  159. }
  160. BugDriver D(argv[0], FindBugs, TimeoutValue, MemoryLimit, UseValgrind,
  161. Context);
  162. if (D.addSources(InputFilenames))
  163. return 1;
  164. AddToDriver PM(D);
  165. if (OptLevelO1)
  166. AddOptimizationPasses(PM, 1, 0);
  167. else if (OptLevelO2)
  168. AddOptimizationPasses(PM, 2, 0);
  169. else if (OptLevelO3)
  170. AddOptimizationPasses(PM, 3, 0);
  171. else if (OptLevelOs)
  172. AddOptimizationPasses(PM, 2, 1);
  173. else if (OptLevelOz)
  174. AddOptimizationPasses(PM, 2, 2);
  175. for (const PassInfo *PI : PassList)
  176. D.addPass(std::string(PI->getPassArgument()));
  177. // Bugpoint has the ability of generating a plethora of core files, so to
  178. // avoid filling up the disk, we prevent it
  179. #ifndef DEBUG_BUGPOINT
  180. sys::Process::PreventCoreFiles();
  181. #endif
  182. // Needed to pull in symbols from statically linked extensions, including static
  183. // registration. It is unused otherwise because bugpoint has no support for
  184. // NewPM.
  185. #define HANDLE_EXTENSION(Ext) \
  186. (void)get##Ext##PluginInfo();
  187. #include "llvm/Support/Extension.def"
  188. if (Error E = D.run()) {
  189. errs() << toString(std::move(E));
  190. return 1;
  191. }
  192. return 0;
  193. }