llvm-reduce: Reorganize some function locations
authorMatt Arsenault <Matthew.Arsenault@amd.com>
Tue, 17 Jan 2023 18:35:43 +0000 (13:35 -0500)
committerMatt Arsenault <arsenm2@gmail.com>
Sat, 21 Jan 2023 03:21:13 +0000 (23:21 -0400)
Move things that are naturally methods of ReducerWorkItem to
be methods of ReducerWorkItem in the same source file.

llvm/tools/llvm-reduce/ReducerWorkItem.cpp
llvm/tools/llvm-reduce/ReducerWorkItem.h
llvm/tools/llvm-reduce/TestRunner.cpp
llvm/tools/llvm-reduce/TestRunner.h
llvm/tools/llvm-reduce/deltas/Delta.cpp
llvm/tools/llvm-reduce/deltas/Delta.h
llvm/tools/llvm-reduce/llvm-reduce.cpp

index a33a427..c3ca777 100644 (file)
@@ -7,7 +7,11 @@
 //===----------------------------------------------------------------------===//
 
 #include "ReducerWorkItem.h"
+#include "TestRunner.h"
+#include "llvm/Analysis/ModuleSummaryAnalysis.h"
+#include "llvm/Analysis/ProfileSummaryInfo.h"
 #include "llvm/Bitcode/BitcodeReader.h"
+#include "llvm/Bitcode/BitcodeWriter.h"
 #include "llvm/CodeGen/CommandFlags.h"
 #include "llvm/CodeGen/MIRParser/MIRParser.h"
 #include "llvm/CodeGen/MIRPrinter.h"
 #include "llvm/IR/Verifier.h"
 #include "llvm/IRReader/IRReader.h"
 #include "llvm/MC/TargetRegistry.h"
+#include "llvm/Passes/PassBuilder.h"
 #include "llvm/Support/Host.h"
 #include "llvm/Support/MemoryBufferRef.h"
 #include "llvm/Support/SourceMgr.h"
 #include "llvm/Support/TargetSelect.h"
+#include "llvm/Support/ToolOutputFile.h"
 #include "llvm/Support/WithColor.h"
 #include "llvm/Target/TargetMachine.h"
+#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
 #include "llvm/Transforms/Utils/Cloning.h"
 #include <optional>
 
@@ -44,8 +51,10 @@ static cl::opt<std::string> TargetTriple("mtriple",
                                          cl::desc("Set the target triple"),
                                          cl::cat(LLVMReduceOptions));
 
