10f9d9eddSMatt Arsenault //===- ReduceRegisterMasks.cpp - Specialized Delta Pass -------------------===//
20f9d9eddSMatt Arsenault //
30f9d9eddSMatt Arsenault // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40f9d9eddSMatt Arsenault // See https://llvm.org/LICENSE.txt for license information.
50f9d9eddSMatt Arsenault // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60f9d9eddSMatt Arsenault //
70f9d9eddSMatt Arsenault //===----------------------------------------------------------------------===//
80f9d9eddSMatt Arsenault //
90f9d9eddSMatt Arsenault // This file implements a function which calls the Generic Delta pass in order
100f9d9eddSMatt Arsenault // to reduce custom register masks from the MachineFunction.
110f9d9eddSMatt Arsenault //
120f9d9eddSMatt Arsenault //===----------------------------------------------------------------------===//
130f9d9eddSMatt Arsenault
140f9d9eddSMatt Arsenault #include "ReduceRegisterMasks.h"
150f9d9eddSMatt Arsenault #include "llvm/CodeGen/MachineFunction.h"
16*333ffafbSMatt Arsenault #include "llvm/CodeGen/MachineModuleInfo.h"
170f9d9eddSMatt Arsenault #include "llvm/CodeGen/MachineRegisterInfo.h"
180f9d9eddSMatt Arsenault
190f9d9eddSMatt Arsenault using namespace llvm;
200f9d9eddSMatt Arsenault
reduceMasksInFunction(Oracle & O,MachineFunction & MF)210f9d9eddSMatt Arsenault static void reduceMasksInFunction(Oracle &O, MachineFunction &MF) {
220f9d9eddSMatt Arsenault DenseSet<const uint32_t *> ConstRegisterMasks;
230f9d9eddSMatt Arsenault const auto *TRI = MF.getSubtarget().getRegisterInfo();
240f9d9eddSMatt Arsenault
250f9d9eddSMatt Arsenault // Track predefined/named regmasks which we ignore.
260f9d9eddSMatt Arsenault const unsigned NumRegs = TRI->getNumRegs();
270f9d9eddSMatt Arsenault for (const uint32_t *Mask : TRI->getRegMasks())
280f9d9eddSMatt Arsenault ConstRegisterMasks.insert(Mask);
290f9d9eddSMatt Arsenault
300f9d9eddSMatt Arsenault for (MachineBasicBlock &MBB : MF) {
310f9d9eddSMatt Arsenault for (MachineInstr &MI : MBB) {
320f9d9eddSMatt Arsenault for (MachineOperand &MO : MI.operands()) {
330f9d9eddSMatt Arsenault if (!MO.isRegMask())
340f9d9eddSMatt Arsenault continue;
350f9d9eddSMatt Arsenault
360f9d9eddSMatt Arsenault const uint32_t *OldRegMask = MO.getRegMask();
370f9d9eddSMatt Arsenault // We're only reducing custom reg masks.
380f9d9eddSMatt Arsenault if (ConstRegisterMasks.count(OldRegMask))
390f9d9eddSMatt Arsenault continue;
400f9d9eddSMatt Arsenault unsigned RegMaskSize =
410f9d9eddSMatt Arsenault MachineOperand::getRegMaskSize(TRI->getNumRegs());
420f9d9eddSMatt Arsenault std::vector<uint32_t> NewMask(RegMaskSize);
430f9d9eddSMatt Arsenault
440f9d9eddSMatt Arsenault bool MadeChange = false;
450f9d9eddSMatt Arsenault for (unsigned I = 0; I != NumRegs; ++I) {
46fe1678d1SMatt Arsenault if (OldRegMask[I / 32] & (1u << (I % 32))) {
470f9d9eddSMatt Arsenault if (O.shouldKeep())
480f9d9eddSMatt Arsenault NewMask[I / 32] |= 1u << (I % 32);
490f9d9eddSMatt Arsenault } else
500f9d9eddSMatt Arsenault MadeChange = true;
510f9d9eddSMatt Arsenault }
520f9d9eddSMatt Arsenault
530f9d9eddSMatt Arsenault if (MadeChange) {
540f9d9eddSMatt Arsenault uint32_t *UpdatedMask = MF.allocateRegMask();
550f9d9eddSMatt Arsenault std::memcpy(UpdatedMask, NewMask.data(),
560f9d9eddSMatt Arsenault RegMaskSize * sizeof(*OldRegMask));
570f9d9eddSMatt Arsenault MO.setRegMask(UpdatedMask);
580f9d9eddSMatt Arsenault }
590f9d9eddSMatt Arsenault }
600f9d9eddSMatt Arsenault }
610f9d9eddSMatt Arsenault }
620f9d9eddSMatt Arsenault }
630f9d9eddSMatt Arsenault
reduceMasksInModule(Oracle & O,ReducerWorkItem & WorkItem)640f9d9eddSMatt Arsenault static void reduceMasksInModule(Oracle &O, ReducerWorkItem &WorkItem) {
650f9d9eddSMatt Arsenault for (const Function &F : WorkItem.getModule()) {
660f9d9eddSMatt Arsenault if (auto *MF = WorkItem.MMI->getMachineFunction(F))
670f9d9eddSMatt Arsenault reduceMasksInFunction(O, *MF);
680f9d9eddSMatt Arsenault }
690f9d9eddSMatt Arsenault }
700f9d9eddSMatt Arsenault
reduceRegisterMasksMIRDeltaPass(TestRunner & Test)710f9d9eddSMatt Arsenault void llvm::reduceRegisterMasksMIRDeltaPass(TestRunner &Test) {
722592ccdeSArthur Eubanks runDeltaPass(Test, reduceMasksInModule, "Reducing register masks");
730f9d9eddSMatt Arsenault }
74