[llvm] 0f9d9ed - llvm-reduce: Add reduction for custom register masks

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 18 10:41:12 PDT 2022


Author: Matt Arsenault
Date: 2022-07-18T13:41:08-04:00
New Revision: 0f9d9edd24774678491c19aa8653d8ac6c44da97

URL: https://github.com/llvm/llvm-project/commit/0f9d9edd24774678491c19aa8653d8ac6c44da97
DIFF: https://github.com/llvm/llvm-project/commit/0f9d9edd24774678491c19aa8653d8ac6c44da97.diff

LOG: llvm-reduce: Add reduction for custom register masks

I have a register allocator failure that only reproduces with IPRA
enabled, and requires the specific regmask if I want to only run the
one relevant pass. The printed custom regmask is enormous and I would
like to reduce it.

This reduces each individual bit in the mask, but it would probably be
better to start at register units and clear all aliasing fields at a
time. This would require stricter verification that all aliasing bits
are set in regmasks (although I would prefer to switch regmasks to use
register units in the first place).

Added: 
    llvm/test/tools/llvm-reduce/mir/reduce-register-masks.mir
    llvm/tools/llvm-reduce/deltas/ReduceRegisterMasks.cpp
    llvm/tools/llvm-reduce/deltas/ReduceRegisterMasks.h

Modified: 
    llvm/tools/llvm-reduce/CMakeLists.txt
    llvm/tools/llvm-reduce/DeltaManager.cpp
    llvm/tools/llvm-reduce/ReducerWorkItem.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/test/tools/llvm-reduce/mir/reduce-register-masks.mir b/llvm/test/tools/llvm-reduce/mir/reduce-register-masks.mir
new file mode 100644
index 0000000000000..396f07a4fe63a
--- /dev/null
+++ b/llvm/test/tools/llvm-reduce/mir/reduce-register-masks.mir
@@ -0,0 +1,23 @@
+# REQUIRES: amdgpu-registered-target
+# RUN: llvm-reduce -abort-on-invalid-reduction -simplify-mir --delta-passes=register-masks -mtriple=amdgcn-amd-amdhsa --test FileCheck --test-arg --check-prefix=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t
+# RUN: FileCheck --match-full-lines --check-prefix=RESULT %s < %t
+
+# CHECK-INTERESTINGNESS: CustomRegMask
+# CHECK-INTERESTINGNESS-SAME: $vcc_lo,
+# CHECK-INTERESTINGNESS-SAME: $agpr8,
+# CHECK-INTERESTINGNESS-SAME: $sgpr99,
+# CHECK-INTERESTINGNESS-SAME: $vgpr23,
+# CHECK-INTERESTINGNESS-SAME: $vgpr48_vgpr49_vgpr50,
+
+# RESULT: $sgpr30_sgpr31 = SI_CALL %0, 0, CustomRegMask($vcc_lo,$agpr8,$sgpr99,$vgpr23,$vgpr48_vgpr49_vgpr50,$vgpr49_vgpr50_vgpr51)
+
+---
+name: func
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    liveins: $vgpr0, $vgpr1, $sgpr8_sgpr9
+    %0:sreg_64_xexec = COPY $sgpr8_sgpr9
+    $sgpr30_sgpr31 = SI_CALL %0:sreg_64_xexec, 0, CustomRegMask($vgpr8_vgpr9, $vgpr9_vgpr10_vgpr11,$vcc_lo,$agpr8,$sgpr99,$vgpr23,$vgpr48_vgpr49_vgpr50,$vgpr49_vgpr50_vgpr51, $vgpr52_vgpr53_vgpr54,$vcc_hi,$sgpr0_sgpr1_sgpr2_sgpr3,$sgpr4_sgpr5_sgpr6_sgpr7)
+    S_ENDPGM 0
+...

