/// IsSingleValuePHICycle - Check if MI is a PHI where all the source operands /// are copies of SingleValReg, possibly via copies through other PHIs. If /// SingleValReg is zero on entry, it is set to the register with the single /// non-copy value. PHIsInCycle is a set used to keep track of the PHIs that /// have been scanned. PHIs may be grouped by cycle, several cycles or chains. bool OptimizePHIs::IsSingleValuePHICycle(MachineInstr *MI, unsigned &SingleValReg, InstrSet &PHIsInCycle) { assert(MI->isPHI() && "IsSingleValuePHICycle expects a PHI instruction"); unsigned DstReg = MI->getOperand(0).getReg(); // See if we already saw this register. if (!PHIsInCycle.insert(MI).second) return true; // Don't scan crazily complex things. if (PHIsInCycle.size() == 16) return false; // Scan the PHI operands. for (unsigned i = 1; i != MI->getNumOperands(); i += 2) { unsigned SrcReg = MI->getOperand(i).getReg(); if (SrcReg == DstReg) continue; MachineInstr *SrcMI = MRI->getVRegDef(SrcReg); // Skip over register-to-register moves. if (SrcMI && SrcMI->isCopy() && !SrcMI->getOperand(0).getSubReg() && !SrcMI->getOperand(1).getSubReg() && TargetRegisterInfo::isVirtualRegister(SrcMI->getOperand(1).getReg())) { SrcReg = SrcMI->getOperand(1).getReg(); SrcMI = MRI->getVRegDef(SrcReg); } if (!SrcMI) return false; if (SrcMI->isPHI()) { if (!IsSingleValuePHICycle(SrcMI, SingleValReg, PHIsInCycle)) return false; } else { // Fail if there is more than one non-phi/non-move register. if (SingleValReg != 0 && SingleValReg != SrcReg) return false; SingleValReg = SrcReg; } } return true; }
/// IsDeadPHICycle - Check if the register defined by a PHI is only used by /// other PHIs in a cycle. bool OptimizePHIs::IsDeadPHICycle(MachineInstr *MI, InstrSet &PHIsInCycle) { assert(MI->isPHI() && "IsDeadPHICycle expects a PHI instruction"); unsigned DstReg = MI->getOperand(0).getReg(); assert(TargetRegisterInfo::isVirtualRegister(DstReg) && "PHI destination is not a virtual register"); // See if we already saw this register. if (!PHIsInCycle.insert(MI)) return true; // Don't scan crazily complex things. if (PHIsInCycle.size() == 16) return false; for (MachineInstr &UseMI : MRI->use_instructions(DstReg)) { if (!UseMI.isPHI() || !IsDeadPHICycle(&UseMI, PHIsInCycle)) return false; } return true; }