bugpoint.cpp 7.9 KB

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