diff  --git a/llvm/tools/llvm-reduce/CMakeLists.txt b/llvm/tools/llvm-reduce/CMakeLists.txt
index b1911f9c407b2..b28c54a851dc3 100644
--- a/llvm/tools/llvm-reduce/CMakeLists.txt
+++ b/llvm/tools/llvm-reduce/CMakeLists.txt
@@ -45,6 +45,7 @@ add_llvm_tool(llvm-reduce
   deltas/ReduceInstructionFlagsMIR.cpp
   deltas/ReduceIRReferences.cpp
   deltas/ReduceVirtualRegisters.cpp
+  deltas/ReduceRegisterMasks.cpp
   deltas/ReduceRegisterUses.cpp
   deltas/SimplifyInstructions.cpp
   llvm-reduce.cpp

diff  --git a/llvm/tools/llvm-reduce/DeltaManager.cpp b/llvm/tools/llvm-reduce/DeltaManager.cpp
index 98fd818bb0459..f0fae0c658db1 100644
--- a/llvm/tools/llvm-reduce/DeltaManager.cpp
+++ b/llvm/tools/llvm-reduce/DeltaManager.cpp
@@ -35,6 +35,7 @@
 #include "deltas/ReduceOperands.h"
 #include "deltas/ReduceOperandsSkip.h"
 #include "deltas/ReduceOperandsToArgs.h"
+#include "deltas/ReduceRegisterMasks.h"
 #include "deltas/ReduceRegisterUses.h"
 #include "deltas/ReduceSpecialGlobals.h"
 #include "deltas/ReduceVirtualRegisters.h"
@@ -85,6 +86,7 @@ static cl::opt<std::string>
     DELTA_PASS("instruction-flags", reduceInstructionFlagsMIRDeltaPass)        \
     DELTA_PASS("register-uses", reduceRegisterUsesMIRDeltaPass)                \
     DELTA_PASS("register-hints", reduceVirtualRegisterHintsDeltaPass)          \
+    DELTA_PASS("register-masks", reduceRegisterMasksMIRDeltaPass)              \
   } while (false)
 
 static void runAllDeltaPasses(TestRunner &Tester) {

diff  --git a/llvm/tools/llvm-reduce/ReducerWorkItem.cpp b/llvm/tools/llvm-reduce/ReducerWorkItem.cpp
index 891553497b9bb..b6e78dd97e768 100644
--- a/llvm/tools/llvm-reduce/ReducerWorkItem.cpp
+++ b/llvm/tools/llvm-reduce/ReducerWorkItem.cpp
@@ -291,6 +291,12 @@ static std::unique_ptr<MachineFunction> cloneMF(MachineFunction *SrcMF,
     }
   }
 
