diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2021-02-16 20:13:02 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2021-02-16 20:13:02 +0000 |
| commit | b60736ec1405bb0a8dd40989f67ef4c93da068ab (patch) | |
| tree | 5c43fbb7c9fc45f0f87e0e6795a86267dbd12f9d /llvm/lib/CodeGen/TwoAddressInstructionPass.cpp | |
| parent | cfca06d7963fa0909f90483b42a6d7d194d01e08 (diff) | |
Diffstat (limited to 'llvm/lib/CodeGen/TwoAddressInstructionPass.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/TwoAddressInstructionPass.cpp | 421 |
1 files changed, 138 insertions, 283 deletions
diff --git a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp index de336abe607a..ecee4aed7f88 100644 --- a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -70,7 +70,6 @@ STATISTIC(NumTwoAddressInstrs, "Number of two-address instructions"); STATISTIC(NumCommuted , "Number of instructions commuted to coalesce"); STATISTIC(NumAggrCommuted , "Number of instructions aggressively commuted"); STATISTIC(NumConvertedTo3Addr, "Number of instructions promoted to 3-address"); -STATISTIC(Num3AddrSunk, "Number of 3-address instructions sunk"); STATISTIC(NumReSchedUps, "Number of instructions re-scheduled up"); STATISTIC(NumReSchedDowns, "Number of instructions re-scheduled down"); @@ -109,47 +108,38 @@ class TwoAddressInstructionPass : public MachineFunctionPass { // Set of already processed instructions in the current block. SmallPtrSet<MachineInstr*, 8> Processed; - // Set of instructions converted to three-address by target and then sunk - // down current basic block. - SmallPtrSet<MachineInstr*, 8> SunkInstrs; - // A map from virtual registers to physical registers which are likely targets // to be coalesced to due to copies from physical registers to virtual // registers. e.g. v1024 = move r0. - DenseMap<unsigned, unsigned> SrcRegMap; + DenseMap<Register, Register> SrcRegMap; // A map from virtual registers to physical registers which are likely targets // to be coalesced to due to copies to physical registers from virtual // registers. e.g. r1 = move v1024. - DenseMap<unsigned, unsigned> DstRegMap; - - bool sink3AddrInstruction(MachineInstr *MI, unsigned Reg, - MachineBasicBlock::iterator OldPos); + DenseMap<Register, Register> DstRegMap; - bool isRevCopyChain(unsigned FromReg, unsigned ToReg, int Maxlen); + bool isRevCopyChain(Register FromReg, Register ToReg, int Maxlen); - bool noUseAfterLastDef(unsigned Reg, unsigned Dist, unsigned &LastDef); + bool noUseAfterLastDef(Register Reg, unsigned Dist, unsigned &LastDef); - bool isProfitableToCommute(unsigned regA, unsigned regB, unsigned regC, + bool isProfitableToCommute(Register RegA, Register RegB, Register RegC, MachineInstr *MI, unsigned Dist); bool commuteInstruction(MachineInstr *MI, unsigned DstIdx, unsigned RegBIdx, unsigned RegCIdx, unsigned Dist); - bool isProfitableToConv3Addr(unsigned RegA, unsigned RegB); + bool isProfitableToConv3Addr(Register RegA, Register RegB); bool convertInstTo3Addr(MachineBasicBlock::iterator &mi, - MachineBasicBlock::iterator &nmi, - unsigned RegA, unsigned RegB, unsigned Dist); + MachineBasicBlock::iterator &nmi, Register RegA, + Register RegB, unsigned Dist); - bool isDefTooClose(unsigned Reg, unsigned Dist, MachineInstr *MI); + bool isDefTooClose(Register Reg, unsigned Dist, MachineInstr *MI); bool rescheduleMIBelowKill(MachineBasicBlock::iterator &mi, - MachineBasicBlock::iterator &nmi, - unsigned Reg); + MachineBasicBlock::iterator &nmi, Register Reg); bool rescheduleKillAboveMI(MachineBasicBlock::iterator &mi, - MachineBasicBlock::iterator &nmi, - unsigned Reg); + MachineBasicBlock::iterator &nmi, Register Reg); bool tryInstructionTransform(MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator &nmi, @@ -161,7 +151,7 @@ class TwoAddressInstructionPass : public MachineFunctionPass { unsigned BaseOpIdx, bool BaseOpKilled, unsigned Dist); - void scanUses(unsigned DstReg); + void scanUses(Register DstReg); void processCopy(MachineInstr *MI); @@ -207,140 +197,10 @@ INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) INITIALIZE_PASS_END(TwoAddressInstructionPass, DEBUG_TYPE, "Two-Address instruction pass", false, false) -static bool isPlainlyKilled(MachineInstr *MI, unsigned Reg, LiveIntervals *LIS); - -/// A two-address instruction has been converted to a three-address instruction -/// to avoid clobbering a register. Try to sink it past the instruction that -/// would kill the above mentioned register to reduce register pressure. -bool TwoAddressInstructionPass:: -sink3AddrInstruction(MachineInstr *MI, unsigned SavedReg, - MachineBasicBlock::iterator OldPos) { - // FIXME: Shouldn't we be trying to do this before we three-addressify the - // instruction? After this transformation is done, we no longer need - // the instruction to be in three-address form. - - // Check if it's safe to move this instruction. - bool SeenStore = true; // Be conservative. - if (!MI->isSafeToMove(AA, SeenStore)) - return false; - - unsigned DefReg = 0; - SmallSet<unsigned, 4> UseRegs; - - for (const MachineOperand &MO : MI->operands()) { - if (!MO.isReg()) - continue; - Register MOReg = MO.getReg(); - if (!MOReg) - continue; - if (MO.isUse() && MOReg != SavedReg) - UseRegs.insert(MO.getReg()); - if (!MO.isDef()) - continue; - if (MO.isImplicit()) - // Don't try to move it if it implicitly defines a register. - return false; - if (DefReg) - // For now, don't move any instructions that define multiple registers. - return false; - DefReg = MO.getReg(); - } - - // Find the instruction that kills SavedReg. - MachineInstr *KillMI = nullptr; - if (LIS) { - LiveInterval &LI = LIS->getInterval(SavedReg); - assert(LI.end() != LI.begin() && - "Reg should not have empty live interval."); - - SlotIndex MBBEndIdx = LIS->getMBBEndIdx(MBB).getPrevSlot(); - LiveInterval::const_iterator I = LI.find(MBBEndIdx); - if (I != LI.end() && I->start < MBBEndIdx) - return false; - - --I; - KillMI = LIS->getInstructionFromIndex(I->end); - } - if (!KillMI) { - for (MachineOperand &UseMO : MRI->use_nodbg_operands(SavedReg)) { - if (!UseMO.isKill()) - continue; - KillMI = UseMO.getParent(); - break; - } - } - - // If we find the instruction that kills SavedReg, and it is in an - // appropriate location, we can try to sink the current instruction - // past it. - if (!KillMI || KillMI->getParent() != MBB || KillMI == MI || - MachineBasicBlock::iterator(KillMI) == OldPos || KillMI->isTerminator()) - return false; - - // If any of the definitions are used by another instruction between the - // position and the kill use, then it's not safe to sink it. - // - // FIXME: This can be sped up if there is an easy way to query whether an - // instruction is before or after another instruction. Then we can use - // MachineRegisterInfo def / use instead. - MachineOperand *KillMO = nullptr; - MachineBasicBlock::iterator KillPos = KillMI; - ++KillPos; - - unsigned NumVisited = 0; - for (MachineInstr &OtherMI : make_range(std::next(OldPos), KillPos)) { - // Debug instructions cannot be counted against the limit. - if (OtherMI.isDebugInstr()) - continue; - if (NumVisited > 30) // FIXME: Arbitrary limit to reduce compile time cost. - return false; - ++NumVisited; - for (unsigned i = 0, e = OtherMI.getNumOperands(); i != e; ++i) { - MachineOperand &MO = OtherMI.getOperand(i); - if (!MO.isReg()) - continue; - Register MOReg = MO.getReg(); - if (!MOReg) - continue; - if (DefReg == MOReg) - return false; - - if (MO.isKill() || (LIS && isPlainlyKilled(&OtherMI, MOReg, LIS))) { - if (&OtherMI == KillMI && MOReg == SavedReg) - // Save the operand that kills the register. We want to unset the kill - // marker if we can sink MI past it. - KillMO = &MO; - else if (UseRegs.count(MOReg)) - // One of the uses is killed before the destination. - return false; - } - } - } - assert(KillMO && "Didn't find kill"); - - if (!LIS) { - // Update kill and LV information. - KillMO->setIsKill(false); - KillMO = MI->findRegisterUseOperand(SavedReg, false, TRI); - KillMO->setIsKill(true); - - if (LV) - LV->replaceKillInstruction(SavedReg, *KillMI, *MI); - } - - // Move instruction to its destination. - MBB->remove(MI); - MBB->insert(KillPos, MI); - - if (LIS) - LIS->handleMove(*MI); - - ++Num3AddrSunk; - return true; -} +static bool isPlainlyKilled(MachineInstr *MI, Register Reg, LiveIntervals *LIS); /// Return the MachineInstr* if it is the single def of the Reg in current BB. -static MachineInstr *getSingleDef(unsigned Reg, MachineBasicBlock *BB, +static MachineInstr *getSingleDef(Register Reg, MachineBasicBlock *BB, const MachineRegisterInfo *MRI) { MachineInstr *Ret = nullptr; for (MachineInstr &DefMI : MRI->def_instructions(Reg)) { @@ -361,9 +221,9 @@ static MachineInstr *getSingleDef(unsigned Reg, MachineBasicBlock *BB, /// %Tmp2 = copy %ToReg; /// MaxLen specifies the maximum length of the copy chain the func /// can walk through. -bool TwoAddressInstructionPass::isRevCopyChain(unsigned FromReg, unsigned ToReg, +bool TwoAddressInstructionPass::isRevCopyChain(Register FromReg, Register ToReg, int Maxlen) { - unsigned TmpReg = FromReg; + Register TmpReg = FromReg; for (int i = 0; i < Maxlen; i++) { MachineInstr *Def = getSingleDef(TmpReg, MBB, MRI); if (!Def || !Def->isCopy()) @@ -381,7 +241,7 @@ bool TwoAddressInstructionPass::isRevCopyChain(unsigned FromReg, unsigned ToReg, /// in the MBB that defines the specified register and the two-address /// instruction which is being processed. It also returns the last def location /// by reference. -bool TwoAddressInstructionPass::noUseAfterLastDef(unsigned Reg, unsigned Dist, +bool TwoAddressInstructionPass::noUseAfterLastDef(Register Reg, unsigned Dist, unsigned &LastDef) { LastDef = 0; unsigned LastUse = Dist; @@ -405,8 +265,8 @@ bool TwoAddressInstructionPass::noUseAfterLastDef(unsigned Reg, unsigned Dist, /// instruction. It also returns the source and destination registers and /// whether they are physical registers by reference. static bool isCopyToReg(MachineInstr &MI, const TargetInstrInfo *TII, - unsigned &SrcReg, unsigned &DstReg, - bool &IsSrcPhys, bool &IsDstPhys) { + Register &SrcReg, Register &DstReg, bool &IsSrcPhys, + bool &IsDstPhys) { SrcReg = 0; DstReg = 0; if (MI.isCopy()) { @@ -415,19 +275,20 @@ static bool isCopyToReg(MachineInstr &MI, const TargetInstrInfo *TII, } else if (MI.isInsertSubreg() || MI.isSubregToReg()) { DstReg = MI.getOperand(0).getReg(); SrcReg = MI.getOperand(2).getReg(); - } else + } else { return false; + } - IsSrcPhys = Register::isPhysicalRegister(SrcReg); - IsDstPhys = Register::isPhysicalRegister(DstReg); + IsSrcPhys = SrcReg.isPhysical(); + IsDstPhys = DstReg.isPhysical(); return true; } /// Test if the given register value, which is used by the /// given instruction, is killed by the given instruction. -static bool isPlainlyKilled(MachineInstr *MI, unsigned Reg, +static bool isPlainlyKilled(MachineInstr *MI, Register Reg, LiveIntervals *LIS) { - if (LIS && Register::isVirtualRegister(Reg) && !LIS->isNotInMIMap(*MI)) { + if (LIS && Reg.isVirtual() && !LIS->isNotInMIMap(*MI)) { // FIXME: Sometimes tryInstructionTransform() will add instructions and // test whether they can be folded before keeping them. In this case it // sets a kill before recursively calling tryInstructionTransform() again. @@ -466,20 +327,17 @@ static bool isPlainlyKilled(MachineInstr *MI, unsigned Reg, /// /// If allowFalsePositives is true then likely kills are treated as kills even /// if it can't be proven that they are kills. -static bool isKilled(MachineInstr &MI, unsigned Reg, - const MachineRegisterInfo *MRI, - const TargetInstrInfo *TII, - LiveIntervals *LIS, - bool allowFalsePositives) { +static bool isKilled(MachineInstr &MI, Register Reg, + const MachineRegisterInfo *MRI, const TargetInstrInfo *TII, + LiveIntervals *LIS, bool allowFalsePositives) { MachineInstr *DefMI = &MI; while (true) { // All uses of physical registers are likely to be kills. - if (Register::isPhysicalRegister(Reg) && - (allowFalsePositives || MRI->hasOneUse(Reg))) + if (Reg.isPhysical() && (allowFalsePositives || MRI->hasOneUse(Reg))) return true; if (!isPlainlyKilled(DefMI, Reg, LIS)) return false; - if (Register::isPhysicalRegister(Reg)) + if (Reg.isPhysical()) return true; MachineRegisterInfo::def_iterator Begin = MRI->def_begin(Reg); // If there are multiple defs, we can't do a simple analysis, so just @@ -488,7 +346,7 @@ static bool isKilled(MachineInstr &MI, unsigned Reg, return true; DefMI = Begin->getParent(); bool IsSrcPhys, IsDstPhys; - unsigned SrcReg, DstReg; + Register SrcReg, DstReg; // If the def is something other than a copy, then it isn't going to // be coalesced, so follow the kill flag. if (!isCopyToReg(*DefMI, TII, SrcReg, DstReg, IsSrcPhys, IsDstPhys)) @@ -499,7 +357,7 @@ static bool isKilled(MachineInstr &MI, unsigned Reg, /// Return true if the specified MI uses the specified register as a two-address /// use. If so, return the destination register by reference. -static bool isTwoAddrUse(MachineInstr &MI, unsigned Reg, unsigned &DstReg) { +static bool isTwoAddrUse(MachineInstr &MI, Register Reg, Register &DstReg) { for (unsigned i = 0, NumOps = MI.getNumOperands(); i != NumOps; ++i) { const MachineOperand &MO = MI.getOperand(i); if (!MO.isReg() || !MO.isUse() || MO.getReg() != Reg) @@ -515,19 +373,17 @@ static bool isTwoAddrUse(MachineInstr &MI, unsigned Reg, unsigned &DstReg) { /// Given a register, if has a single in-basic block use, return the use /// instruction if it's a copy or a two-address use. -static -MachineInstr *findOnlyInterestingUse(unsigned Reg, MachineBasicBlock *MBB, - MachineRegisterInfo *MRI, - const TargetInstrInfo *TII, - bool &IsCopy, - unsigned &DstReg, bool &IsDstPhys) { +static MachineInstr * +findOnlyInterestingUse(Register Reg, MachineBasicBlock *MBB, + MachineRegisterInfo *MRI, const TargetInstrInfo *TII, + bool &IsCopy, Register &DstReg, bool &IsDstPhys) { if (!MRI->hasOneNonDBGUse(Reg)) // None or more than one use. return nullptr; MachineInstr &UseMI = *MRI->use_instr_nodbg_begin(Reg); if (UseMI.getParent() != MBB) return nullptr; - unsigned SrcReg; + Register SrcReg; bool IsSrcPhys; if (isCopyToReg(UseMI, TII, SrcReg, DstReg, IsSrcPhys, IsDstPhys)) { IsCopy = true; @@ -535,7 +391,7 @@ MachineInstr *findOnlyInterestingUse(unsigned Reg, MachineBasicBlock *MBB, } IsDstPhys = false; if (isTwoAddrUse(UseMI, Reg, DstReg)) { - IsDstPhys = Register::isPhysicalRegister(DstReg); + IsDstPhys = DstReg.isPhysical(); return &UseMI; } return nullptr; @@ -543,22 +399,22 @@ MachineInstr *findOnlyInterestingUse(unsigned Reg, MachineBasicBlock *MBB, /// Return the physical register the specified virtual register might be mapped /// to. -static unsigned -getMappedReg(unsigned Reg, DenseMap<unsigned, unsigned> &RegMap) { - while (Register::isVirtualRegister(Reg)) { - DenseMap<unsigned, unsigned>::iterator SI = RegMap.find(Reg); +static MCRegister getMappedReg(Register Reg, + DenseMap<Register, Register> &RegMap) { + while (Reg.isVirtual()) { + DenseMap<Register, Register>::iterator SI = RegMap.find(Reg); if (SI == RegMap.end()) return 0; Reg = SI->second; } - if (Register::isPhysicalRegister(Reg)) + if (Reg.isPhysical()) return Reg; return 0; } /// Return true if the two registers are equal or aliased. -static bool -regsAreCompatible(unsigned RegA, unsigned RegB, const TargetRegisterInfo *TRI) { +static bool regsAreCompatible(Register RegA, Register RegB, + const TargetRegisterInfo *TRI) { if (RegA == RegB) return true; if (!RegA || !RegB) @@ -567,7 +423,7 @@ regsAreCompatible(unsigned RegA, unsigned RegB, const TargetRegisterInfo *TRI) { } // Returns true if Reg is equal or aliased to at least one register in Set. -static bool regOverlapsSet(const SmallVectorImpl<unsigned> &Set, unsigned Reg, +static bool regOverlapsSet(const SmallVectorImpl<Register> &Set, Register Reg, const TargetRegisterInfo *TRI) { for (unsigned R : Set) if (TRI->regsOverlap(R, Reg)) @@ -578,10 +434,11 @@ static bool regOverlapsSet(const SmallVectorImpl<unsigned> &Set, unsigned Reg, /// Return true if it's potentially profitable to commute the two-address /// instruction that's being processed. -bool -TwoAddressInstructionPass:: -isProfitableToCommute(unsigned regA, unsigned regB, unsigned regC, - MachineInstr *MI, unsigned Dist) { +bool TwoAddressInstructionPass::isProfitableToCommute(Register RegA, + Register RegB, + Register RegC, + MachineInstr *MI, + unsigned Dist) { if (OptLevel == CodeGenOpt::None) return false; @@ -603,7 +460,7 @@ isProfitableToCommute(unsigned regA, unsigned regB, unsigned regC, // insert => %reg1030 = COPY %reg1029 // %reg1030 = ADD8rr killed %reg1029, killed %reg1028, implicit dead %eflags - if (!isPlainlyKilled(MI, regC, LIS)) + if (!isPlainlyKilled(MI, RegC, LIS)) return false; // Ok, we have something like: @@ -616,10 +473,10 @@ isProfitableToCommute(unsigned regA, unsigned regB, unsigned regC, // %reg1026 = ADD %reg1024, %reg1025 // r0 = MOV %reg1026 // Commute the ADD to hopefully eliminate an otherwise unavoidable copy. - unsigned ToRegA = getMappedReg(regA, DstRegMap); + MCRegister ToRegA = getMappedReg(RegA, DstRegMap); if (ToRegA) { - unsigned FromRegB = getMappedReg(regB, SrcRegMap); - unsigned FromRegC = getMappedReg(regC, SrcRegMap); + MCRegister FromRegB = getMappedReg(RegB, SrcRegMap); + MCRegister FromRegC = getMappedReg(RegC, SrcRegMap); bool CompB = FromRegB && regsAreCompatible(FromRegB, ToRegA, TRI); bool CompC = FromRegC && regsAreCompatible(FromRegC, ToRegA, TRI); @@ -637,16 +494,16 @@ isProfitableToCommute(unsigned regA, unsigned regB, unsigned regC, return false; } - // If there is a use of regC between its last def (could be livein) and this + // If there is a use of RegC between its last def (could be livein) and this // instruction, then bail. unsigned LastDefC = 0; - if (!noUseAfterLastDef(regC, Dist, LastDefC)) + if (!noUseAfterLastDef(RegC, Dist, LastDefC)) return false; - // If there is a use of regB between its last def (could be livein) and this + // If there is a use of RegB between its last def (could be livein) and this // instruction, then go ahead and make this transformation. unsigned LastDefB = 0; - if (!noUseAfterLastDef(regB, Dist, LastDefB)) + if (!noUseAfterLastDef(RegB, Dist, LastDefB)) return true; // Look for situation like this: @@ -664,14 +521,14 @@ isProfitableToCommute(unsigned regA, unsigned regB, unsigned regC, // To more generally minimize register copies, ideally the logic of two addr // instruction pass should be integrated with register allocation pass where // interference graph is available. - if (isRevCopyChain(regC, regA, MaxDataFlowEdge)) + if (isRevCopyChain(RegC, RegA, MaxDataFlowEdge)) return true; - if (isRevCopyChain(regB, regA, MaxDataFlowEdge)) + if (isRevCopyChain(RegB, RegA, MaxDataFlowEdge)) return false; // Since there are no intervening uses for both registers, then commute - // if the def of regC is closer. Its live interval is shorter. + // if the def of RegC is closer. Its live interval is shorter. return LastDefB && LastDefC && LastDefC > LastDefB; } @@ -697,7 +554,7 @@ bool TwoAddressInstructionPass::commuteInstruction(MachineInstr *MI, "instruction unless it was requested."); // Update source register map. - unsigned FromRegC = getMappedReg(RegC, SrcRegMap); + MCRegister FromRegC = getMappedReg(RegC, SrcRegMap); if (FromRegC) { Register RegA = MI->getOperand(DstIdx).getReg(); SrcRegMap[RegA] = FromRegC; @@ -708,28 +565,26 @@ bool TwoAddressInstructionPass::commuteInstruction(MachineInstr *MI, /// Return true if it is profitable to convert the given 2-address instruction /// to a 3-address one. -bool -TwoAddressInstructionPass::isProfitableToConv3Addr(unsigned RegA,unsigned RegB){ +bool TwoAddressInstructionPass::isProfitableToConv3Addr(Register RegA, + Register RegB) { // Look for situations like this: // %reg1024 = MOV r1 // %reg1025 = MOV r0 // %reg1026 = ADD %reg1024, %reg1025 // r2 = MOV %reg1026 // Turn ADD into a 3-address instruction to avoid a copy. - unsigned FromRegB = getMappedReg(RegB, SrcRegMap); + MCRegister FromRegB = getMappedReg(RegB, SrcRegMap); if (!FromRegB) return false; - unsigned ToRegA = getMappedReg(RegA, DstRegMap); + MCRegister ToRegA = getMappedReg(RegA, DstRegMap); return (ToRegA && !regsAreCompatible(FromRegB, ToRegA, TRI)); } /// Convert the specified two-address instruction into a three address one. /// Return true if this transformation was successful. -bool -TwoAddressInstructionPass::convertInstTo3Addr(MachineBasicBlock::iterator &mi, - MachineBasicBlock::iterator &nmi, - unsigned RegA, unsigned RegB, - unsigned Dist) { +bool TwoAddressInstructionPass::convertInstTo3Addr( + MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator &nmi, + Register RegA, Register RegB, unsigned Dist) { // FIXME: Why does convertToThreeAddress() need an iterator reference? MachineFunction::iterator MFI = MBB->getIterator(); MachineInstr *NewMI = TII->convertToThreeAddress(MFI, *mi, LV); @@ -740,26 +595,33 @@ TwoAddressInstructionPass::convertInstTo3Addr(MachineBasicBlock::iterator &mi, LLVM_DEBUG(dbgs() << "2addr: CONVERTING 2-ADDR: " << *mi); LLVM_DEBUG(dbgs() << "2addr: TO 3-ADDR: " << *NewMI); - bool Sunk = false; if (LIS) LIS->ReplaceMachineInstrInMaps(*mi, *NewMI); - if (NewMI->findRegisterUseOperand(RegB, false, TRI)) - // FIXME: Temporary workaround. If the new instruction doesn't - // uses RegB, convertToThreeAddress must have created more - // then one instruction. - Sunk = sink3AddrInstruction(NewMI, RegB, mi); + // If the old instruction is debug value tracked, an update is required. + if (auto OldInstrNum = mi->peekDebugInstrNum()) { + // Sanity check. + assert(mi->getNumExplicitDefs() == 1); + assert(NewMI->getNumExplicitDefs() == 1); - MBB->erase(mi); // Nuke the old inst. + // Find the old and new def location. + auto OldIt = mi->defs().begin(); + auto NewIt = NewMI->defs().begin(); + unsigned OldIdx = mi->getOperandNo(OldIt); + unsigned NewIdx = NewMI->getOperandNo(NewIt); - if (!Sunk) { - DistanceMap.insert(std::make_pair(NewMI, Dist)); - mi = NewMI; - nmi = std::next(mi); + // Record that one def has been replaced by the other. + unsigned NewInstrNum = NewMI->getDebugInstrNum(); + MF->makeDebugValueSubstitution(std::make_pair(OldInstrNum, OldIdx), + std::make_pair(NewInstrNum, NewIdx)); } - else - SunkInstrs.insert(NewMI); + + MBB->erase(mi); // Nuke the old inst. + + DistanceMap.insert(std::make_pair(NewMI, Dist)); + mi = NewMI; + nmi = std::next(mi); // Update source and destination register maps. SrcRegMap.erase(RegA); @@ -769,13 +631,12 @@ TwoAddressInstructionPass::convertInstTo3Addr(MachineBasicBlock::iterator &mi, /// Scan forward recursively for only uses, update maps if the use is a copy or /// a two-address instruction. -void -TwoAddressInstructionPass::scanUses(unsigned DstReg) { - SmallVector<unsigned, 4> VirtRegPairs; +void TwoAddressInstructionPass::scanUses(Register DstReg) { + SmallVector<Register, 4> VirtRegPairs; bool IsDstPhys; bool IsCopy = false; - unsigned NewReg = 0; - unsigned Reg = DstReg; + Register NewReg; + Register Reg = DstReg; while (MachineInstr *UseMI = findOnlyInterestingUse(Reg, MBB, MRI, TII,IsCopy, NewReg, IsDstPhys)) { if (IsCopy && !Processed.insert(UseMI).second) @@ -831,13 +692,13 @@ void TwoAddressInstructionPass::processCopy(MachineInstr *MI) { return; bool IsSrcPhys, IsDstPhys; - unsigned SrcReg, DstReg; + Register SrcReg, DstReg; if (!isCopyToReg(*MI, TII, SrcReg, DstReg, IsSrcPhys, IsDstPhys)) return; - if (IsDstPhys && !IsSrcPhys) + if (IsDstPhys && !IsSrcPhys) { DstRegMap.insert(std::make_pair(SrcReg, DstReg)); - else if (!IsDstPhys && IsSrcPhys) { + } else if (!IsDstPhys && IsSrcPhys) { bool isNew = SrcRegMap.insert(std::make_pair(DstReg, SrcReg)).second; if (!isNew) assert(SrcRegMap[DstReg] == SrcReg && @@ -852,10 +713,9 @@ void TwoAddressInstructionPass::processCopy(MachineInstr *MI) { /// If there is one more local instruction that reads 'Reg' and it kills 'Reg, /// consider moving the instruction below the kill instruction in order to /// eliminate the need for the copy. -bool TwoAddressInstructionPass:: -rescheduleMIBelowKill(MachineBasicBlock::iterator &mi, - MachineBasicBlock::iterator &nmi, - unsigned Reg) { +bool TwoAddressInstructionPass::rescheduleMIBelowKill( + MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator &nmi, + Register Reg) { // Bail immediately if we don't have LV or LIS available. We use them to find // kills efficiently. if (!LV && !LIS) @@ -892,7 +752,7 @@ rescheduleMIBelowKill(MachineBasicBlock::iterator &mi, // Don't move pass calls, etc. return false; - unsigned DstReg; + Register DstReg; if (isTwoAddrUse(*KillMI, Reg, DstReg)) return false; @@ -904,9 +764,9 @@ rescheduleMIBelowKill(MachineBasicBlock::iterator &mi, // FIXME: Needs more sophisticated heuristics. return false; - SmallVector<unsigned, 2> Uses; - SmallVector<unsigned, 2> Kills; - SmallVector<unsigned, 2> Defs; + SmallVector<Register, 2> Uses; + SmallVector<Register, 2> Kills; + SmallVector<Register, 2> Defs; for (const MachineOperand &MO : MI->operands()) { if (!MO.isReg()) continue; @@ -1021,7 +881,7 @@ rescheduleMIBelowKill(MachineBasicBlock::iterator &mi, /// Return true if the re-scheduling will put the given instruction too close /// to the defs of its register dependencies. -bool TwoAddressInstructionPass::isDefTooClose(unsigned Reg, unsigned Dist, +bool TwoAddressInstructionPass::isDefTooClose(Register Reg, unsigned Dist, MachineInstr *MI) { for (MachineInstr &DefMI : MRI->def_instructions(Reg)) { if (DefMI.getParent() != MBB || DefMI.isCopy() || DefMI.isCopyLike()) @@ -1042,10 +902,9 @@ bool TwoAddressInstructionPass::isDefTooClose(unsigned Reg, unsigned Dist, /// If there is one more local instruction that reads 'Reg' and it kills 'Reg, /// consider moving the kill instruction above the current two-address /// instruction in order to eliminate the need for the copy. -bool TwoAddressInstructionPass:: -rescheduleKillAboveMI(MachineBasicBlock::iterator &mi, - MachineBasicBlock::iterator &nmi, - unsigned Reg) { +bool TwoAddressInstructionPass::rescheduleKillAboveMI( + MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator &nmi, + Register Reg) { // Bail immediately if we don't have LV or LIS available. We use them to find // kills efficiently. if (!LV && !LIS) @@ -1077,7 +936,7 @@ rescheduleKillAboveMI(MachineBasicBlock::iterator &mi, // Don't mess with copies, they may be coalesced later. return false; - unsigned DstReg; + Register DstReg; if (isTwoAddrUse(*KillMI, Reg, DstReg)) return false; @@ -1085,10 +944,10 @@ rescheduleKillAboveMI(MachineBasicBlock::iterator &mi, if (!KillMI->isSafeToMove(AA, SeenStore)) return false; - SmallSet<unsigned, 2> Uses; - SmallSet<unsigned, 2> Kills; - SmallSet<unsigned, 2> Defs; - SmallSet<unsigned, 2> LiveDefs; + SmallVector<Register, 2> Uses; + SmallVector<Register, 2> Kills; + SmallVector<Register, 2> Defs; + SmallVector<Register, 2> LiveDefs; for (const MachineOperand &MO : KillMI->operands()) { if (!MO.isReg()) continue; @@ -1101,13 +960,13 @@ rescheduleKillAboveMI(MachineBasicBlock::iterator &mi, bool isKill = MO.isKill() || (LIS && isPlainlyKilled(KillMI, MOReg, LIS)); if (MOReg == Reg && !isKill) return false; - Uses.insert(MOReg); + Uses.push_back(MOReg); if (isKill && MOReg != Reg) - Kills.insert(MOReg); - } else if (Register::isPhysicalRegister(MOReg)) { - Defs.insert(MOReg); + Kills.push_back(MOReg); + } else if (MOReg.isPhysical()) { + Defs.push_back(MOReg); if (!MO.isDead()) - LiveDefs.insert(MOReg); + LiveDefs.push_back(MOReg); } } @@ -1125,7 +984,7 @@ rescheduleKillAboveMI(MachineBasicBlock::iterator &mi, OtherMI.isBranch() || OtherMI.isTerminator()) // Don't move pass calls, etc. return false; - SmallVector<unsigned, 2> OtherDefs; + SmallVector<Register, 2> OtherDefs; for (const MachineOperand &MO : OtherMI.operands()) { if (!MO.isReg()) continue; @@ -1133,11 +992,11 @@ rescheduleKillAboveMI(MachineBasicBlock::iterator &mi, if (!MOReg) continue; if (MO.isUse()) { - if (Defs.count(MOReg)) + if (regOverlapsSet(Defs, MOReg, TRI)) // Moving KillMI can clobber the physical register if the def has // not been seen. return false; - if (Kills.count(MOReg)) + if (regOverlapsSet(Kills, MOReg, TRI)) // Don't want to extend other live ranges and update kills. return false; if (&OtherMI != MI && MOReg == Reg && @@ -1150,13 +1009,13 @@ rescheduleKillAboveMI(MachineBasicBlock::iterator &mi, } for (unsigned i = 0, e = OtherDefs.size(); i != e; ++i) { - unsigned MOReg = OtherDefs[i]; - if (Uses.count(MOReg)) + Register MOReg = OtherDefs[i]; + if (regOverlapsSet(Uses, MOReg, TRI)) return false; - if (Register::isPhysicalRegister(MOReg) && LiveDefs.count(MOReg)) + if (MOReg.isPhysical() && regOverlapsSet(LiveDefs, MOReg, TRI)) return false; // Physical register def is seen. - Defs.erase(MOReg); + llvm::erase_value(Defs, MOReg); } } @@ -1274,11 +1133,10 @@ tryInstructionTransform(MachineBasicBlock::iterator &mi, Register regA = MI.getOperand(DstIdx).getReg(); Register regB = MI.getOperand(SrcIdx).getReg(); - assert(Register::isVirtualRegister(regB) && - "cannot make instruction into two-address form"); + assert(regB.isVirtual() && "cannot make instruction into two-address form"); bool regBKilled = isKilled(MI, regB, MRI, TII, LIS, true); - if (Register::isVirtualRegister(regA)) + if (regA.isVirtual()) scanUses(regA); bool Commuted = tryInstructionCommute(&MI, DstIdx, SrcIdx, regBKilled, Dist); @@ -1394,7 +1252,7 @@ tryInstructionTransform(MachineBasicBlock::iterator &mi, if (LV) { for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { MachineOperand &MO = MI.getOperand(i); - if (MO.isReg() && Register::isVirtualRegister(MO.getReg())) { + if (MO.isReg() && MO.getReg().isVirtual()) { if (MO.isUse()) { if (MO.isKill()) { if (NewMIs[0]->killsRegister(MO.getReg())) @@ -1479,7 +1337,7 @@ collectTiedOperands(MachineInstr *MI, TiedOperandMap &TiedOperands) { // Deal with undef uses immediately - simply rewrite the src operand. if (SrcMO.isUndef() && !DstMO.getSubReg()) { // Constrain the DstReg register class if required. - if (Register::isVirtualRegister(DstReg)) + if (DstReg.isVirtual()) if (const TargetRegisterClass *RC = TII->getRegClass(MCID, SrcIdx, TRI, *MF)) MRI->constrainRegClass(DstReg, RC); @@ -1509,7 +1367,7 @@ TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI, bool AllUsesCopied = true; unsigned LastCopiedReg = 0; SlotIndex LastCopyIdx; - unsigned RegB = 0; + Register RegB = 0; unsigned SubRegB = 0; for (unsigned tpi = 0, tpe = TiedPairs.size(); tpi != tpe; ++tpi) { unsigned SrcIdx = TiedPairs[tpi].first; @@ -1532,8 +1390,7 @@ TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI, } LastCopiedReg = RegA; - assert(Register::isVirtualRegister(RegB) && - "cannot make instruction into two-address form"); + assert(RegB.isVirtual() && "cannot make instruction into two-address form"); #ifndef NDEBUG // First, verify that we don't have a use of "a" in the instruction @@ -1553,7 +1410,7 @@ TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI, MIB.addReg(RegB, 0, SubRegB); const TargetRegisterClass *RC = MRI->getRegClass(RegB); if (SubRegB) { - if (Register::isVirtualRegister(RegA)) { + if (RegA.isVirtual()) { assert(TRI->getMatchingSuperRegClass(RC, MRI->getRegClass(RegA), SubRegB) && "tied subregister must be a truncation"); @@ -1574,7 +1431,7 @@ TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI, if (LIS) { LastCopyIdx = LIS->InsertMachineInstrInMaps(*PrevMI).getRegSlot(); - if (Register::isVirtualRegister(RegA)) { + if (RegA.isVirtual()) { LiveInterval &LI = LIS->getInterval(RegA); VNInfo *VNI = LI.getNextValue(LastCopyIdx, LIS->getVNInfoAllocator()); SlotIndex endIdx = @@ -1594,7 +1451,7 @@ TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI, } // Make sure regA is a legal regclass for the SrcIdx operand. - if (Register::isVirtualRegister(RegA) && Register::isVirtualRegister(RegB)) + if (RegA.isVirtual() && RegB.isVirtual()) MRI->constrainRegClass(RegA, RC); MO.setReg(RegA); // The getMatchingSuper asserts guarantee that the register class projected @@ -1700,13 +1557,11 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &Func) { SrcRegMap.clear(); DstRegMap.clear(); Processed.clear(); - SunkInstrs.clear(); for (MachineBasicBlock::iterator mi = MBB->begin(), me = MBB->end(); mi != me; ) { MachineBasicBlock::iterator nmi = std::next(mi); - // Don't revisit an instruction previously converted by target. It may - // contain undef register operands (%noreg), which are not handled. - if (mi->isDebugInstr() || SunkInstrs.count(&*mi)) { + // Skip debug instructions. + if (mi->isDebugInstr()) { mi = nmi; continue; } @@ -1800,7 +1655,7 @@ void TwoAddressInstructionPass:: eliminateRegSequence(MachineBasicBlock::iterator &MBBI) { MachineInstr &MI = *MBBI; Register DstReg = MI.getOperand(0).getReg(); - if (MI.getOperand(0).getSubReg() || Register::isPhysicalRegister(DstReg) || + if (MI.getOperand(0).getSubReg() || DstReg.isPhysical() || !(MI.getNumOperands() & 1)) { LLVM_DEBUG(dbgs() << "Illegal REG_SEQUENCE instruction:" << MI); llvm_unreachable(nullptr); @@ -1850,7 +1705,7 @@ eliminateRegSequence(MachineBasicBlock::iterator &MBBI) { DefEmitted = true; // Update LiveVariables' kill info. - if (LV && isKill && !Register::isPhysicalRegister(SrcReg)) + if (LV && isKill && !SrcReg.isPhysical()) LV->replaceKillInstruction(SrcReg, MI, *CopyMI); LLVM_DEBUG(dbgs() << "Inserted: " << *CopyMI); |
