xref: /llvm-project/llvm/tools/llvm-reduce/deltas/ReduceRegisterMasks.cpp (revision 333ffafb4500cad19aec81e841686ade1f31f67f)
1 //===- ReduceRegisterMasks.cpp - Specialized Delta Pass -------------------===//
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 file implements a function which calls the Generic Delta pass in order
10 // to reduce custom register masks from the MachineFunction.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "ReduceRegisterMasks.h"
15 #include "llvm/CodeGen/MachineFunction.h"
16 #include "llvm/CodeGen/MachineModuleInfo.h"
17 #include "llvm/CodeGen/MachineRegisterInfo.h"
18 
19 using namespace llvm;
20 
reduceMasksInFunction(Oracle & O,MachineFunction & MF)21 static void reduceMasksInFunction(Oracle &O, MachineFunction &MF) {
22   DenseSet<const uint32_t *> ConstRegisterMasks;
23   const auto *TRI = MF.getSubtarget().getRegisterInfo();
24 
25   // Track predefined/named regmasks which we ignore.
26   const unsigned NumRegs = TRI->getNumRegs();
27   for (const uint32_t *Mask : TRI->getRegMasks())
28     ConstRegisterMasks.insert(Mask);
29 
30   for (MachineBasicBlock &MBB : MF) {
31     for (MachineInstr &MI : MBB) {
32       for (MachineOperand &MO : MI.operands()) {
33         if (!MO.isRegMask())
34           continue;
35 
36         const uint32_t *OldRegMask = MO.getRegMask();
37         // We're only reducing custom reg masks.
38         if (ConstRegisterMasks.count(OldRegMask))
39           continue;
40         unsigned RegMaskSize =
41             MachineOperand::getRegMaskSize(TRI->getNumRegs());
42         std::vector<uint32_t> NewMask(RegMaskSize);
43 
44         bool MadeChange = false;
45         for (unsigned I = 0; I != NumRegs; ++I) {
46           if (OldRegMask[I / 32] & (1u << (I % 32))) {
47             if (O.shouldKeep())
48               NewMask[I / 32] |= 1u << (I % 32);
49           } else
50             MadeChange = true;
51         }
52 
53         if (MadeChange) {
54           uint32_t *UpdatedMask = MF.allocateRegMask();
55           std::memcpy(UpdatedMask, NewMask.data(),
56                       RegMaskSize * sizeof(*OldRegMask));
57           MO.setRegMask(UpdatedMask);
58         }
59       }
60     }
61   }
62 }
63 
reduceMasksInModule(Oracle & O,ReducerWorkItem & WorkItem)64 static void reduceMasksInModule(Oracle &O, ReducerWorkItem &WorkItem) {
65   for (const Function &F : WorkItem.getModule()) {
66     if (auto *MF = WorkItem.MMI->getMachineFunction(F))
67       reduceMasksInFunction(O, *MF);
68   }
69 }
70 
reduceRegisterMasksMIRDeltaPass(TestRunner & Test)71 void llvm::reduceRegisterMasksMIRDeltaPass(TestRunner &Test) {
72   runDeltaPass(Test, reduceMasksInModule, "Reducing register masks");
73 }
74