+  DenseSet<const uint32_t *> ConstRegisterMasks;
+
+  // Track predefined/named regmasks which we ignore.
+  for (const uint32_t *Mask : TRI->getRegMasks())
+    ConstRegisterMasks.insert(Mask);
+
   // Clone instructions.
   for (auto &SrcMBB : *SrcMF) {
     auto *DstMBB = Src2DstMBB[&SrcMBB];
@@ -309,9 +315,18 @@ static std::unique_ptr<MachineFunction> cloneMF(MachineFunction *SrcMF,
         // Update MBB.
         if (DstMO.isMBB())
           DstMO.setMBB(Src2DstMBB[DstMO.getMBB()]);
-        else if (DstMO.isRegMask())
+        else if (DstMO.isRegMask()) {
           DstMRI->addPhysRegsUsedFromRegMask(DstMO.getRegMask());
 
+          if (!ConstRegisterMasks.count(DstMO.getRegMask())) {
+            uint32_t *DstMask = DstMF->allocateRegMask();
+            std::memcpy(DstMask, SrcMO.getRegMask(),
+                        sizeof(*DstMask) *
+                            MachineOperand::getRegMaskSize(TRI->getNumRegs()));
+            DstMO.setRegMask(DstMask);
+          }
+        }
+
         DstMI->addOperand(DstMO);
       }
 

diff  --git a/llvm/tools/llvm-reduce/deltas/ReduceRegisterMasks.cpp b/llvm/tools/llvm-reduce/deltas/ReduceRegisterMasks.cpp
new file mode 100644
index 0000000000000..5cf145aa1a4a9
--- /dev/null
+++ b/llvm/tools/llvm-reduce/deltas/ReduceRegisterMasks.cpp
@@ -0,0 +1,73 @@
+//===- ReduceRegisterMasks.cpp - Specialized Delta Pass -------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a function which calls the Generic Delta pass in order
+// to reduce custom register masks from the MachineFunction.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ReduceRegisterMasks.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+
+using namespace llvm;
+
+static void reduceMasksInFunction(Oracle &O, MachineFunction &MF) {
+  DenseSet<const uint32_t *> ConstRegisterMasks;
+  const auto *TRI = MF.getSubtarget().getRegisterInfo();
+
+  // Track predefined/named regmasks which we ignore.
+  const unsigned NumRegs = TRI->getNumRegs();
+  for (const uint32_t *Mask : TRI->getRegMasks())
+    ConstRegisterMasks.insert(Mask);
+
+  for (MachineBasicBlock &MBB : MF) {
+    for (MachineInstr &MI : MBB) {
+      for (MachineOperand &MO : MI.operands()) {
+        if (!MO.isRegMask())
+          continue;
+
+        const uint32_t *OldRegMask = MO.getRegMask();
+        // We're only reducing custom reg masks.
+        if (ConstRegisterMasks.count(OldRegMask))
+          continue;
+        unsigned RegMaskSize =
+            MachineOperand::getRegMaskSize(TRI->getNumRegs());
+        std::vector<uint32_t> NewMask(RegMaskSize);
+
+        bool MadeChange = false;
+        for (unsigned I = 0; I != NumRegs; ++I) {
+          if (OldRegMask[I / 32] >> I % 32) {
+            if (O.shouldKeep())
+              NewMask[I / 32] |= 1u << (I % 32);
+          } else
+            MadeChange = true;
+        }
+
+        if (MadeChange) {
+          uint32_t *UpdatedMask = MF.allocateRegMask();
+          std::memcpy(UpdatedMask, NewMask.data(),
+                      RegMaskSize * sizeof(*OldRegMask));
+          MO.setRegMask(UpdatedMask);
+        }
+      }
+    }
+  }
+}
+
+static void reduceMasksInModule(Oracle &O, ReducerWorkItem &WorkItem) {
+  for (const Function &F : WorkItem.getModule()) {
+    if (auto *MF = WorkItem.MMI->getMachineFunction(F))
+      reduceMasksInFunction(O, *MF);
+  }
+}
+
+void llvm::reduceRegisterMasksMIRDeltaPass(TestRunner &Test) {
+  outs() << "*** Reducing register masks...\n";
+  runDeltaPass(Test, reduceMasksInModule);
+}

diff  --git a/llvm/tools/llvm-reduce/deltas/ReduceRegisterMasks.h b/llvm/tools/llvm-reduce/deltas/ReduceRegisterMasks.h
new file mode 100644
index 0000000000000..b8bb109e5c996
--- /dev/null
+++ b/llvm/tools/llvm-reduce/deltas/ReduceRegisterMasks.h
@@ -0,0 +1,18 @@
+//===- ReduceRegisterMasks.h  - Specialized Delta Pass ----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVM_REDUCE_DELTAS_REDUCEREGISTERMASKS_H
+#define LLVM_TOOLS_LLVM_REDUCE_DELTAS_REDUCEREGISTERMASKS_H
+
+#include "Delta.h"
+
+namespace llvm {
+void reduceRegisterMasksMIRDeltaPass(TestRunner &Test);
+} // namespace llvm
+
+#endif


        


More information about the llvm-commits mailing list