-void readBitcode(ReducerWorkItem &M, MemoryBufferRef Data, LLVMContext &Ctx,
-                 StringRef ToolName);
+static cl::opt<bool> TmpFilesAsBitcode(
+    "write-tmp-files-as-bitcode",
+    cl::desc("Always write temporary files as bitcode instead of textual IR"),
+    cl::init(false), cl::cat(LLVMReduceOptions));
 
 static void cloneFrameInfo(
     MachineFrameInfo &DstMFI, const MachineFrameInfo &SrcMFI,
@@ -392,102 +401,75 @@ static void initializeTargetInfo() {
   InitializeAllAsmParsers();
 }
 
-std::pair<std::unique_ptr<ReducerWorkItem>, bool>
-parseReducerWorkItem(StringRef ToolName, StringRef Filename, LLVMContext &Ctxt,
-                     std::unique_ptr<TargetMachine> &TM, bool IsMIR) {
-  bool IsBitcode = false;
-  Triple TheTriple;
+void ReducerWorkItem::print(raw_ostream &ROS, void *p) const {
+  if (MMI) {
+    printMIR(ROS, *M);
+    for (Function &F : *M) {
+      if (auto *MF = MMI->getMachineFunction(F))
+        printMIR(ROS, *MF);
+    }
+  } else {
+    M->print(ROS, /*AssemblyAnnotationWriter=*/nullptr,
+             /*ShouldPreserveUseListOrder=*/true);
+  }
+}
 
-  auto MMM = std::make_unique<ReducerWorkItem>();
+bool ReducerWorkItem::verify(raw_fd_ostream *OS) const {
+  if (verifyModule(*M, OS))
+    return true;
 
-  if (IsMIR) {
-    initializeTargetInfo();
+  if (!MMI)
+    return false;
 
-    auto FileOrErr = MemoryBuffer::getFileOrSTDIN(Filename, /*IsText=*/true);
-    if (std::error_code EC = FileOrErr.getError()) {
-      WithColor::error(errs(), ToolName) << EC.message() << '\n';
-      return {nullptr, false};
+  for (const Function &F : getModule()) {
+    if (const MachineFunction *MF = MMI->getMachineFunction(F)) {
+      if (!MF->verify(nullptr, "", /*AbortOnError=*/false))
+        return true;
     }
+  }
 
-    std::unique_ptr<MIRParser> MParser =
-        createMIRParser(std::move(FileOrErr.get()), Ctxt);
-
-    auto SetDataLayout = [&](StringRef DataLayoutTargetTriple,
-                             StringRef OldDLStr) -> std::optional<std::string> {
-      // If we are supposed to override the target triple, do so now.
-      std::string IRTargetTriple = DataLayoutTargetTriple.str();
-      if (!TargetTriple.empty())
-        IRTargetTriple = Triple::normalize(TargetTriple);
-      TheTriple = Triple(IRTargetTriple);
-      if (TheTriple.getTriple().empty())
-        TheTriple.setTriple(sys::getDefaultTargetTriple());
-
-      std::string Error;
-      const Target *TheTarget =
-          TargetRegistry::lookupTarget(codegen::getMArch(), TheTriple, Error);
-      if (!TheTarget) {
-        WithColor::error(errs(), ToolName) << Error;
-        exit(1);
-      }
+  return false;
+}
 
-      // Hopefully the MIR parsing doesn't depend on any options.
-      TargetOptions Options;
-      std::optional<Reloc::Model> RM = codegen::getExplicitRelocModel();
-      std::string CPUStr = codegen::getCPUStr();
-      std::string FeaturesStr = codegen::getFeaturesStr();
-      TM = std::unique_ptr<TargetMachine>(TheTarget->createTargetMachine(
-          TheTriple.getTriple(), CPUStr, FeaturesStr, Options, RM,
-          codegen::getExplicitCodeModel(), CodeGenOpt::Default));
-      assert(TM && "Could not allocate target machine!");
+bool ReducerWorkItem::isReduced(const TestRunner &Test) const {
+  const bool UseBitcode = Test.inputIsBitcode() || TmpFilesAsBitcode;
 
-      return TM->createDataLayout().getStringRepresentation();
-    };
+  SmallString<128> CurrentFilepath;
 
-    std::unique_ptr<Module> M = MParser->parseIRModule(SetDataLayout);
-    LLVMTargetMachine *LLVMTM = static_cast<LLVMTargetMachine *>(TM.get());
+  // Write ReducerWorkItem to tmp file
+  int FD;
+  std::error_code EC = sys::fs::createTemporaryFile(
+      "llvm-reduce", isMIR() ? "mir" : (UseBitcode ? "bc" : "ll"), FD,
+      CurrentFilepath,
+      UseBitcode && !isMIR() ? sys::fs::OF_None : sys::fs::OF_Text);
+  if (EC) {
+    errs() << "Error making unique filename: " << EC.message() << "!\n";
+    exit(1);
+  }
 
-    MMM->MMI = std::make_unique<MachineModuleInfo>(LLVMTM);
-    MParser->parseMachineFunctions(*M, *MMM->MMI);
-    MMM->M = std::move(M);
-  } else {
-    SMDiagnostic Err;
-    ErrorOr<std::unique_ptr<MemoryBuffer>> MB = MemoryBuffer::getFileOrSTDIN(Filename);
-    if (std::error_code EC = MB.getError()) {
-      WithColor::error(errs(), ToolName) << Filename << ": " << EC.message() << "\n";
-      return {nullptr, false};
-    }
+  ToolOutputFile Out(CurrentFilepath, FD);
 
-    if (!isBitcode((const unsigned char *)(*MB)->getBufferStart(),
-                  (const unsigned char *)(*MB)->getBufferEnd())) {
-      std::unique_ptr<Module> Result = parseIRFile(Filename, Err, Ctxt);
-      if (!Result) {
-        Err.print(ToolName.data(), errs());
-        return {nullptr, false};
-      }
-      MMM->M = std::move(Result);
-    } else {
-      IsBitcode = true;
-      readBitcode(*MMM, MemoryBufferRef(**MB), Ctxt, ToolName);
+  // FIXME: This should be UseBitcode
+  writeOutput(Out.os(), TmpFilesAsBitcode);
 
-      if (MMM->LTOInfo->IsThinLTO && MMM->LTOInfo->EnableSplitLTOUnit)
-       initializeTargetInfo();
-    }
+  Out.os().close();
+  if (Out.os().has_error()) {
+    errs() << "Error emitting bitcode to file '" << CurrentFilepath
+           << "': " << Out.os().error().message();
+    exit(1);
   }
-  if (verifyReducerWorkItem(*MMM, &errs())) {
-    WithColor::error(errs(), ToolName)
-        << Filename << " - input module is broken!\n";
-    return {nullptr, false};
-  }
-  return {std::move(MMM), IsBitcode};
+
+  // Current Chunks aren't interesting
+  return Test.run(CurrentFilepath);
 }
 
 std::unique_ptr<ReducerWorkItem>
-cloneReducerWorkItem(const ReducerWorkItem &MMM, const TargetMachine *TM) {
+ReducerWorkItem::clone(const TargetMachine *TM) const {
   auto CloneMMM = std::make_unique<ReducerWorkItem>();
   if (TM) {
     // We're assuming the Module IR contents are always unchanged by MIR
     // reductions, and can share it as a constant.
-    CloneMMM->M = MMM.M;
+    CloneMMM->M = M;
 
     // MachineModuleInfo contains a lot of other state used during codegen which
     // we won't be using here, but we should be able to ignore it (although this
@@ -496,46 +478,16 @@ cloneReducerWorkItem(const ReducerWorkItem &MMM, const TargetMachine *TM) {
         static_cast<const LLVMTargetMachine *>(TM);
     CloneMMM->MMI = std::make_unique<MachineModuleInfo>(LLVMTM);
 
-    for (const Function &F : MMM.getModule()) {
-      if (auto *MF = MMM.MMI->getMachineFunction(F))
+    for (const Function &F : getModule()) {
+      if (auto *MF = MMI->getMachineFunction(F))
         CloneMMM->MMI->insertFunction(F, cloneMF(MF, *CloneMMM->MMI));
     }
   } else {
-    CloneMMM->M = CloneModule(*MMM.M);
+    CloneMMM->M = CloneModule(*M);
   }
   return CloneMMM;
 }
 
-bool verifyReducerWorkItem(const ReducerWorkItem &MMM, raw_fd_ostream *OS) {
-  if (verifyModule(*MMM.M, OS))
-    return true;
-
-  if (!MMM.MMI)
-    return false;
-
-  for (const Function &F : MMM.getModule()) {
-    if (const MachineFunction *MF = MMM.MMI->getMachineFunction(F)) {
-      if (!MF->verify(nullptr, "", /*AbortOnError=*/false))
-        return true;
-    }
-  }
-
-  return false;
-}
-
-void ReducerWorkItem::print(raw_ostream &ROS, void *p) const {
-  if (MMI) {
-    printMIR(ROS, *M);
-    for (Function &F : *M) {
-      if (auto *MF = MMI->getMachineFunction(F))
-        printMIR(ROS, *MF);
-    }
-  } else {
-    M->print(ROS, /*AssemblyAnnotationWriter=*/nullptr,
-             /*ShouldPreserveUseListOrder=*/true);
-  }
-}
-
 /// Try to produce some number that indicates a function is getting smaller /
 /// simpler.
 static uint64_t computeMIRComplexityScoreImpl(const MachineFunction &MF) {
@@ -731,3 +683,147 @@ uint64_t ReducerWorkItem::computeIRComplexityScore() const {
 
   return Score;
 }
+
+void ReducerWorkItem::writeOutput(raw_ostream &OS, bool EmitBitcode) const {
+  // Requesting bitcode emission with mir is nonsense, so just ignore it.
+  if (EmitBitcode && !isMIR())
+    writeBitcode(OS);
+  else
+    print(OS, /*AnnotationWriter=*/nullptr);
+}
+
+void ReducerWorkItem::readBitcode(MemoryBufferRef Data, LLVMContext &Ctx,
+                                  StringRef ToolName) {
+  Expected<BitcodeFileContents> IF = llvm::getBitcodeFileContents(Data);
+  if (!IF) {
+    WithColor::error(errs(), ToolName) << IF.takeError();
+    exit(1);
+  }
+  BitcodeModule BM = IF->Mods[0];
+  Expected<BitcodeLTOInfo> LI = BM.getLTOInfo();
+  Expected<std::unique_ptr<Module>> MOrErr = BM.parseModule(Ctx);
+  if (!LI || !MOrErr) {
+    WithColor::error(errs(), ToolName) << IF.takeError();
+    exit(1);
+  }
+  LTOInfo = std::make_unique<BitcodeLTOInfo>(*LI);
+  M = std::move(MOrErr.get());
+}
+
+void ReducerWorkItem::writeBitcode(raw_ostream &OutStream) const {
+  if (LTOInfo && LTOInfo->IsThinLTO && LTOInfo->EnableSplitLTOUnit) {
+    PassBuilder PB;
+    LoopAnalysisManager LAM;
+    FunctionAnalysisManager FAM;
+    CGSCCAnalysisManager CGAM;
+    ModuleAnalysisManager MAM;
+    PB.registerModuleAnalyses(MAM);
+    PB.registerCGSCCAnalyses(CGAM);
+    PB.registerFunctionAnalyses(FAM);
+    PB.registerLoopAnalyses(LAM);
+    PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
+    ModulePassManager MPM;
+    MPM.addPass(ThinLTOBitcodeWriterPass(OutStream, nullptr));
+    MPM.run(*M, MAM);
+  } else {
+    std::unique_ptr<ModuleSummaryIndex> Index;
+    if (LTOInfo && LTOInfo->HasSummary) {
+      ProfileSummaryInfo PSI(*M);
+      Index = std::make_unique<ModuleSummaryIndex>(
+          buildModuleSummaryIndex(*M, nullptr, &PSI));
+    }
+    WriteBitcodeToFile(getModule(), OutStream, Index.get());
+  }
+}
+
+std::pair<std::unique_ptr<ReducerWorkItem>, bool>
+llvm::parseReducerWorkItem(StringRef ToolName, StringRef Filename,
+                           LLVMContext &Ctxt,
+                           std::unique_ptr<TargetMachine> &TM, bool IsMIR) {
+  bool IsBitcode = false;
+  Triple TheTriple;
+
+  auto MMM = std::make_unique<ReducerWorkItem>();
+
+  if (IsMIR) {
+    initializeTargetInfo();
+
+    auto FileOrErr = MemoryBuffer::getFileOrSTDIN(Filename, /*IsText=*/true);
+    if (std::error_code EC = FileOrErr.getError()) {
+      WithColor::error(errs(), ToolName) << EC.message() << '\n';
+      return {nullptr, false};
+    }
+
+    std::unique_ptr<MIRParser> MParser =
+        createMIRParser(std::move(FileOrErr.get()), Ctxt);
+
+    auto SetDataLayout = [&](StringRef DataLayoutTargetTriple,
+                             StringRef OldDLStr) -> std::optional<std::string> {
+      // If we are supposed to override the target triple, do so now.
+      std::string IRTargetTriple = DataLayoutTargetTriple.str();
+      if (!TargetTriple.empty())
+        IRTargetTriple = Triple::normalize(TargetTriple);
+      TheTriple = Triple(IRTargetTriple);
+      if (TheTriple.getTriple().empty())
+        TheTriple.setTriple(sys::getDefaultTargetTriple());
+
+      std::string Error;
+      const Target *TheTarget =
+          TargetRegistry::lookupTarget(codegen::getMArch(), TheTriple, Error);
+      if (!TheTarget) {
+        WithColor::error(errs(), ToolName) << Error;
+        exit(1);
+      }
+
+      // Hopefully the MIR parsing doesn't depend on any options.
+      TargetOptions Options;
+      std::optional<Reloc::Model> RM = codegen::getExplicitRelocModel();
+      std::string CPUStr = codegen::getCPUStr();
+      std::string FeaturesStr = codegen::getFeaturesStr();
+      TM = std::unique_ptr<TargetMachine>(TheTarget->createTargetMachine(
+          TheTriple.getTriple(), CPUStr, FeaturesStr, Options, RM,
+          codegen::getExplicitCodeModel(), CodeGenOpt::Default));
+      assert(TM && "Could not allocate target machine!");
+
+      return TM->createDataLayout().getStringRepresentation();
+    };
+
+    std::unique_ptr<Module> M = MParser->parseIRModule(SetDataLayout);
+    LLVMTargetMachine *LLVMTM = static_cast<LLVMTargetMachine *>(TM.get());
+
+    MMM->MMI = std::make_unique<MachineModuleInfo>(LLVMTM);
+    MParser->parseMachineFunctions(*M, *MMM->MMI);
+    MMM->M = std::move(M);
+  } else {
+    SMDiagnostic Err;
+    ErrorOr<std::unique_ptr<MemoryBuffer>> MB =
+        MemoryBuffer::getFileOrSTDIN(Filename);
+    if (std::error_code EC = MB.getError()) {
+      WithColor::error(errs(), ToolName)
+          << Filename << ": " << EC.message() << "\n";
+      return {nullptr, false};
+    }
+
+    if (!isBitcode((const unsigned char *)(*MB)->getBufferStart(),
+                   (const unsigned char *)(*MB)->getBufferEnd())) {
+      std::unique_ptr<Module> Result = parseIRFile(Filename, Err, Ctxt);
+      if (!Result) {
+        Err.print(ToolName.data(), errs());
+        return {nullptr, false};
+      }
+      MMM->M = std::move(Result);
+    } else {
+      IsBitcode = true;
+      MMM->readBitcode(MemoryBufferRef(**MB), Ctxt, ToolName);
+
+      if (MMM->LTOInfo->IsThinLTO && MMM->LTOInfo->EnableSplitLTOUnit)
+        initializeTargetInfo();
+    }
+  }
+  if (MMM->verify(&errs())) {
+    WithColor::error(errs(), ToolName)
+        << Filename << " - input module is broken!\n";
+    return {nullptr, false};
+  }
+  return {std::move(MMM), IsBitcode};
+}
index 95c2291..dc11322 100644 (file)
@@ -15,6 +15,7 @@
 namespace llvm {
 class LLVMContext;
 class MachineModuleInfo;
+class MemoryBufferRef;
 class raw_ostream;
 class TargetMachine;
 class TestRunner;
@@ -26,6 +27,11 @@ public:
   std::unique_ptr<BitcodeLTOInfo> LTOInfo;
   std::unique_ptr<MachineModuleInfo> MMI;
 
+  ReducerWorkItem();
+  ~ReducerWorkItem();
+  ReducerWorkItem(ReducerWorkItem &) = delete;
+  ReducerWorkItem(ReducerWorkItem &&) = default;
+
   bool isMIR() const { return MMI != nullptr; }
 
   LLVMContext &getContext() {
@@ -34,36 +40,31 @@ public:
 
   Module &getModule() { return *M; }
   const Module &getModule() const { return *M; }
+  operator Module &() const { return *M; }
 
   void print(raw_ostream &ROS, void *p = nullptr) const;
-  operator Module &() const { return *M; }
+  bool verify(raw_fd_ostream *OS) const;
+  std::unique_ptr<ReducerWorkItem> clone(const TargetMachine *TM) const;
 
   /// Return a number to indicate whether there was any reduction progress.
   uint64_t getComplexityScore() const {
     return isMIR() ? computeMIRComplexityScore() : computeIRComplexityScore();
   }
 
-  ReducerWorkItem();
-  ~ReducerWorkItem();
-  ReducerWorkItem(ReducerWorkItem &) = delete;
-  ReducerWorkItem(ReducerWorkItem &&) = default;
+  void writeOutput(raw_ostream &OS, bool EmitBitcode) const;
+  void readBitcode(MemoryBufferRef Data, LLVMContext &Ctx, StringRef ToolName);
+  void writeBitcode(raw_ostream &OutStream) const;
+
+  bool isReduced(const TestRunner &Test) const;
 
 private:
   uint64_t computeIRComplexityScore() const;
   uint64_t computeMIRComplexityScore() const;
 };
-} // namespace llvm
-
-std::pair<std::unique_ptr<llvm::ReducerWorkItem>, bool>
-parseReducerWorkItem(llvm::StringRef ToolName, llvm::StringRef Filename,
-                     llvm::LLVMContext &Ctxt,
-                     std::unique_ptr<llvm::TargetMachine> &TM, bool IsMIR);
 
-std::unique_ptr<llvm::ReducerWorkItem>
-cloneReducerWorkItem(const llvm::ReducerWorkItem &MMM,
-                     const llvm::TargetMachine *TM);
-
-bool verifyReducerWorkItem(const llvm::ReducerWorkItem &MMM,
-                           llvm::raw_fd_ostream *OS);
+std::pair<std::unique_ptr<ReducerWorkItem>, bool>
+parseReducerWorkItem(StringRef ToolName, StringRef Filename, LLVMContext &Ctxt,
+                     std::unique_ptr<TargetMachine> &TM, bool IsMIR);
+} // namespace llvm
 
 #endif
index a6ecd10..8a61aae 100644 (file)
@@ -9,13 +9,7 @@
 #include "TestRunner.h"
 #include "ReducerWorkItem.h"
 #include "deltas/Utils.h"
-#include "llvm/Analysis/ModuleSummaryAnalysis.h"
-#include "llvm/Analysis/ProfileSummaryInfo.h"
-#include "llvm/Bitcode/BitcodeReader.h"
-#include "llvm/Bitcode/BitcodeWriter.h"
-#include "llvm/Passes/PassBuilder.h"
 #include "llvm/Support/WithColor.h"
-#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
 
 using namespace llvm;
 
@@ -65,37 +59,6 @@ int TestRunner::run(StringRef Filename) const {
   return !Result;
 }
 
-void TestRunner::setProgram(std::unique_ptr<ReducerWorkItem> P) {
-  assert(P && "Setting null program?");
-  Program = std::move(P);
-}
-
-void writeBitcode(const ReducerWorkItem &M, raw_ostream &OutStream) {
-  if (M.LTOInfo && M.LTOInfo->IsThinLTO && M.LTOInfo->EnableSplitLTOUnit) {
-    PassBuilder PB;
-    LoopAnalysisManager LAM;
-    FunctionAnalysisManager FAM;
-    CGSCCAnalysisManager CGAM;
-    ModuleAnalysisManager MAM;
-    PB.registerModuleAnalyses(MAM);
-    PB.registerCGSCCAnalyses(CGAM);
-    PB.registerFunctionAnalyses(FAM);
-    PB.registerLoopAnalyses(LAM);
-    PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
-    ModulePassManager MPM;
-    MPM.addPass(ThinLTOBitcodeWriterPass(OutStream, nullptr));
-    MPM.run(*M.M, MAM);
-  } else {
-    std::unique_ptr<ModuleSummaryIndex> Index;
-    if (M.LTOInfo && M.LTOInfo->HasSummary) {
-      ProfileSummaryInfo PSI(M);
-      Index = std::make_unique<ModuleSummaryIndex>(
-          buildModuleSummaryIndex(M, nullptr, &PSI));
-    }
-    WriteBitcodeToFile(M.getModule(), OutStream, Index.get());
-  }
-}
-
 void TestRunner::writeOutput(StringRef Message) {
   std::error_code EC;
   raw_fd_ostream Out(OutputFilename, EC,
@@ -106,11 +69,6 @@ void TestRunner::writeOutput(StringRef Message) {
     exit(1);
   }
 
-  // Requesting bitcode emission with mir is nonsense, so just ignore it.
-  if (EmitBitcode && !Program->isMIR())
-    writeBitcode(*Program, Out);
-  else
-    Program->print(Out, /*AnnotationWriter=*/nullptr);
-
+  Program->writeOutput(Out, EmitBitcode);
   errs() << Message << OutputFilename << '\n';
 }
index 128eede..136cd80 100644 (file)
@@ -38,7 +38,10 @@ public:
   /// Returns the most reduced version of the original testcase
   ReducerWorkItem &getProgram() const { return *Program; }
 
-  void setProgram(std::unique_ptr<ReducerWorkItem> P);
+  void setProgram(std::unique_ptr<ReducerWorkItem> &&P) {
+    assert(P && "Setting null program?");
+    Program = std::move(P);
+  }
 
   const TargetMachine *getTargetMachine() const { return TM.get(); }
 
index 0c754d6..9bdfb66 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "Delta.h"
 #include "ReducerWorkItem.h"
+#include "TestRunner.h"
 #include "Utils.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Analysis/ModuleSummaryAnalysis.h"
@@ -27,7 +28,6 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/MemoryBufferRef.h"
 #include "llvm/Support/ThreadPool.h"
-#include "llvm/Support/ToolOutputFile.h"
 #include <fstream>
 #include <set>
 
@@ -45,11 +45,6 @@ static cl::opt<unsigned int> StartingGranularityLevel(
     cl::desc("Number of times to divide chunks prior to first test"),
     cl::cat(LLVMReduceOptions));
 
-static cl::opt<bool> TmpFilesAsBitcode(
-    "write-tmp-files-as-bitcode",
-    cl::desc("Always write temporary files as bitcode instead of textual IR"),
-    cl::init(false), cl::cat(LLVMReduceOptions));
-
 #ifdef LLVM_ENABLE_THREADS
 static cl::opt<unsigned> NumJobs(
     "j",
@@ -60,45 +55,6 @@ static cl::opt<unsigned> NumJobs(
 unsigned NumJobs = 1;
 #endif
 
-void writeBitcode(const ReducerWorkItem &M, raw_ostream &OutStream);
-
-void readBitcode(ReducerWorkItem &M, MemoryBufferRef Data, LLVMContext &Ctx,
-                 StringRef ToolName);
-
-bool isReduced(const ReducerWorkItem &M, const TestRunner &Test) {
-  const bool UseBitcode = Test.inputIsBitcode() || TmpFilesAsBitcode;
-
-  SmallString<128> CurrentFilepath;
-
-  // Write ReducerWorkItem to tmp file
-  int FD;
-  std::error_code EC = sys::fs::createTemporaryFile(
-      "llvm-reduce", M.isMIR() ? "mir" : (UseBitcode ? "bc" : "ll"), FD,
-      CurrentFilepath,
-      UseBitcode && !M.isMIR() ? sys::fs::OF_None : sys::fs::OF_Text);
-  if (EC) {
-    errs() << "Error making unique filename: " << EC.message() << "!\n";
-    exit(1);
-  }
-
-  ToolOutputFile Out(CurrentFilepath, FD);
-
-  if (TmpFilesAsBitcode)
-    writeBitcode(M, Out.os());
-  else
-    M.print(Out.os(), /*AnnotationWriter=*/nullptr);
-
-  Out.os().close();
-  if (Out.os().has_error()) {
-    errs() << "Error emitting bitcode to file '" << CurrentFilepath
-           << "': " << Out.os().error().message();
-    exit(1);
-  }
-
-  // Current Chunks aren't interesting
-  return Test.run(CurrentFilepath);
-}
-
 /// Splits Chunks in half and prints them.
 /// If unable to split (when chunk size is 1) returns false.
 static bool increaseGranularity(std::vector<Chunk> &Chunks) {
@@ -157,7 +113,7 @@ CheckChunk(const Chunk ChunkToCheckForUninterestingness,
   ExtractChunksFromModule(O, *Clone);
 
   // Some reductions may result in invalid IR. Skip such reductions.
-  if (verifyReducerWorkItem(*Clone, &errs())) {
+  if (Clone->verify(&errs())) {
     if (AbortOnInvalidReduction) {
       errs() << "Invalid reduction, aborting.\n";
       Clone->print(errs());
@@ -178,7 +134,7 @@ CheckChunk(const Chunk ChunkToCheckForUninterestingness,
     errs() << "\n";
   }
 
-  if (!isReduced(*Clone, Test)) {
+  if (!Clone->isReduced(Test)) {
     // Program became non-reduced, so this chunk appears to be interesting.
     if (Verbose)
       errs() << "\n";
@@ -196,7 +152,7 @@ static SmallString<0> ProcessChunkFromSerializedBitcode(
   LLVMContext Ctx;
   auto CloneMMM = std::make_unique<ReducerWorkItem>();
   MemoryBufferRef Data(OriginalBC, "<bc file>");
-  readBitcode(*CloneMMM, Data, Ctx, Test.getToolName());
+  CloneMMM->readBitcode(Data, Ctx, Test.getToolName());
 
   SmallString<0> Result;
   if (std::unique_ptr<ReducerWorkItem> ChunkResult =
@@ -204,7 +160,7 @@ static SmallString<0> ProcessChunkFromSerializedBitcode(
                      Test, ExtractChunksFromModule, UninterestingChunks,
                      ChunksStillConsideredInteresting)) {
     raw_svector_ostream BCOS(Result);
-    writeBitcode(*ChunkResult, BCOS);
+    ChunkResult->writeBitcode(BCOS);
     // Communicate that the task reduced a chunk.
     AnyReduced = true;
   }
@@ -227,7 +183,7 @@ static void waitAndDiscardResultsBarrier(SharedTaskQueue &TaskQueue) {
 /// reduction pass where no change must be made to the module.
 void llvm::runDeltaPass(TestRunner &Test, ReductionFunc ExtractChunksFromModule,
                         StringRef Message) {
-  assert(!verifyReducerWorkItem(Test.getProgram(), &errs()) &&
+  assert(!Test.getProgram().verify(&errs()) &&
          "input module is broken before making changes");
   errs() << "*** " << Message << "...\n";
 
@@ -241,9 +197,9 @@ void llvm::runDeltaPass(TestRunner &Test, ReductionFunc ExtractChunksFromModule,
     ExtractChunksFromModule(Counter, Test.getProgram());
     Targets = Counter.count();
 
-    assert(!verifyReducerWorkItem(Test.getProgram(), &errs()) &&
+    assert(!Test.getProgram().verify(&errs()) &&
            "input module is broken after counting chunks");
-    assert(isReduced(Test.getProgram(), Test) &&
+    assert(Test.getProgram().isReduced(Test) &&
            "input module no longer interesting after counting chunks");
 
 #ifndef NDEBUG
@@ -251,7 +207,7 @@ void llvm::runDeltaPass(TestRunner &Test, ReductionFunc ExtractChunksFromModule,
     std::vector<Chunk> NoChunks = {{0, INT_MAX}};
     Oracle NoChunksCounter(NoChunks);
     std::unique_ptr<ReducerWorkItem> Clone =
-        cloneReducerWorkItem(Test.getProgram(), Test.getTargetMachine());
+      Test.getProgram().clone(Test.getTargetMachine());
     ExtractChunksFromModule(NoChunksCounter, *Clone);
     assert(Targets == NoChunksCounter.count() &&
            "number of chunks changes when reducing");
@@ -288,7 +244,7 @@ void llvm::runDeltaPass(TestRunner &Test, ReductionFunc ExtractChunksFromModule,
     SmallString<0> OriginalBC;
     if (NumJobs > 1) {
       raw_svector_ostream BCOS(OriginalBC);
-      writeBitcode(Test.getProgram(), BCOS);
+      Test.getProgram().writeBitcode(BCOS);
     }
 
     SharedTaskQueue TaskQueue;
@@ -351,8 +307,8 @@ void llvm::runDeltaPass(TestRunner &Test, ReductionFunc ExtractChunksFromModule,
 
           Result = std::make_unique<ReducerWorkItem>();
           MemoryBufferRef Data(StringRef(Res), "<bc file>");
-          readBitcode(*Result, Data, Test.getProgram().M->getContext(),
-                      Test.getToolName());
+          Result->readBitcode(Data, Test.getProgram().M->getContext(),
+                              Test.getToolName());
           break;
         }
 
@@ -366,11 +322,10 @@ void llvm::runDeltaPass(TestRunner &Test, ReductionFunc ExtractChunksFromModule,
         // Forward I to the last chunk processed in parallel.
         I += NumChunksProcessed - 1;
       } else {
-        Result = CheckChunk(
-            *I,
-            cloneReducerWorkItem(Test.getProgram(), Test.getTargetMachine()),
-            Test, ExtractChunksFromModule, UninterestingChunks,
-            ChunksStillConsideredInteresting);
+        Result =
+            CheckChunk(*I, Test.getProgram().clone(Test.getTargetMachine()),
+                       Test, ExtractChunksFromModule, UninterestingChunks,
+                       ChunksStillConsideredInteresting);
       }
 
       if (!Result)
index fde1b88..5b60ea6 100644 (file)
 #ifndef LLVM_TOOLS_LLVM_REDUCE_DELTAS_DELTA_H
 #define LLVM_TOOLS_LLVM_REDUCE_DELTAS_DELTA_H
 
-#include "TestRunner.h"
+#include "ReducerWorkItem.h"
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/ScopeExit.h"
+#include "llvm/Support/raw_ostream.h"
 #include <functional>
 #include <utility>
 #include <vector>
 
 namespace llvm {
 
+class TestRunner;
+
 struct Chunk {
   int Begin;
   int End;
index 094cbe3..ace5c95 100644 (file)
@@ -103,8 +103,6 @@ static cl::opt<int>
 
 static codegen::RegisterCodeGenFlags CGF;
 
-bool isReduced(const ReducerWorkItem &M, const TestRunner &Test);
-
 /// Turn off crash debugging features
 ///
 /// Crash is expected, so disable crash reports and symbolization to reduce
@@ -139,24 +137,6 @@ static std::pair<StringRef, bool> determineOutputType(bool IsMIR,
   return {OutputFilename, OutputBitcode};
 }
 
-void readBitcode(ReducerWorkItem &M, MemoryBufferRef Data, LLVMContext &Ctx,
-                 StringRef ToolName) {
-  Expected<BitcodeFileContents> IF = llvm::getBitcodeFileContents(Data);
-  if (!IF) {
-    WithColor::error(errs(), ToolName) << IF.takeError();
-    exit(1);
-  }
-  BitcodeModule BM = IF->Mods[0];
-  Expected<BitcodeLTOInfo> LI = BM.getLTOInfo();
-  Expected<std::unique_ptr<Module>> MOrErr = BM.parseModule(Ctx);
-  if (!LI || !MOrErr) {
-    WithColor::error(errs(), ToolName) << IF.takeError();
-    exit(1);
-  }
-  M.LTOInfo = std::make_unique<BitcodeLTOInfo>(*LI);
-  M.M = std::move(MOrErr.get());
-}
-
 int main(int Argc, char **Argv) {
   InitLLVM X(Argc, Argv);
   const StringRef ToolName(Argv[0]);
@@ -219,7 +199,7 @@ int main(int Argc, char **Argv) {
   // test, rather than evaluating the source IR directly. This is for the
   // convenience of lit tests; the stripped out comments may have broken the
   // interestingness checks.
-  if (!isReduced(Tester.getProgram(), Tester)) {
+  if (!Tester.getProgram().isReduced(Tester)) {
     errs() << "\nInput isn't interesting! Verify interesting-ness test\n";
     return 1;
   }