| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,122 @@ | ||
| //===- ReduceRegisterDefs.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 uninteresting register uses from the MachineFunction. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "ReduceRegisterDefs.h" | ||
| #include "llvm/CodeGen/MachineFunction.h" | ||
| #include "llvm/CodeGen/MachineRegisterInfo.h" | ||
| #include "llvm/CodeGen/TargetInstrInfo.h" | ||
|
|
||
| using namespace llvm; | ||
|
|
||
| static void removeDefsFromFunction(Oracle &O, MachineFunction &MF) { | ||
| MachineRegisterInfo &MRI = MF.getRegInfo(); | ||
| const TargetSubtargetInfo &STI = MF.getSubtarget(); | ||
| const TargetInstrInfo *TII = STI.getInstrInfo(); | ||
|
|
||
| DenseSet<MachineOperand *> KeepDefs; | ||
| DenseSet<TargetInstrInfo::RegSubRegPair> DeleteDefs; | ||
|
|
||
| for (MachineBasicBlock &MBB : MF) { | ||
| for (MachineBasicBlock::iterator It = MBB.begin(), | ||
| E = MBB.getFirstTerminator(); | ||
| It != E;) { | ||
| MachineBasicBlock::iterator InsPt = It; | ||
| MachineInstr &MI = *It; | ||
| ++It; | ||
|
|
||
| KeepDefs.clear(); | ||
| DeleteDefs.clear(); | ||
|
|
||
| int NumOperands = MI.getNumOperands(); | ||
| int NumRequiredOps = MI.getNumExplicitOperands() + | ||
| MI.getDesc().getNumImplicitDefs() + | ||
| MI.getDesc().getNumImplicitUses(); | ||
|
|
||
| bool HaveDelete = false; | ||
| // Do an initial scan in case the instruction defines the same register | ||
| // multiple times. | ||
| for (int I = NumOperands - 1; I >= 0; --I) { | ||
| MachineOperand &MO = MI.getOperand(I); | ||
| if (!MO.isReg() || !MO.isDef()) | ||
| continue; | ||
|
|
||
| TargetInstrInfo::RegSubRegPair RegPair(MO.getReg(), MO.getSubReg()); | ||
| if (!RegPair.Reg.isVirtual()) | ||
| continue; | ||
|
|
||
| if (O.shouldKeep()) | ||
| KeepDefs.insert(&MO); | ||
| else | ||
| HaveDelete = true; | ||
| } | ||
|
|
||
| if (!HaveDelete) | ||
| continue; | ||
|
|
||
| bool HaveKeptDef = !KeepDefs.empty(); | ||
| for (int I = NumOperands - 1; I >= 0; --I) { | ||
| MachineOperand &MO = MI.getOperand(I); | ||
| if (!MO.isReg() || !MO.isDef()) | ||
| continue; | ||
|
|
||
| if (KeepDefs.count(&MO)) | ||
| continue; | ||
|
|
||
| TargetInstrInfo::RegSubRegPair RegPair(MO.getReg(), MO.getSubReg()); | ||
| if (!RegPair.Reg.isVirtual()) | ||
| continue; | ||
|
|
||
| if (!DeleteDefs.insert(RegPair).second) | ||
| continue; | ||
|
|
||
| if (MRI.use_empty(RegPair.Reg)) { | ||
| if (I >= NumRequiredOps) { | ||
| // Delete implicit def operands that aren't part of the instruction | ||
| // definition | ||
| MI.removeOperand(I); | ||
| } | ||
|
|
||
| continue; | ||
| } | ||
|
|
||
| // If we aren't going to delete the instruction, replace it with a dead | ||
| // def. | ||
| if (HaveKeptDef) | ||
| MO.setReg(MRI.cloneVirtualRegister(MO.getReg())); | ||
|
|
||
| bool IsGeneric = MRI.getRegClassOrNull(RegPair.Reg) == nullptr; | ||
| unsigned ImpDef = IsGeneric ? TargetOpcode::G_IMPLICIT_DEF | ||
| : TargetOpcode::IMPLICIT_DEF; | ||
|
|
||
| unsigned OpFlags = getRegState(MO) & ~RegState::Implicit; | ||
| InsPt = BuildMI(MBB, InsPt, DebugLoc(), TII->get(ImpDef)) | ||
| .addReg(RegPair.Reg, OpFlags, RegPair.SubReg); | ||
| } | ||
|
|
||
| if (!HaveKeptDef) | ||
| MI.eraseFromParent(); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| static void removeDefsFromModule(Oracle &O, ReducerWorkItem &WorkItem) { | ||
| for (const Function &F : WorkItem.getModule()) { | ||
| if (auto *MF = WorkItem.MMI->getMachineFunction(F)) | ||
| removeDefsFromFunction(O, *MF); | ||
| } | ||
| } | ||
|
|
||
| void llvm::reduceRegisterDefsMIRDeltaPass(TestRunner &Test) { | ||
| outs() << "*** Reducing register defs...\n"; | ||
| runDeltaPass(Test, removeDefsFromModule); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| //===- ReduceRegisterDefs.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 | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file implements a function which calls the Generic Delta pass in order | ||
| // to reduce uninteresting register defs from the MachineFunction. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_TOOLS_LLVM_REDUCE_DELTAS_REDUCEREGISTERDEFS_H | ||
| #define LLVM_TOOLS_LLVM_REDUCE_DELTAS_REDUCEREGISTERDEFS_H | ||
|
|
||
| #include "Delta.h" | ||
|
|
||
| namespace llvm { | ||
| void reduceRegisterDefsMIRDeltaPass(TestRunner &Test); | ||
| } // namespace llvm | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |