//===- 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/MachineModuleInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" using namespace llvm; static void reduceMasksInFunction(Oracle &O, MachineFunction &MF) { DenseSet 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 NewMask(RegMaskSize); bool MadeChange = false; for (unsigned I = 0; I != NumRegs; ++I) { if (OldRegMask[I / 32] & (1u << (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) { runDeltaPass(Test, reduceMasksInModule, "Reducing register masks"); }