[llvm] [Instrumentation] Support MachineFunction in ChangeReporter (PR #80946)

via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 8 02:32:18 PST 2024


https://github.com/paperchalice updated https://github.com/llvm/llvm-project/pull/80946

>From 6a3d14fe2ec27b31a622e719d6a8db61c57c5ce5 Mon Sep 17 00:00:00 2001
From: PaperChalice <liujunchang97 at outlook.com>
Date: Wed, 7 Feb 2024 15:09:38 +0800
Subject: [PATCH 1/3] [Instrumentation] Support MachineFunction in
 ChangeReporter

---
 .../llvm/Passes/StandardInstrumentations.h    |  22 ++-
 llvm/lib/CodeGen/MachinePassManager.cpp       |   4 +-
 llvm/lib/Passes/StandardInstrumentations.cpp  | 129 ++++++++++++++--
 .../DotCfg/print-changed-dot-cfg.mir          | 138 ++++++++++++++++++
 llvm/test/Other/change-printer.mir            | 112 ++++++++++++++
 5 files changed, 392 insertions(+), 13 deletions(-)
 create mode 100644 llvm/test/Other/ChangePrinters/DotCfg/print-changed-dot-cfg.mir
 create mode 100644 llvm/test/Other/change-printer.mir

diff --git a/llvm/include/llvm/Passes/StandardInstrumentations.h b/llvm/include/llvm/Passes/StandardInstrumentations.h
index 8c6a44876d5459..daf8c10102626e 100644
--- a/llvm/include/llvm/Passes/StandardInstrumentations.h
+++ b/llvm/include/llvm/Passes/StandardInstrumentations.h
@@ -18,6 +18,7 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/OptBisect.h"
 #include "llvm/IR/PassTimingInfo.h"
@@ -33,6 +34,7 @@ namespace llvm {
 
 class Module;
 class Function;
+class MachineFunction;
 class PassInstrumentationCallbacks;
 
 /// Instrumentation to print IR before/after passes.
@@ -209,6 +211,8 @@ template <typename IRUnitT> class ChangeReporter {
 
   // Called on the first IR processed.
   virtual void handleInitialIR(Any IR) = 0;
+  // Called on the first MIR processed.
+  virtual void handleInitialMIR(const MachineFunction *IR) = 0;
   // Called before and after a pass to get the representation of the IR.
   virtual void generateIRRepresentation(Any IR, StringRef PassID,
                                         IRUnitT &Output) = 0;
@@ -229,6 +233,8 @@ template <typename IRUnitT> class ChangeReporter {
   std::vector<IRUnitT> BeforeStack;
   // Is this the first IR seen?
   bool InitialIR = true;
+  // Is this the first MIR seen?
+  bool InitialMIR = true;
 
   // Run in verbose mode, printing everything?
   const bool VerboseMode;
@@ -243,6 +249,8 @@ class TextChangeReporter : public ChangeReporter<IRUnitT> {
 
   // Print a module dump of the first IR that is changed.
   void handleInitialIR(Any IR) override;
+  // Print a module dump of the first MIR that is changed.
+  void handleInitialMIR(const MachineFunction *IR) override;
   // Report that the IR was omitted because it did not change.
   void omitAfter(StringRef PassID, std::string &Name) override;
   // Report that the pass was invalidated.
@@ -289,6 +297,8 @@ class IRChangedTester : public IRChangedPrinter {
 
   // Check initial IR
   void handleInitialIR(Any IR) override;
+  // Check initial MIR
+  void handleInitialMIR(const MachineFunction *IR) override;
   // Do nothing.
   void omitAfter(StringRef PassID, std::string &Name) override;
   // Do nothing.
@@ -313,6 +323,11 @@ template <typename T> class BlockDataT {
     B.print(SS, nullptr, true, true);
   }
 
+  BlockDataT(const MachineBasicBlock &B) : Label(B.getName().str()), Data(B) {
+    raw_string_ostream SS(Body);
+    B.print(SS);
+  }
+
   bool operator==(const BlockDataT &That) const { return Body == That.Body; }
   bool operator!=(const BlockDataT &That) const { return Body != That.Body; }
 
@@ -364,6 +379,7 @@ template <typename T> class OrderedChangedData {
 class EmptyData {
 public:
   EmptyData(const BasicBlock &) {}
+  EmptyData(const MachineBasicBlock &) {}
 };
 
 // The data saved for comparing functions.
@@ -405,7 +421,8 @@ template <typename T> class IRComparer {
 
 protected:
   // Generate the data for \p F into \p Data.
-  static bool generateFunctionData(IRDataT<T> &Data, const Function &F);
+  template <typename FunctionT>
+  static bool generateFunctionData(IRDataT<T> &Data, const FunctionT &F);
 
   const IRDataT<T> &Before;
   const IRDataT<T> &After;
@@ -475,6 +492,7 @@ class DCData {
 public:
   // Fill the map with the transitions from basic block \p B.
   DCData(const BasicBlock &B);
+  DCData(const MachineBasicBlock &B);
 
   // Return an iterator to the names of the successor blocks.
   StringMap<std::string>::const_iterator begin() const {
@@ -514,6 +532,8 @@ class DotCfgChangeReporter : public ChangeReporter<IRDataT<DCData>> {
 
   // Called on the first IR processed.
   void handleInitialIR(Any IR) override;
+  // Called on the first MIR processed.
+  void handleInitialMIR(const MachineFunction *IR) override;
   // Called before and after a pass to get the representation of the IR.
   void generateIRRepresentation(Any IR, StringRef PassID,
                                 IRDataT<DCData> &Output) override;
diff --git a/llvm/lib/CodeGen/MachinePassManager.cpp b/llvm/lib/CodeGen/MachinePassManager.cpp
index 0770eba660b45d..d4a00764b715f8 100644
--- a/llvm/lib/CodeGen/MachinePassManager.cpp
+++ b/llvm/lib/CodeGen/MachinePassManager.cpp
@@ -90,7 +90,9 @@ Error MachineFunctionPassManager::run(Module &M,
       for (unsigned I = Begin, E = Idx; I != E; ++I) {
         auto *P = Passes[I].get();
 
-        if (!PI.runBeforePass<MachineFunction>(*P, MF))
+        // Keep BeforeStack empty in ChangeReporter
+        if (P->name() != FreeMachineFunctionPass::name() &&
+            !PI.runBeforePass<MachineFunction>(*P, MF))
           continue;
 
         // TODO: EmitSizeRemarks
diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp
index 697988b3fc7c0b..c90850ce195716 100644
--- a/llvm/lib/Passes/StandardInstrumentations.cpp
+++ b/llvm/lib/Passes/StandardInstrumentations.cpp
@@ -20,6 +20,7 @@
 #include "llvm/Analysis/LazyCallGraph.h"
 #include "llvm/Analysis/LoopInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/Module.h"
@@ -180,6 +181,12 @@ const Module *unwrapModule(Any IR, bool Force = false) {
     return F->getParent();
   }
 
+  if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
+    if (!Force && !isFunctionInPrintList(MF->getName()))
+      return nullptr;
+    return MF->getFunction().getParent();
+  }
+
   llvm_unreachable("Unknown IR unit");
 }
 
@@ -215,6 +222,12 @@ void printIR(raw_ostream &OS, const Loop *L) {
   printLoop(const_cast<Loop &>(*L), OS);
 }
 
+void printIR(raw_ostream &OS, const MachineFunction *MF) {
+  if (!isFunctionInPrintList(MF->getName()))
+    return;
+  MF->print(OS);
+}
+
 std::string getIRName(Any IR) {
   if (unwrapIR<Module>(IR))
     return "[module]";
@@ -262,6 +275,9 @@ bool shouldPrintIR(Any IR) {
 
   if (const auto *L = unwrapIR<Loop>(IR))
     return isFunctionInPrintList(L->getHeader()->getParent()->getName());
+
+  if (const auto *MF = unwrapIR<MachineFunction>(IR))
+    return isFunctionInPrintList(MF->getName());
   llvm_unreachable("Unknown wrapped IR type");
 }
 
@@ -297,6 +313,11 @@ void unwrapAndPrint(raw_ostream &OS, Any IR) {
     printIR(OS, L);
     return;
   }
+
+  if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
+    printIR(OS, MF);
+    return;
+  }
   llvm_unreachable("Unknown wrapped IR type");
 }
 
@@ -305,7 +326,8 @@ bool isIgnored(StringRef PassID) {
   return isSpecialPass(PassID,
                        {"PassManager", "PassAdaptor", "AnalysisManagerProxy",
                         "DevirtSCCRepeatedPass", "ModuleInlinerWrapperPass",
-                        "VerifierPass", "PrintModulePass"});
+                        "VerifierPass", "PrintModulePass", "PrintMIRPass",
+                        "PrintMIRPreparePass"});
 }
 
 std::string makeHTMLReady(StringRef SR) {
@@ -362,6 +384,14 @@ void ChangeReporter<T>::saveIRBeforePass(Any IR, StringRef PassID,
       handleInitialIR(IR);
   }
 
+  if (InitialMIR) {
+    if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
+      InitialMIR = false;
+      if (VerboseMode)
+        handleInitialMIR(MF);
+    }
+  }
+
   // Always need to place something on the stack because invalidated passes
   // are not given the IR so it cannot be determined whether the pass was for
   // something that was filtered out.
@@ -448,6 +478,17 @@ template <typename T> void TextChangeReporter<T>::handleInitialIR(Any IR) {
   M->print(Out, nullptr);
 }
 
+template <typename T>
+void TextChangeReporter<T>::handleInitialMIR(const MachineFunction *IR) {
+  // Print all available machine functions.
+  const auto &MMI = IR->getMMI();
+  const auto &M = *MMI.getModule();
+  Out << "*** MIR Dump At Start ***\n";
+  for (const Function &F : M)
+    if (auto *MF = MMI.getMachineFunction(F))
+      MF->print(Out);
+}
+
 template <typename T>
 void TextChangeReporter<T>::omitAfter(StringRef PassID, std::string &Name) {
   Out << formatv("*** IR Dump After {0} on {1} omitted because no change ***\n",
@@ -546,6 +587,12 @@ void IRChangedTester::handleInitialIR(Any IR) {
   handleIR(S, "Initial IR");
 }
 
+void IRChangedTester::handleInitialMIR(const MachineFunction *IR) {
+  std::string S;
+  generateIRRepresentation(IR, "Initial MIR", S);
+  handleIR(S, "Initial MIR");
+}
+
 void IRChangedTester::omitAfter(StringRef PassID, std::string &Name) {}
 void IRChangedTester::handleInvalidated(StringRef PassID) {}
 void IRChangedTester::handleFiltered(StringRef PassID, std::string &Name) {}
@@ -664,20 +711,38 @@ template <typename T> void IRComparer<T>::analyzeIR(Any IR, IRDataT<T> &Data) {
     return;
   }
 
-  const auto *F = unwrapIR<Function>(IR);
-  if (!F) {
-    const auto *L = unwrapIR<Loop>(IR);
-    assert(L && "Unknown IR unit.");
-    F = L->getHeader()->getParent();
+  if (const auto *F = unwrapIR<Function>(IR)) {
+    generateFunctionData(Data, *F);
+    return;
+  }
+
+  if (const auto *L = unwrapIR<Loop>(IR)) {
+    auto *F = L->getHeader()->getParent();
+    generateFunctionData(Data, *F);
+    return;
   }
-  assert(F && "Unknown IR unit.");
-  generateFunctionData(Data, *F);
+
+  if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
+    generateFunctionData(Data, *MF);
+    return;
+  }
+
+  llvm_unreachable("Unknown IR unit");
+}
+
+static bool shouldGenerateData(const Function &F) {
+  return !F.isDeclaration() && isFunctionInPrintList(F.getName());
+}
+
+static bool shouldGenerateData(const MachineFunction &MF) {
+  return isFunctionInPrintList(MF.getName());
 }
 
 template <typename T>
-bool IRComparer<T>::generateFunctionData(IRDataT<T> &Data, const Function &F) {
-  if (!F.isDeclaration() && isFunctionInPrintList(F.getName())) {
-    FuncDataT<T> FD(F.getEntryBlock().getName().str());
+template <typename FunctionT>
+bool IRComparer<T>::generateFunctionData(IRDataT<T> &Data, const FunctionT &F) {
+  if (shouldGenerateData(F)) {
+    FuncDataT<T> FD(F.front().getName().str());
     int I = 0;
     for (const auto &B : F) {
       std::string BBName = B.getName().str();
@@ -722,6 +787,12 @@ static SmallString<32> getIRFileDisplayName(Any IR) {
     ResultStream << "-loop-";
     stable_hash LoopNameHash = stable_hash_combine_string(L->getName());
     write_hex(ResultStream, LoopNameHash, HexPrintStyle::Lower, MaxHashWidth);
+  } else if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
+    ResultStream << "-machine-function-";
+    stable_hash MachineFunctionNameHash =
+        stable_hash_combine_string(MF->getName());
+    write_hex(ResultStream, MachineFunctionNameHash, HexPrintStyle::Lower,
+              MaxHashWidth);
   } else {
     llvm_unreachable("Unknown wrapped IR type");
   }
@@ -2122,6 +2193,11 @@ DCData::DCData(const BasicBlock &B) {
       addSuccessorLabel(Succ->getName().str(), "");
 }
 
+DCData::DCData(const MachineBasicBlock &B) {
+  for (const MachineBasicBlock *Succ : successors(&B))
+    addSuccessorLabel(Succ->getName().str(), "");
+}
+
 DotCfgChangeReporter::DotCfgChangeReporter(bool Verbose)
     : ChangeReporter<IRDataT<DCData>>(Verbose) {}
 
@@ -2210,6 +2286,37 @@ void DotCfgChangeReporter::handleInitialIR(Any IR) {
   ++N;
 }
 
+void DotCfgChangeReporter::handleInitialMIR(const MachineFunction *IR) {
+  assert(HTML && "Expected outstream to be set");
+  *HTML << "<button type=\"button\" class=\"collapsible\">0. "
+        << "Initial MIR (by machine function)</button>\n"
+        << "<div class=\"content\">\n"
+        << "  <p>\n";
+
+  auto &MMI = IR->getMMI();
+  const auto *M = MMI.getModule();
+  for (const auto &F : *M) {
+    if (const auto *MF = MMI.getMachineFunction(F)) {
+      // Create representation of IR
+      IRDataT<DCData> Data;
+      IRComparer<DCData>::analyzeIR(llvm::Any(MF), Data);
+      // Now compare it against itself, which will have everything the
+      // same and will generate the files.
+      IRComparer<DCData>(Data, Data)
+          .compare(getModuleForComparison(IR),
+                   [&](bool InModule, unsigned Minor,
+                       const FuncDataT<DCData> &Before,
+                       const FuncDataT<DCData> &After) -> void {
+                     handleFunctionCompare("", " ", "Initial MIR", "", InModule,
+                                           Minor, Before, After);
+                   });
+      ++N;
+    }
+  }
+  *HTML << "  </p>\n"
+        << "</div><br/>\n";
+}
+
 void DotCfgChangeReporter::generateIRRepresentation(Any IR, StringRef PassID,
                                                     IRDataT<DCData> &Data) {
   IRComparer<DCData>::analyzeIR(IR, Data);
diff --git a/llvm/test/Other/ChangePrinters/DotCfg/print-changed-dot-cfg.mir b/llvm/test/Other/ChangePrinters/DotCfg/print-changed-dot-cfg.mir
new file mode 100644
index 00000000000000..c7edd29a6107b7
--- /dev/null
+++ b/llvm/test/Other/ChangePrinters/DotCfg/print-changed-dot-cfg.mir
@@ -0,0 +1,138 @@
+# REQUIRES: x86-registered-target
+# Simple functionality check.
+# RUN: rm -rf %t && mkdir -p %t
+# RUN: llc -filetype=null -print-changed=dot-cfg -passes=no-op-machine-function -dot-cfg-dir=%t %s
+# RUN: ls %t/*.pdf %t/passes.html | count 5
+
+--- |
+  ; ModuleID = './print-changed-dot-cfg.ll'
+  source_filename = "./print-changed-dot-cfg.ll"
+  target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+  
+  define i32 @g() {
+  entry:
+    %a = add i32 2, 3
+    ret i32 %a
+  }
+  
+  define i32 @f() {
+  entry:
+    %a = add i32 2, 5
+    ret i32 %a
+  }
+
+...
+---
+name:            g
+alignment:       16
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+failedISel:      false
+tracksRegLiveness: true
+hasWinCFI:       false
+callsEHReturn:   false
+callsUnwindInit: false
+hasEHCatchret:   false
+hasEHScopes:     false
+hasEHFunclets:   false
+isOutlined:      false
+debugInstrRef:   true
+failsVerification: false
+tracksDebugUserValues: false
+registers:
+  - { id: 0, class: gr32, preferred-register: '' }
+liveins:         []
+frameInfo:
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    1
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  functionContext: ''
+  maxCallFrameSize: 4294967295
+  cvBytesOfCalleeSavedRegisters: 0
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  hasTailCall:     false
+  localFrameSize:  0
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      []
+stack:           []
+entry_values:    []
+callSites:       []
+debugValueSubstitutions: []
+constants:       []
+machineFunctionInfo: {}
+body:             |
+  bb.0.entry:
+    %0:gr32 = MOV32ri 5
+    $eax = COPY %0
+    RET 0, $eax
+
+...
+---
+name:            f
+alignment:       16
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+failedISel:      false
+tracksRegLiveness: true
+hasWinCFI:       false
+callsEHReturn:   false
+callsUnwindInit: false
+hasEHCatchret:   false
+hasEHScopes:     false
+hasEHFunclets:   false
+isOutlined:      false
+debugInstrRef:   true
+failsVerification: false
+tracksDebugUserValues: false
+registers:
+  - { id: 0, class: gr32, preferred-register: '' }
+liveins:         []
+frameInfo:
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    1
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  functionContext: ''
+  maxCallFrameSize: 4294967295
+  cvBytesOfCalleeSavedRegisters: 0
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  hasTailCall:     false
+  localFrameSize:  0
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      []
+stack:           []
+entry_values:    []
+callSites:       []
+debugValueSubstitutions: []
+constants:       []
+machineFunctionInfo: {}
+body:             |
+  bb.0.entry:
+    %0:gr32 = MOV32ri 7
+    $eax = COPY %0
+    RET 0, $eax
+
+...
diff --git a/llvm/test/Other/change-printer.mir b/llvm/test/Other/change-printer.mir
new file mode 100644
index 00000000000000..8b6dfe515c18b1
--- /dev/null
+++ b/llvm/test/Other/change-printer.mir
@@ -0,0 +1,112 @@
+# REQUIRES: x86-registered-target
+# RUN: llc -mtriple=x86_64-unknown-linux-gnu -filetype=null %s \
+# RUN: -p no-op-machine-function -print-changed 2>&1 | FileCheck %s --check-prefix=CHECK-NO-OP
+
+# RUN: llc -mtriple=x86_64-unknown-linux-gnu -filetype=null %s \
+# RUN: -p dead-mi-elimination -print-changed 2>&1 | FileCheck %s --check-prefix=CHECK-SIMPLE
+
+--- |
+  ; ModuleID = 'main.ll'
+  source_filename = "main.cpp"
+  target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+  target triple = "x86_64-unknown-linux-gnu"
+  
+  define noundef i32 @_Z4testv() {
+  0:
+    %1 = alloca i32, align 4
+    %2 = alloca i32, align 4
+    %3 = alloca i32, align 4
+    store i32 0, ptr %1, align 4
+    store i32 1, ptr %2, align 4
+    %4 = load i32, ptr %1, align 4
+    %5 = load i32, ptr %2, align 4
+    %6 = add nsw i32 %4, %5
+    store i32 %6, ptr %3, align 4
+    %7 = load i32, ptr %3, align 4
+    ret i32 %7
+  }
+...
+---
+name:            _Z4testv
+alignment:       16
+exposesReturnsTwice: false
+legalized:       false
+regBankSelected: false
+selected:        false
+failedISel:      false
+tracksRegLiveness: true
+hasWinCFI:       false
+callsEHReturn:   false
+callsUnwindInit: false
+hasEHCatchret:   false
+hasEHScopes:     false
+hasEHFunclets:   false
+isOutlined:      false
+debugInstrRef:   false
+failsVerification: false
+tracksDebugUserValues: false
+registers:
+  - { id: 0, class: gr32, preferred-register: '' }
+  - { id: 1, class: gr32, preferred-register: '' }
+  - { id: 2, class: gr32, preferred-register: '' }
+  - { id: 3, class: gr32, preferred-register: '' }
+  - { id: 4, class: gr32, preferred-register: '' }
+  - { id: 5, class: gr32, preferred-register: '' }
+  - { id: 6, class: gr32, preferred-register: '' }
+  - { id: 7, class: gr32, preferred-register: '' }
+liveins:         []
+frameInfo:
+  isFrameAddressTaken: false
+  isReturnAddressTaken: false
+  hasStackMap:     false
+  hasPatchPoint:   false
+  stackSize:       0
+  offsetAdjustment: 0
+  maxAlignment:    4
+  adjustsStack:    false
+  hasCalls:        false
+  stackProtector:  ''
+  functionContext: ''
+  maxCallFrameSize: 4294967295
+  cvBytesOfCalleeSavedRegisters: 0
+  hasOpaqueSPAdjustment: false
+  hasVAStart:      false
+  hasMustTailInVarArgFunc: false
+  hasTailCall:     false
+  localFrameSize:  0
+  savePoint:       ''
+  restorePoint:    ''
+fixedStack:      []
+stack:
+  - { id: 0, name: '', type: default, offset: 0, size: 4, alignment: 4, 
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 1, name: '', type: default, offset: 0, size: 4, alignment: 4, 
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+  - { id: 2, name: '', type: default, offset: 0, size: 4, alignment: 4, 
+      stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
+      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
+entry_values:    []
+callSites:       []
+debugValueSubstitutions: []
+constants:       []
+machineFunctionInfo: {}
+body:             |
+  bb.0 (%ir-block.0):
+    MOV32mi %stack.0, 1, $noreg, 0, $noreg, 0 :: (store (s32) into %ir.1)
+    MOV32mi %stack.1, 1, $noreg, 0, $noreg, 1 :: (store (s32) into %ir.2)
+    %6:gr32 = MOV32rm %stack.0, 1, $noreg, 0, $noreg :: (load (s32) from %ir.1)
+    %5:gr32 = ADD32rm %6, %stack.1, 1, $noreg, 0, $noreg, implicit-def $eflags :: (load (s32) from %ir.2)
+    MOV32mr %stack.2, 1, $noreg, 0, $noreg, %5 :: (store (s32) into %ir.3)
+    %1:gr32 = MOV32rm %stack.2, 1, $noreg, 0, $noreg :: (load (s32) from %ir.3)
+    %7:gr32 = MOV32rm %stack.0, 1, $noreg, 0, $noreg :: (load (s32) from %ir.1)
+    $eax = COPY %1
+    RET64 implicit $eax
+
+...
+
+# CHECK-NO-OP: *** IR Dump After NoOpMachineFunctionPass on _Z4testv omitted because no change ***
+
+# CHECK-SIMPLE: *** IR Dump After DeadMachineInstructionElimPass on _Z4testv ***
+# CHECK-SIMPLE-NOT: %7:gr32 = MOV32rm %stack.0, 1, $noreg, 0, $noreg :: (load (s32) from %ir.1)

>From bcccf41aee448603cd19e3be8f568597c4c6e2b8 Mon Sep 17 00:00:00 2001
From: PaperChalice <liujunchang97 at outlook.com>
Date: Wed, 7 Feb 2024 16:50:33 +0800
Subject: [PATCH 2/3] simplify test case

---
 .../DotCfg/print-changed-dot-cfg.mir          | 114 ------------------
 llvm/test/Other/change-printer.mir            | 105 ++--------------
 2 files changed, 7 insertions(+), 212 deletions(-)

diff --git a/llvm/test/Other/ChangePrinters/DotCfg/print-changed-dot-cfg.mir b/llvm/test/Other/ChangePrinters/DotCfg/print-changed-dot-cfg.mir
index c7edd29a6107b7..8fdd661f6c5b3f 100644
--- a/llvm/test/Other/ChangePrinters/DotCfg/print-changed-dot-cfg.mir
+++ b/llvm/test/Other/ChangePrinters/DotCfg/print-changed-dot-cfg.mir
@@ -4,74 +4,8 @@
 # RUN: llc -filetype=null -print-changed=dot-cfg -passes=no-op-machine-function -dot-cfg-dir=%t %s
 # RUN: ls %t/*.pdf %t/passes.html | count 5
 
---- |
-  ; ModuleID = './print-changed-dot-cfg.ll'
-  source_filename = "./print-changed-dot-cfg.ll"
-  target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
-  
-  define i32 @g() {
-  entry:
-    %a = add i32 2, 3
-    ret i32 %a
-  }
-  
-  define i32 @f() {
-  entry:
-    %a = add i32 2, 5
-    ret i32 %a
-  }
-
-...
 ---
 name:            g
-alignment:       16
-exposesReturnsTwice: false
-legalized:       false
-regBankSelected: false
-selected:        false
-failedISel:      false
-tracksRegLiveness: true
-hasWinCFI:       false
-callsEHReturn:   false
-callsUnwindInit: false
-hasEHCatchret:   false
-hasEHScopes:     false
-hasEHFunclets:   false
-isOutlined:      false
-debugInstrRef:   true
-failsVerification: false
-tracksDebugUserValues: false
-registers:
-  - { id: 0, class: gr32, preferred-register: '' }
-liveins:         []
-frameInfo:
-  isFrameAddressTaken: false
-  isReturnAddressTaken: false
-  hasStackMap:     false
-  hasPatchPoint:   false
-  stackSize:       0
-  offsetAdjustment: 0
-  maxAlignment:    1
-  adjustsStack:    false
-  hasCalls:        false
-  stackProtector:  ''
-  functionContext: ''
-  maxCallFrameSize: 4294967295
-  cvBytesOfCalleeSavedRegisters: 0
-  hasOpaqueSPAdjustment: false
-  hasVAStart:      false
-  hasMustTailInVarArgFunc: false
-  hasTailCall:     false
-  localFrameSize:  0
-  savePoint:       ''
-  restorePoint:    ''
-fixedStack:      []
-stack:           []
-entry_values:    []
-callSites:       []
-debugValueSubstitutions: []
-constants:       []
-machineFunctionInfo: {}
 body:             |
   bb.0.entry:
     %0:gr32 = MOV32ri 5
@@ -81,54 +15,6 @@ body:             |
 ...
 ---
 name:            f
-alignment:       16
-exposesReturnsTwice: false
-legalized:       false
-regBankSelected: false
-selected:        false
-failedISel:      false
-tracksRegLiveness: true
-hasWinCFI:       false
-callsEHReturn:   false
-callsUnwindInit: false
-hasEHCatchret:   false
-hasEHScopes:     false
-hasEHFunclets:   false
-isOutlined:      false
-debugInstrRef:   true
-failsVerification: false
-tracksDebugUserValues: false
-registers:
-  - { id: 0, class: gr32, preferred-register: '' }
-liveins:         []
-frameInfo:
-  isFrameAddressTaken: false
-  isReturnAddressTaken: false
-  hasStackMap:     false
-  hasPatchPoint:   false
-  stackSize:       0
-  offsetAdjustment: 0
-  maxAlignment:    1
-  adjustsStack:    false
-  hasCalls:        false
-  stackProtector:  ''
-  functionContext: ''
-  maxCallFrameSize: 4294967295
-  cvBytesOfCalleeSavedRegisters: 0
-  hasOpaqueSPAdjustment: false
-  hasVAStart:      false
-  hasMustTailInVarArgFunc: false
-  hasTailCall:     false
-  localFrameSize:  0
-  savePoint:       ''
-  restorePoint:    ''
-fixedStack:      []
-stack:           []
-entry_values:    []
-callSites:       []
-debugValueSubstitutions: []
-constants:       []
-machineFunctionInfo: {}
 body:             |
   bb.0.entry:
     %0:gr32 = MOV32ri 7
diff --git a/llvm/test/Other/change-printer.mir b/llvm/test/Other/change-printer.mir
index 8b6dfe515c18b1..5e57da50e625dc 100644
--- a/llvm/test/Other/change-printer.mir
+++ b/llvm/test/Other/change-printer.mir
@@ -5,108 +5,17 @@
 # RUN: llc -mtriple=x86_64-unknown-linux-gnu -filetype=null %s \
 # RUN: -p dead-mi-elimination -print-changed 2>&1 | FileCheck %s --check-prefix=CHECK-SIMPLE
 
---- |
-  ; ModuleID = 'main.ll'
-  source_filename = "main.cpp"
-  target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
-  target triple = "x86_64-unknown-linux-gnu"
-  
-  define noundef i32 @_Z4testv() {
-  0:
-    %1 = alloca i32, align 4
-    %2 = alloca i32, align 4
-    %3 = alloca i32, align 4
-    store i32 0, ptr %1, align 4
-    store i32 1, ptr %2, align 4
-    %4 = load i32, ptr %1, align 4
-    %5 = load i32, ptr %2, align 4
-    %6 = add nsw i32 %4, %5
-    store i32 %6, ptr %3, align 4
-    %7 = load i32, ptr %3, align 4
-    ret i32 %7
-  }
-...
 ---
-name:            _Z4testv
-alignment:       16
-exposesReturnsTwice: false
-legalized:       false
-regBankSelected: false
-selected:        false
-failedISel:      false
-tracksRegLiveness: true
-hasWinCFI:       false
-callsEHReturn:   false
-callsUnwindInit: false
-hasEHCatchret:   false
-hasEHScopes:     false
-hasEHFunclets:   false
-isOutlined:      false
-debugInstrRef:   false
-failsVerification: false
-tracksDebugUserValues: false
-registers:
-  - { id: 0, class: gr32, preferred-register: '' }
-  - { id: 1, class: gr32, preferred-register: '' }
-  - { id: 2, class: gr32, preferred-register: '' }
-  - { id: 3, class: gr32, preferred-register: '' }
-  - { id: 4, class: gr32, preferred-register: '' }
-  - { id: 5, class: gr32, preferred-register: '' }
-  - { id: 6, class: gr32, preferred-register: '' }
-  - { id: 7, class: gr32, preferred-register: '' }
-liveins:         []
-frameInfo:
-  isFrameAddressTaken: false
-  isReturnAddressTaken: false
-  hasStackMap:     false
-  hasPatchPoint:   false
-  stackSize:       0
-  offsetAdjustment: 0
-  maxAlignment:    4
-  adjustsStack:    false
-  hasCalls:        false
-  stackProtector:  ''
-  functionContext: ''
-  maxCallFrameSize: 4294967295
-  cvBytesOfCalleeSavedRegisters: 0
-  hasOpaqueSPAdjustment: false
-  hasVAStart:      false
-  hasMustTailInVarArgFunc: false
-  hasTailCall:     false
-  localFrameSize:  0
-  savePoint:       ''
-  restorePoint:    ''
-fixedStack:      []
-stack:
-  - { id: 0, name: '', type: default, offset: 0, size: 4, alignment: 4, 
-      stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
-      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
-  - { id: 1, name: '', type: default, offset: 0, size: 4, alignment: 4, 
-      stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
-      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
-  - { id: 2, name: '', type: default, offset: 0, size: 4, alignment: 4, 
-      stack-id: default, callee-saved-register: '', callee-saved-restored: true, 
-      debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
-entry_values:    []
-callSites:       []
-debugValueSubstitutions: []
-constants:       []
-machineFunctionInfo: {}
+name:            test
 body:             |
-  bb.0 (%ir-block.0):
-    MOV32mi %stack.0, 1, $noreg, 0, $noreg, 0 :: (store (s32) into %ir.1)
-    MOV32mi %stack.1, 1, $noreg, 0, $noreg, 1 :: (store (s32) into %ir.2)
-    %6:gr32 = MOV32rm %stack.0, 1, $noreg, 0, $noreg :: (load (s32) from %ir.1)
-    %5:gr32 = ADD32rm %6, %stack.1, 1, $noreg, 0, $noreg, implicit-def $eflags :: (load (s32) from %ir.2)
-    MOV32mr %stack.2, 1, $noreg, 0, $noreg, %5 :: (store (s32) into %ir.3)
-    %1:gr32 = MOV32rm %stack.2, 1, $noreg, 0, $noreg :: (load (s32) from %ir.3)
-    %7:gr32 = MOV32rm %stack.0, 1, $noreg, 0, $noreg :: (load (s32) from %ir.1)
+  bb.0:
+    %1:gr64 = MOV64ri 0
+    %2:gr64 = MOV64ri 0
     $eax = COPY %1
     RET64 implicit $eax
-
 ...
 
-# CHECK-NO-OP: *** IR Dump After NoOpMachineFunctionPass on _Z4testv omitted because no change ***
+# CHECK-NO-OP: *** IR Dump After NoOpMachineFunctionPass on test omitted because no change ***
 
-# CHECK-SIMPLE: *** IR Dump After DeadMachineInstructionElimPass on _Z4testv ***
-# CHECK-SIMPLE-NOT: %7:gr32 = MOV32rm %stack.0, 1, $noreg, 0, $noreg :: (load (s32) from %ir.1)
+# CHECK-SIMPLE: *** IR Dump After DeadMachineInstructionElimPass on test ***
+# CHECK-SIMPLE-NOT: %2:gr64 = MOV64ri 0

>From ec9f3f5be9b7787978a7a47a1165848ae22a9f0c Mon Sep 17 00:00:00 2001
From: PaperChalice <liujunchang97 at outlook.com>
Date: Thu, 8 Feb 2024 18:32:03 +0800
Subject: [PATCH 3/3] Print MIR when meet first non empty machine function

---
 .../llvm/Passes/StandardInstrumentations.h    |  3 +-
 llvm/lib/Passes/StandardInstrumentations.cpp  | 53 +++++++------------
 2 files changed, 22 insertions(+), 34 deletions(-)

diff --git a/llvm/include/llvm/Passes/StandardInstrumentations.h b/llvm/include/llvm/Passes/StandardInstrumentations.h
index daf8c10102626e..9a65df471b242a 100644
--- a/llvm/include/llvm/Passes/StandardInstrumentations.h
+++ b/llvm/include/llvm/Passes/StandardInstrumentations.h
@@ -18,6 +18,7 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSet.h"
 #include "llvm/CodeGen/MachineBasicBlock.h"
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/OptBisect.h"
@@ -234,7 +235,7 @@ template <typename IRUnitT> class ChangeReporter {
   // Is this the first IR seen?
   bool InitialIR = true;
   // Is this the first MIR seen?
-  bool InitialMIR = true;
+  StringSet<> HandledMIR;
 
   // Run in verbose mode, printing everything?
   const bool VerboseMode;
diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp
index c90850ce195716..ce68d90ee7f8e2 100644
--- a/llvm/lib/Passes/StandardInstrumentations.cpp
+++ b/llvm/lib/Passes/StandardInstrumentations.cpp
@@ -384,11 +384,10 @@ void ChangeReporter<T>::saveIRBeforePass(Any IR, StringRef PassID,
       handleInitialIR(IR);
   }
 
-  if (InitialMIR) {
-    if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
-      InitialMIR = false;
-      if (VerboseMode)
-        handleInitialMIR(MF);
+  if (const auto *MF = unwrapIR<MachineFunction>(IR)) {
+    if (VerboseMode && !HandledMIR.contains(MF->getName()) && !MF->empty()) {
+      handleInitialMIR(MF);
+      HandledMIR.insert(MF->getName());
     }
   }
 
@@ -480,13 +479,8 @@ template <typename T> void TextChangeReporter<T>::handleInitialIR(Any IR) {
 
 template <typename T>
 void TextChangeReporter<T>::handleInitialMIR(const MachineFunction *IR) {
-  // Print all available machine functions.
-  const auto &MMI = IR->getMMI();
-  const auto &M = *MMI.getModule();
   Out << "*** MIR Dump At Start ***\n";
-  for (const Function &F : M)
-    if (auto *MF = MMI.getMachineFunction(F))
-      MF->print(Out);
+  IR->print(Out);
 }
 
 template <typename T>
@@ -2288,33 +2282,26 @@ void DotCfgChangeReporter::handleInitialIR(Any IR) {
 
 void DotCfgChangeReporter::handleInitialMIR(const MachineFunction *IR) {
   assert(HTML && "Expected outstream to be set");
-  *HTML << "<button type=\"button\" class=\"collapsible\">0. "
+  *HTML << "<button type=\"button\" class=\"collapsible\">" << N << ". "
         << "Initial MIR (by machine function)</button>\n"
         << "<div class=\"content\">\n"
         << "  <p>\n";
-
-  auto &MMI = IR->getMMI();
-  const auto *M = MMI.getModule();
-  for (const auto &F : *M) {
-    if (const auto *MF = MMI.getMachineFunction(F)) {
-      // Create representation of IR
-      IRDataT<DCData> Data;
-      IRComparer<DCData>::analyzeIR(llvm::Any(MF), Data);
-      // Now compare it against itself, which will have everything the
-      // same and will generate the files.
-      IRComparer<DCData>(Data, Data)
-          .compare(getModuleForComparison(IR),
-                   [&](bool InModule, unsigned Minor,
-                       const FuncDataT<DCData> &Before,
-                       const FuncDataT<DCData> &After) -> void {
-                     handleFunctionCompare("", " ", "Initial MIR", "", InModule,
-                                           Minor, Before, After);
-                   });
-      ++N;
-    }
-  }
+  // Create representation of IR
+  IRDataT<DCData> Data;
+  IRComparer<DCData>::analyzeIR(llvm::Any(IR), Data);
+  // Now compare it against itself, which will have everything the
+  // same and will generate the files.
+  IRComparer<DCData>(Data, Data)
+      .compare(getModuleForComparison(IR),
+               [&](bool InModule, unsigned Minor,
+                   const FuncDataT<DCData> &Before,
+                   const FuncDataT<DCData> &After) -> void {
+                 handleFunctionCompare("", " ", "Initial MIR", "", InModule,
+                                       Minor, Before, After);
+               });
   *HTML << "  </p>\n"
         << "</div><br/>\n";
+  ++N;
 }
 
 void DotCfgChangeReporter::generateIRRepresentation(Any IR, StringRef PassID,



More information about the llvm-commits mailing list