1 //===- OptimizePHIs.cpp - Optimize machine instruction PHIs ---------------===// 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 pass optimizes machine instruction PHIs to take advantage of 10 // opportunities created during DAG legalization. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/ADT/SmallPtrSet.h" 15 #include "llvm/ADT/Statistic.h" 16 #include "llvm/CodeGen/MachineBasicBlock.h" 17 #include "llvm/CodeGen/MachineFunction.h" 18 #include "llvm/CodeGen/MachineFunctionPass.h" 19 #include "llvm/CodeGen/MachineInstr.h" 20 #include "llvm/CodeGen/MachineOperand.h" 21 #include "llvm/CodeGen/MachineRegisterInfo.h" 22 #include "llvm/CodeGen/TargetRegisterInfo.h" 23 #include "llvm/CodeGen/TargetSubtargetInfo.h" 24 #include "llvm/InitializePasses.h" 25 #include "llvm/Pass.h" 26 #include <cassert> 27 28 using namespace llvm; 29 30 #define DEBUG_TYPE "opt-phis" 31 32 STATISTIC(NumPHICycles, "Number of PHI cycles replaced"); 33 STATISTIC(NumDeadPHICycles, "Number of dead PHI cycles"); 34 35 namespace { 36 37 class OptimizePHIs : public MachineFunctionPass { 38 MachineRegisterInfo *MRI; 39 const TargetInstrInfo *TII; 40 41 public: 42 static char ID; // Pass identification 43 44 OptimizePHIs() : MachineFunctionPass(ID) { 45 initializeOptimizePHIsPass(*PassRegistry::getPassRegistry()); 46 } 47 48 bool runOnMachineFunction(MachineFunction &Fn) override; 49 50 void getAnalysisUsage(AnalysisUsage &AU) const override { 51 AU.setPreservesCFG(); 52 MachineFunctionPass::getAnalysisUsage(AU); 53 } 54 55 private: 56 using InstrSet = SmallPtrSet<MachineInstr *, 16>; 57 using InstrSetIterator = SmallPtrSetIterator<MachineInstr *>; 58 59 bool IsSingleValuePHICycle(MachineInstr *MI, unsigned &SingleValReg, 60 InstrSet &PHIsInCycle); 61 bool IsDeadPHICycle(MachineInstr *MI, InstrSet &PHIsInCycle); 62 bool OptimizeBB(MachineBasicBlock &MBB); 63 }; 64 65 } // end anonymous namespace 66 67 char OptimizePHIs::ID = 0; 68 69 char &llvm::OptimizePHIsID = OptimizePHIs::ID; 70 71 INITIALIZE_PASS(OptimizePHIs, DEBUG_TYPE, 72 "Optimize machine instruction PHIs", false, false) 73 74 bool OptimizePHIs::runOnMachineFunction(MachineFunction &Fn) { 75 if (skipFunction(Fn.getFunction())) 76 return false; 77 78 MRI = &Fn.getRegInfo(); 79 TII = Fn.getSubtarget().getInstrInfo(); 80 81 // Find dead PHI cycles and PHI cycles that can be replaced by a single 82 // value. InstCombine does these optimizations, but DAG legalization may 83 // introduce new opportunities, e.g., when i64 values are split up for 84 // 32-bit targets. 85 bool Changed = false; 86 for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) 87 Changed |= OptimizeBB(*I); 88 89 return Changed; 90 } 91 92 /// IsSingleValuePHICycle - Check if MI is a PHI where all the source operands 93 /// are copies of SingleValReg, possibly via copies through other PHIs. If 94 /// SingleValReg is zero on entry, it is set to the register with the single 95 /// non-copy value. PHIsInCycle is a set used to keep track of the PHIs that 96 /// have been scanned. PHIs may be grouped by cycle, several cycles or chains. 97 bool OptimizePHIs::IsSingleValuePHICycle(MachineInstr *MI, 98 unsigned &SingleValReg, 99 InstrSet &PHIsInCycle) { 100 assert(MI->isPHI() && "IsSingleValuePHICycle expects a PHI instruction"); 101 Register DstReg = MI->getOperand(0).getReg(); 102 103 // See if we already saw this register. 104 if (!PHIsInCycle.insert(MI).second) 105 return true; 106 107 // Don't scan crazily complex things. 108 if (PHIsInCycle.size() == 16) 109 return false; 110 111 // Scan the PHI operands. 112 for (unsigned i = 1; i != MI->getNumOperands(); i += 2) { 113 Register SrcReg = MI->getOperand(i).getReg(); 114 if (SrcReg == DstReg) 115 continue; 116 MachineInstr *SrcMI = MRI->getVRegDef(SrcReg); 117 118 // Skip over register-to-register moves. 119 if (SrcMI && SrcMI->isCopy() && !SrcMI->getOperand(0).getSubReg() && 120 !SrcMI->getOperand(1).getSubReg() && 121 Register::isVirtualRegister(SrcMI->getOperand(1).getReg())) { 122 SrcReg = SrcMI->getOperand(1).getReg(); 123 SrcMI = MRI->getVRegDef(SrcReg); 124 } 125 if (!SrcMI) 126 return false; 127 128 if (SrcMI->isPHI()) { 129 if (!IsSingleValuePHICycle(SrcMI, SingleValReg, PHIsInCycle)) 130 return false; 131 } else { 132 // Fail if there is more than one non-phi/non-move register. 133 if (SingleValReg != 0 && SingleValReg != SrcReg) 134 return false; 135 SingleValReg = SrcReg; 136 } 137 } 138 return true; 139 } 140 141 /// IsDeadPHICycle - Check if the register defined by a PHI is only used by 142 /// other PHIs in a cycle. 143 bool OptimizePHIs::IsDeadPHICycle(MachineInstr *MI, InstrSet &PHIsInCycle) { 144 assert(MI->isPHI() && "IsDeadPHICycle expects a PHI instruction"); 145 Register DstReg = MI->getOperand(0).getReg(); 146 assert(Register::isVirtualRegister(DstReg) && 147 "PHI destination is not a virtual register"); 148 149 // See if we already saw this register. 150 if (!PHIsInCycle.insert(MI).second) 151 return true; 152 153 // Don't scan crazily complex things. 154 if (PHIsInCycle.size() == 16) 155 return false; 156 157 for (MachineInstr &UseMI : MRI->use_nodbg_instructions(DstReg)) { 158 if (!UseMI.isPHI() || !IsDeadPHICycle(&UseMI, PHIsInCycle)) 159 return false; 160 } 161 162 return true; 163 } 164 165 /// OptimizeBB - Remove dead PHI cycles and PHI cycles that can be replaced by 166 /// a single value. 167 bool OptimizePHIs::OptimizeBB(MachineBasicBlock &MBB) { 168 bool Changed = false; 169 for (MachineBasicBlock::iterator 170 MII = MBB.begin(), E = MBB.end(); MII != E; ) { 171 MachineInstr *MI = &*MII++; 172 if (!MI->isPHI()) 173 break; 174 175 // Check for single-value PHI cycles. 176 unsigned SingleValReg = 0; 177 InstrSet PHIsInCycle; 178 if (IsSingleValuePHICycle(MI, SingleValReg, PHIsInCycle) && 179 SingleValReg != 0) { 180 Register OldReg = MI->getOperand(0).getReg(); 181 if (!MRI->constrainRegClass(SingleValReg, MRI->getRegClass(OldReg))) 182 continue; 183 184 MRI->replaceRegWith(OldReg, SingleValReg); 185 MI->eraseFromParent(); 186 187 // The kill flags on OldReg and SingleValReg may no longer be correct. 188 MRI->clearKillFlags(SingleValReg); 189 190 ++NumPHICycles; 191 Changed = true; 192 continue; 193 } 194 195 // Check for dead PHI cycles. 196 PHIsInCycle.clear(); 197 if (IsDeadPHICycle(MI, PHIsInCycle)) { 198 for (InstrSetIterator PI = PHIsInCycle.begin(), PE = PHIsInCycle.end(); 199 PI != PE; ++PI) { 200 MachineInstr *PhiMI = *PI; 201 if (MII == PhiMI) 202 ++MII; 203 PhiMI->eraseFromParent(); 204 } 205 ++NumDeadPHICycles; 206 Changed = true; 207 } 208 } 209 return Changed; 210 } 211