/// Changes operand OpNum in MI the refer the PhysReg, considering subregs. This /// may invalidate any operand pointers. Return true if the operand kills its /// register. bool RegAllocFast::setPhysReg(MachineInstr &MI, MachineOperand &MO, MCPhysReg PhysReg) { bool Dead = MO.isDead(); if (!MO.getSubReg()) { MO.setReg(PhysReg); MO.setIsRenamable(true); return MO.isKill() || Dead; } // Handle subregister index. MO.setReg(PhysReg ? TRI->getSubReg(PhysReg, MO.getSubReg()) : 0); MO.setIsRenamable(true); MO.setSubReg(0); // A kill flag implies killing the full register. Add corresponding super // register kill. if (MO.isKill()) { MI.addRegisterKilled(PhysReg, TRI, true); return true; } // A <def,read-undef> of a sub-register requires an implicit def of the full // register. if (MO.isDef() && MO.isUndef()) MI.addRegisterDefined(PhysReg, TRI); return Dead; }
void HexagonPeephole::ChangeOpInto(MachineOperand &Dst, MachineOperand &Src) { assert (&Dst != &Src && "Cannot duplicate into itself"); switch (Dst.getType()) { case MachineOperand::MO_Register: if (Src.isReg()) { Dst.setReg(Src.getReg()); } else if (Src.isImm()) { Dst.ChangeToImmediate(Src.getImm()); } else { llvm_unreachable("Unexpected src operand type"); } break; case MachineOperand::MO_Immediate: if (Src.isImm()) { Dst.setImm(Src.getImm()); } else if (Src.isReg()) { Dst.ChangeToRegister(Src.getReg(), Src.isDef(), Src.isImplicit(), Src.isKill(), Src.isDead(), Src.isUndef(), Src.isDebug()); } else { llvm_unreachable("Unexpected src operand type"); } break; default: llvm_unreachable("Unexpected dst operand type"); break; } }
/// RewriteUse - Rewrite a use of the symbolic value. This handles PHI nodes, /// which use their value in the corresponding predecessor. void MachineSSAUpdater::RewriteUse(MachineOperand &U) { MachineInstr *UseMI = U.getParent(); unsigned NewVR = 0; if (UseMI->getOpcode() == TargetInstrInfo::PHI) { MachineBasicBlock *SourceBB = findCorrespondingPred(UseMI, &U); NewVR = GetValueAtEndOfBlockInternal(SourceBB); } else { NewVR = GetValueInMiddleOfBlock(UseMI->getParent()); } U.setReg(NewVR); }
/// If desirable, rewrite NewReg to a drop register. static bool MaybeRewriteToDrop(unsigned OldReg, unsigned NewReg, MachineOperand &MO, WebAssemblyFunctionInfo &MFI, MachineRegisterInfo &MRI) { bool Changed = false; if (OldReg == NewReg) { Changed = true; unsigned NewReg = MRI.createVirtualRegister(MRI.getRegClass(OldReg)); MO.setReg(NewReg); MO.setIsDead(); MFI.stackifyVReg(NewReg); } return Changed; }
void RegAllocFast::allocVirtRegUndef(MachineOperand &MO) { assert(MO.isUndef() && "expected undef use"); unsigned VirtReg = MO.getReg(); assert(TargetRegisterInfo::isVirtualRegister(VirtReg) && "Expected virtreg"); LiveRegMap::const_iterator LRI = findLiveVirtReg(VirtReg); MCPhysReg PhysReg; if (LRI != LiveVirtRegs.end() && LRI->PhysReg) { PhysReg = LRI->PhysReg; } else { const TargetRegisterClass &RC = *MRI->getRegClass(VirtReg); ArrayRef<MCPhysReg> AllocationOrder = RegClassInfo.getOrder(&RC); assert(!AllocationOrder.empty() && "Allocation order must not be empty"); PhysReg = AllocationOrder[0]; } unsigned SubRegIdx = MO.getSubReg(); if (SubRegIdx != 0) { PhysReg = TRI->getSubReg(PhysReg, SubRegIdx); MO.setSubReg(0); } MO.setReg(PhysReg); MO.setIsRenamable(true); }
/// optimizeExtInstr - If instruction is a copy-like instruction, i.e. it reads /// a single register and writes a single register and it does not modify the /// source, and if the source value is preserved as a sub-register of the /// result, then replace all reachable uses of the source with the subreg of the /// result. /// /// Do not generate an EXTRACT that is used only in a debug use, as this changes /// the code. Since this code does not currently share EXTRACTs, just ignore all /// debug uses. bool PeepholeOptimizer:: optimizeExtInstr(MachineInstr *MI, MachineBasicBlock *MBB, SmallPtrSet<MachineInstr*, 8> &LocalMIs) { unsigned SrcReg, DstReg, SubIdx; if (!TII->isCoalescableExtInstr(*MI, SrcReg, DstReg, SubIdx)) return false; if (TargetRegisterInfo::isPhysicalRegister(DstReg) || TargetRegisterInfo::isPhysicalRegister(SrcReg)) return false; if (MRI->hasOneNonDBGUse(SrcReg)) // No other uses. return false; // Ensure DstReg can get a register class that actually supports // sub-registers. Don't change the class until we commit. const TargetRegisterClass *DstRC = MRI->getRegClass(DstReg); DstRC = TM->getRegisterInfo()->getSubClassWithSubReg(DstRC, SubIdx); if (!DstRC) return false; // The ext instr may be operating on a sub-register of SrcReg as well. // PPC::EXTSW is a 32 -> 64-bit sign extension, but it reads a 64-bit // register. // If UseSrcSubIdx is Set, SubIdx also applies to SrcReg, and only uses of // SrcReg:SubIdx should be replaced. bool UseSrcSubIdx = TM->getRegisterInfo()-> getSubClassWithSubReg(MRI->getRegClass(SrcReg), SubIdx) != 0; // The source has other uses. See if we can replace the other uses with use of // the result of the extension. SmallPtrSet<MachineBasicBlock*, 4> ReachedBBs; for (MachineRegisterInfo::use_nodbg_iterator UI = MRI->use_nodbg_begin(DstReg), UE = MRI->use_nodbg_end(); UI != UE; ++UI) ReachedBBs.insert(UI->getParent()); // Uses that are in the same BB of uses of the result of the instruction. SmallVector<MachineOperand*, 8> Uses; // Uses that the result of the instruction can reach. SmallVector<MachineOperand*, 8> ExtendedUses; bool ExtendLife = true; for (MachineRegisterInfo::use_nodbg_iterator UI = MRI->use_nodbg_begin(SrcReg), UE = MRI->use_nodbg_end(); UI != UE; ++UI) { MachineOperand &UseMO = UI.getOperand(); MachineInstr *UseMI = &*UI; if (UseMI == MI) continue; if (UseMI->isPHI()) { ExtendLife = false; continue; } // Only accept uses of SrcReg:SubIdx. if (UseSrcSubIdx && UseMO.getSubReg() != SubIdx) continue; // It's an error to translate this: // // %reg1025 = <sext> %reg1024 // ... // %reg1026 = SUBREG_TO_REG 0, %reg1024, 4 // // into this: // // %reg1025 = <sext> %reg1024 // ... // %reg1027 = COPY %reg1025:4 // %reg1026 = SUBREG_TO_REG 0, %reg1027, 4 // // The problem here is that SUBREG_TO_REG is there to assert that an // implicit zext occurs. It doesn't insert a zext instruction. If we allow // the COPY here, it will give us the value after the <sext>, not the // original value of %reg1024 before <sext>. if (UseMI->getOpcode() == TargetOpcode::SUBREG_TO_REG) continue; MachineBasicBlock *UseMBB = UseMI->getParent(); if (UseMBB == MBB) { // Local uses that come after the extension. if (!LocalMIs.count(UseMI)) Uses.push_back(&UseMO); } else if (ReachedBBs.count(UseMBB)) { // Non-local uses where the result of the extension is used. Always // replace these unless it's a PHI. Uses.push_back(&UseMO); } else if (Aggressive && DT->dominates(MBB, UseMBB)) { // We may want to extend the live range of the extension result in order // to replace these uses. ExtendedUses.push_back(&UseMO); } else { // Both will be live out of the def MBB anyway. Don't extend live range of // the extension result. ExtendLife = false; break; } } if (ExtendLife && !ExtendedUses.empty()) // Extend the liveness of the extension result. std::copy(ExtendedUses.begin(), ExtendedUses.end(), std::back_inserter(Uses)); // Now replace all uses. bool Changed = false; if (!Uses.empty()) { SmallPtrSet<MachineBasicBlock*, 4> PHIBBs; // Look for PHI uses of the extended result, we don't want to extend the // liveness of a PHI input. It breaks all kinds of assumptions down // stream. A PHI use is expected to be the kill of its source values. for (MachineRegisterInfo::use_nodbg_iterator UI = MRI->use_nodbg_begin(DstReg), UE = MRI->use_nodbg_end(); UI != UE; ++UI) if (UI->isPHI()) PHIBBs.insert(UI->getParent()); const TargetRegisterClass *RC = MRI->getRegClass(SrcReg); for (unsigned i = 0, e = Uses.size(); i != e; ++i) { MachineOperand *UseMO = Uses[i]; MachineInstr *UseMI = UseMO->getParent(); MachineBasicBlock *UseMBB = UseMI->getParent(); if (PHIBBs.count(UseMBB)) continue; // About to add uses of DstReg, clear DstReg's kill flags. if (!Changed) { MRI->clearKillFlags(DstReg); MRI->constrainRegClass(DstReg, DstRC); } unsigned NewVR = MRI->createVirtualRegister(RC); MachineInstr *Copy = BuildMI(*UseMBB, UseMI, UseMI->getDebugLoc(), TII->get(TargetOpcode::COPY), NewVR) .addReg(DstReg, 0, SubIdx); // SubIdx applies to both SrcReg and DstReg when UseSrcSubIdx is set. if (UseSrcSubIdx) { Copy->getOperand(0).setSubReg(SubIdx); Copy->getOperand(0).setIsUndef(); } UseMO->setReg(NewVR); ++NumReuse; Changed = true; } } return Changed; }
/// OptimizeInstr - If instruction is a copy-like instruction, i.e. it reads /// a single register and writes a single register and it does not modify /// the source, and if the source value is preserved as a sub-register of /// the result, then replace all reachable uses of the source with the subreg /// of the result. /// Do not generate an EXTRACT that is used only in a debug use, as this /// changes the code. Since this code does not currently share EXTRACTs, just /// ignore all debug uses. bool OptimizeExts::OptimizeInstr(MachineInstr *MI, MachineBasicBlock *MBB, SmallPtrSet<MachineInstr*, 8> &LocalMIs) { bool Changed = false; LocalMIs.insert(MI); unsigned SrcReg, DstReg, SubIdx; if (TII->isCoalescableExtInstr(*MI, SrcReg, DstReg, SubIdx)) { if (TargetRegisterInfo::isPhysicalRegister(DstReg) || TargetRegisterInfo::isPhysicalRegister(SrcReg)) return false; MachineRegisterInfo::use_nodbg_iterator UI = MRI->use_nodbg_begin(SrcReg); if (++UI == MRI->use_nodbg_end()) // No other uses. return false; // Ok, the source has other uses. See if we can replace the other uses // with use of the result of the extension. SmallPtrSet<MachineBasicBlock*, 4> ReachedBBs; UI = MRI->use_nodbg_begin(DstReg); for (MachineRegisterInfo::use_nodbg_iterator UE = MRI->use_nodbg_end(); UI != UE; ++UI) ReachedBBs.insert(UI->getParent()); bool ExtendLife = true; // Uses that are in the same BB of uses of the result of the instruction. SmallVector<MachineOperand*, 8> Uses; // Uses that the result of the instruction can reach. SmallVector<MachineOperand*, 8> ExtendedUses; UI = MRI->use_nodbg_begin(SrcReg); for (MachineRegisterInfo::use_nodbg_iterator UE = MRI->use_nodbg_end(); UI != UE; ++UI) { MachineOperand &UseMO = UI.getOperand(); MachineInstr *UseMI = &*UI; if (UseMI == MI) continue; if (UseMI->isPHI()) { ExtendLife = false; continue; } // It's an error to translate this: // // %reg1025 = <sext> %reg1024 // ... // %reg1026 = SUBREG_TO_REG 0, %reg1024, 4 // // into this: // // %reg1025 = <sext> %reg1024 // ... // %reg1027 = COPY %reg1025:4 // %reg1026 = SUBREG_TO_REG 0, %reg1027, 4 // // The problem here is that SUBREG_TO_REG is there to assert that an // implicit zext occurs. It doesn't insert a zext instruction. If we allow // the COPY here, it will give us the value after the <sext>, // not the original value of %reg1024 before <sext>. if (UseMI->getOpcode() == TargetOpcode::SUBREG_TO_REG) continue; MachineBasicBlock *UseMBB = UseMI->getParent(); if (UseMBB == MBB) { // Local uses that come after the extension. if (!LocalMIs.count(UseMI)) Uses.push_back(&UseMO); } else if (ReachedBBs.count(UseMBB)) // Non-local uses where the result of extension is used. Always // replace these unless it's a PHI. Uses.push_back(&UseMO); else if (Aggressive && DT->dominates(MBB, UseMBB)) // We may want to extend live range of the extension result in order // to replace these uses. ExtendedUses.push_back(&UseMO); else { // Both will be live out of the def MBB anyway. Don't extend live // range of the extension result. ExtendLife = false; break; } } if (ExtendLife && !ExtendedUses.empty()) // Ok, we'll extend the liveness of the extension result. std::copy(ExtendedUses.begin(), ExtendedUses.end(), std::back_inserter(Uses)); // Now replace all uses. if (!Uses.empty()) { SmallPtrSet<MachineBasicBlock*, 4> PHIBBs; // Look for PHI uses of the extended result, we don't want to extend the // liveness of a PHI input. It breaks all kinds of assumptions down // stream. A PHI use is expected to be the kill of its source values. UI = MRI->use_nodbg_begin(DstReg); for (MachineRegisterInfo::use_nodbg_iterator UE = MRI->use_nodbg_end(); UI != UE; ++UI) if (UI->isPHI()) PHIBBs.insert(UI->getParent()); const TargetRegisterClass *RC = MRI->getRegClass(SrcReg); for (unsigned i = 0, e = Uses.size(); i != e; ++i) { MachineOperand *UseMO = Uses[i]; MachineInstr *UseMI = UseMO->getParent(); MachineBasicBlock *UseMBB = UseMI->getParent(); if (PHIBBs.count(UseMBB)) continue; unsigned NewVR = MRI->createVirtualRegister(RC); BuildMI(*UseMBB, UseMI, UseMI->getDebugLoc(), TII->get(TargetOpcode::COPY), NewVR) .addReg(DstReg, 0, SubIdx); UseMO->setReg(NewVR); ++NumReuse; Changed = true; } } } return Changed; }