llvm-reduce.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. //===- llvm-reduce.cpp - The LLVM Delta Reduction 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 tries to reduce an IR test case for a given interesting-ness
  10. // test. It runs multiple delta debugging passes in order to minimize the input
  11. // file. It's worth noting that this is a part of the bugpoint redesign
  12. // proposal, and thus a *temporary* tool that will eventually be integrated
  13. // into the bugpoint tool itself.
  14. //
  15. //===----------------------------------------------------------------------===//
  16. #include "DeltaManager.h"
  17. #include "ReducerWorkItem.h"
  18. #include "TestRunner.h"
  19. #include "llvm/ADT/SmallString.h"
  20. #include "llvm/CodeGen/CommandFlags.h"
  21. #include "llvm/IR/LLVMContext.h"
  22. #include "llvm/IR/Verifier.h"
  23. #include "llvm/IRReader/IRReader.h"
  24. #include "llvm/MC/TargetRegistry.h"
  25. #include "llvm/Support/CommandLine.h"
  26. #include "llvm/Support/Host.h"
  27. #include "llvm/Support/InitLLVM.h"
  28. #include "llvm/Support/SourceMgr.h"
  29. #include "llvm/Support/TargetSelect.h"
  30. #include "llvm/Support/raw_ostream.h"
  31. #include "llvm/Support/WithColor.h"
  32. #include "llvm/Target/TargetMachine.h"
  33. #include <system_error>
  34. #include <vector>
  35. using namespace llvm;
  36. static cl::OptionCategory Options("llvm-reduce options");
  37. static cl::opt<bool> Help("h", cl::desc("Alias for -help"), cl::Hidden,
  38. cl::cat(Options));
  39. static cl::opt<bool> Version("v", cl::desc("Alias for -version"), cl::Hidden,
  40. cl::cat(Options));
  41. static cl::opt<bool>
  42. PrintDeltaPasses("print-delta-passes",
  43. cl::desc("Print list of delta passes, passable to "
  44. "--delta-passes as a comma separated list"),
  45. cl::cat(Options));
  46. static cl::opt<std::string> InputFilename(cl::Positional, cl::Required,
  47. cl::desc("<input llvm ll/bc file>"),
  48. cl::cat(Options));
  49. static cl::opt<std::string>
  50. TestFilename("test", cl::Required,
  51. cl::desc("Name of the interesting-ness test to be run"),
  52. cl::cat(Options));
  53. static cl::list<std::string>
  54. TestArguments("test-arg", cl::ZeroOrMore,
  55. cl::desc("Arguments passed onto the interesting-ness test"),
  56. cl::cat(Options));
  57. static cl::opt<std::string> OutputFilename(
  58. "output", cl::desc("Specify the output file. default: reduced.ll|mir"));
  59. static cl::alias OutputFileAlias("o", cl::desc("Alias for -output"),
  60. cl::aliasopt(OutputFilename),
  61. cl::cat(Options));
  62. static cl::opt<bool>
  63. ReplaceInput("in-place",
  64. cl::desc("WARNING: This option will replace your input file "
  65. "with the reduced version!"),
  66. cl::cat(Options));
  67. enum class InputLanguages { None, IR, MIR };
  68. static cl::opt<InputLanguages>
  69. InputLanguage("x", cl::ValueOptional,
  70. cl::desc("Input language ('ir' or 'mir')"),
  71. cl::init(InputLanguages::None),
  72. cl::values(clEnumValN(InputLanguages::IR, "ir", ""),
  73. clEnumValN(InputLanguages::MIR, "mir", "")),
  74. cl::cat(Options));
  75. static cl::opt<std::string> TargetTriple("mtriple",
  76. cl::desc("Set the target triple"),
  77. cl::cat(Options));
  78. static cl::opt<int>
  79. MaxPassIterations("max-pass-iterations",
  80. cl::desc("Maximum number of times to run the full set "
  81. "of delta passes (default=1)"),
  82. cl::init(1), cl::cat(Options));
  83. static codegen::RegisterCodeGenFlags CGF;
  84. void writeOutput(ReducerWorkItem &M, StringRef Message) {
  85. if (ReplaceInput) // In-place
  86. OutputFilename = InputFilename.c_str();
  87. else if (OutputFilename.empty() || OutputFilename == "-")
  88. OutputFilename = M.isMIR() ? "reduced.mir" : "reduced.ll";
  89. std::error_code EC;
  90. raw_fd_ostream Out(OutputFilename, EC);
  91. if (EC) {
  92. errs() << "Error opening output file: " << EC.message() << "!\n";
  93. exit(1);
  94. }
  95. M.print(Out, /*AnnotationWriter=*/nullptr);
  96. errs() << Message << OutputFilename << "\n";
  97. }
  98. static std::unique_ptr<LLVMTargetMachine> createTargetMachine() {
  99. InitializeAllTargets();
  100. InitializeAllTargetMCs();
  101. InitializeAllAsmPrinters();
  102. InitializeAllAsmParsers();
  103. if (TargetTriple == "")
  104. TargetTriple = sys::getDefaultTargetTriple();
  105. auto TT(Triple::normalize(TargetTriple));
  106. std::string CPU(codegen::getCPUStr());
  107. std::string FS(codegen::getFeaturesStr());
  108. std::string Error;
  109. const Target *TheTarget = TargetRegistry::lookupTarget(TT, Error);
  110. return std::unique_ptr<LLVMTargetMachine>(
  111. static_cast<LLVMTargetMachine *>(TheTarget->createTargetMachine(
  112. TT, CPU, FS, TargetOptions(), None, None, CodeGenOpt::Default)));
  113. }
  114. int main(int Argc, char **Argv) {
  115. InitLLVM X(Argc, Argv);
  116. cl::HideUnrelatedOptions({&Options, &getColorCategory()});
  117. cl::ParseCommandLineOptions(Argc, Argv, "LLVM automatic testcase reducer.\n");
  118. bool ReduceModeMIR = false;
  119. if (InputLanguage != InputLanguages::None) {
  120. if (InputLanguage == InputLanguages::MIR)
  121. ReduceModeMIR = true;
  122. } else if (StringRef(InputFilename).endswith(".mir")) {
  123. ReduceModeMIR = true;
  124. }
  125. if (PrintDeltaPasses) {
  126. printDeltaPasses(errs());
  127. return 0;
  128. }
  129. LLVMContext Context;
  130. std::unique_ptr<LLVMTargetMachine> TM;
  131. std::unique_ptr<MachineModuleInfo> MMI;
  132. std::unique_ptr<ReducerWorkItem> OriginalProgram;
  133. if (ReduceModeMIR) {
  134. TM = createTargetMachine();
  135. MMI = std::make_unique<MachineModuleInfo>(TM.get());
  136. }
  137. OriginalProgram = parseReducerWorkItem(InputFilename, Context, MMI.get());
  138. if (!OriginalProgram) {
  139. return 1;
  140. }
  141. // Initialize test environment
  142. TestRunner Tester(TestFilename, TestArguments, std::move(OriginalProgram));
  143. // Try to reduce code
  144. runDeltaPasses(Tester, MaxPassIterations);
  145. // Print reduced file to STDOUT
  146. if (OutputFilename == "-")
  147. Tester.getProgram().print(outs(), nullptr);
  148. else
  149. writeOutput(Tester.getProgram(), "\nDone reducing! Reduced testcase: ");
  150. return 0;
  151. }