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
19using namespace llvm;
20
21static 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 ConstRegisterMasks.insert_range(R: TRI->getRegMasks());
28
29 for (MachineBasicBlock &MBB : MF) {
30 for (MachineInstr &MI : MBB) {
31 for (MachineOperand &MO : MI.operands()) {
32 if (!MO.isRegMask())
33 continue;
34
35 const uint32_t *OldRegMask = MO.getRegMask();
36 // We're only reducing custom reg masks.
37 if (ConstRegisterMasks.count(V: OldRegMask))
38 continue;
39 unsigned RegMaskSize =
40 MachineOperand::getRegMaskSize(NumRegs: TRI->getNumRegs());
41 std::vector<uint32_t> NewMask(RegMaskSize);
42
43 bool MadeChange = false;
44 for (unsigned I = 0; I != NumRegs; ++I) {
45 if (OldRegMask[I / 32] & (1u << (I % 32))) {
46 if (O.shouldKeep())
47 NewMask[I / 32] |= 1u << (I % 32);
48 } else
49 MadeChange = true;
50 }
51
52 if (MadeChange) {
53 uint32_t *UpdatedMask = MF.allocateRegMask();
54 std::memcpy(dest: UpdatedMask, src: NewMask.data(),
55 n: RegMaskSize * sizeof(*OldRegMask));
56 MO.setRegMask(UpdatedMask);
57 }
58 }
59 }
60 }
61}
62
63void llvm::reduceRegisterMasksMIRDeltaPass(Oracle &O,
64 ReducerWorkItem &WorkItem) {
65 for (const Function &F : WorkItem.getModule()) {
66 if (auto *MF = WorkItem.MMI->getMachineFunction(F))
67 reduceMasksInFunction(O, MF&: *MF);
68 }
69}
70