1 //===- ReduceRegisterDefs.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 uninteresting register uses from the MachineFunction. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "ReduceRegisterDefs.h" 15 #include "llvm/CodeGen/MachineFunction.h" 16 #include "llvm/CodeGen/MachineRegisterInfo.h" 17 #include "llvm/CodeGen/TargetInstrInfo.h" 18 19 using namespace llvm; 20 21 static void removeDefsFromFunction(Oracle &O, MachineFunction &MF) { 22 MachineRegisterInfo &MRI = MF.getRegInfo(); 23 const TargetSubtargetInfo &STI = MF.getSubtarget(); 24 const TargetInstrInfo *TII = STI.getInstrInfo(); 25 26 DenseSet<MachineOperand *> KeepDefs; 27 DenseSet<TargetInstrInfo::RegSubRegPair> DeleteDefs; 28 29 for (MachineBasicBlock &MBB : MF) { 30 for (MachineBasicBlock::iterator It = MBB.begin(), 31 E = MBB.getFirstTerminator(); 32 It != E;) { 33 MachineBasicBlock::iterator InsPt = It; 34 MachineInstr &MI = *It; 35 ++It; 36 37 KeepDefs.clear(); 38 DeleteDefs.clear(); 39 40 int NumOperands = MI.getNumOperands(); 41 int NumRequiredOps = MI.getNumExplicitOperands() + 42 MI.getDesc().getNumImplicitDefs() + 43 MI.getDesc().getNumImplicitUses(); 44 45 bool HaveDelete = false; 46 // Do an initial scan in case the instruction defines the same register 47 // multiple times. 48 for (int I = NumOperands - 1; I >= 0; --I) { 49 MachineOperand &MO = MI.getOperand(I); 50 if (!MO.isReg() || !MO.isDef()) 51 continue; 52 53 TargetInstrInfo::RegSubRegPair RegPair(MO.getReg(), MO.getSubReg()); 54 if (!RegPair.Reg.isVirtual()) 55 continue; 56 57 if (O.shouldKeep()) 58 KeepDefs.insert(&MO); 59 else 60 HaveDelete = true; 61 } 62 63 if (!HaveDelete) 64 continue; 65 66 bool HaveKeptDef = !KeepDefs.empty(); 67 for (int I = NumOperands - 1; I >= 0; --I) { 68 MachineOperand &MO = MI.getOperand(I); 69 if (!MO.isReg() || !MO.isDef()) 70 continue; 71 72 if (KeepDefs.count(&MO)) 73 continue; 74 75 TargetInstrInfo::RegSubRegPair RegPair(MO.getReg(), MO.getSubReg()); 76 if (!RegPair.Reg.isVirtual()) 77 continue; 78 79 if (!DeleteDefs.insert(RegPair).second) 80 continue; 81 82 if (MRI.use_empty(RegPair.Reg)) { 83 if (I >= NumRequiredOps) { 84 // Delete implicit def operands that aren't part of the instruction 85 // definition 86 MI.removeOperand(I); 87 } 88 89 continue; 90 } 91 92 // If we aren't going to delete the instruction, replace it with a dead 93 // def. 94 if (HaveKeptDef) 95 MO.setReg(MRI.cloneVirtualRegister(MO.getReg())); 96 97 bool IsGeneric = MRI.getRegClassOrNull(RegPair.Reg) == nullptr; 98 unsigned ImpDef = IsGeneric ? TargetOpcode::G_IMPLICIT_DEF 99 : TargetOpcode::IMPLICIT_DEF; 100 101 unsigned OpFlags = getRegState(MO) & ~RegState::Implicit; 102 InsPt = BuildMI(MBB, InsPt, DebugLoc(), TII->get(ImpDef)) 103 .addReg(RegPair.Reg, OpFlags, RegPair.SubReg); 104 } 105 106 if (!HaveKeptDef) 107 MI.eraseFromParent(); 108 } 109 } 110 } 111 112 static void removeDefsFromModule(Oracle &O, ReducerWorkItem &WorkItem) { 113 for (const Function &F : WorkItem.getModule()) { 114 if (auto *MF = WorkItem.MMI->getMachineFunction(F)) 115 removeDefsFromFunction(O, *MF); 116 } 117 } 118 119 void llvm::reduceRegisterDefsMIRDeltaPass(TestRunner &Test) { 120 outs() << "*** Reducing register defs...\n"; 121 runDeltaPass(Test, removeDefsFromModule); 122 } 123