diff options
Diffstat (limited to 'lib/CodeGen/RegisterCoalescer.cpp')
-rw-r--r-- | lib/CodeGen/RegisterCoalescer.cpp | 108 |
1 files changed, 62 insertions, 46 deletions
diff --git a/lib/CodeGen/RegisterCoalescer.cpp b/lib/CodeGen/RegisterCoalescer.cpp index 65b0528..2d2dc92 100644 --- a/lib/CodeGen/RegisterCoalescer.cpp +++ b/lib/CodeGen/RegisterCoalescer.cpp @@ -94,11 +94,11 @@ namespace { /// blocks exclusively containing copies. bool JoinSplitEdges; - /// WorkList - Copy instructions yet to be coalesced. + /// Copy instructions yet to be coalesced. SmallVector<MachineInstr*, 8> WorkList; SmallVector<MachineInstr*, 8> LocalWorkList; - /// ErasedInstrs - Set of instruction pointers that have been erased, and + /// Set of instruction pointers that have been erased, and /// that may be present in WorkList. SmallPtrSet<MachineInstr*, 8> ErasedInstrs; @@ -114,21 +114,21 @@ namespace { /// LiveRangeEdit callback. void LRE_WillEraseInstruction(MachineInstr *MI) override; - /// coalesceLocals - coalesce the LocalWorkList. + /// Coalesce the LocalWorkList. void coalesceLocals(); - /// joinAllIntervals - join compatible live intervals + /// Join compatible live intervals void joinAllIntervals(); - /// copyCoalesceInMBB - Coalesce copies in the specified MBB, putting + /// Coalesce copies in the specified MBB, putting /// copies that cannot yet be coalesced into WorkList. void copyCoalesceInMBB(MachineBasicBlock *MBB); - /// copyCoalesceWorkList - Try to coalesce all copies in CurrList. Return + /// Try to coalesce all copies in CurrList. Return /// true if any progress was made. bool copyCoalesceWorkList(MutableArrayRef<MachineInstr*> CurrList); - /// joinCopy - Attempt to join intervals corresponding to SrcReg/DstReg, + /// Attempt to join intervals corresponding to SrcReg/DstReg, /// which are the src/dst of the copy instruction CopyMI. This returns /// true if the copy was successfully coalesced away. If it is not /// currently possible to coalesce this interval, but it may be possible if @@ -136,7 +136,7 @@ namespace { /// 'Again'. bool joinCopy(MachineInstr *TheCopy, bool &Again); - /// joinIntervals - Attempt to join these two intervals. On failure, this + /// Attempt to join these two intervals. On failure, this /// returns false. The output "SrcInt" will not have been modified, so we /// can use this information below to update aliases. bool joinIntervals(CoalescerPair &CP); @@ -147,39 +147,39 @@ namespace { /// Attempt joining with a reserved physreg. bool joinReservedPhysReg(CoalescerPair &CP); - /// adjustCopiesBackFrom - We found a non-trivially-coalescable copy. If + /// We found a non-trivially-coalescable copy. If /// the source value number is defined by a copy from the destination reg /// see if we can merge these two destination reg valno# into a single /// value number, eliminating a copy. bool adjustCopiesBackFrom(const CoalescerPair &CP, MachineInstr *CopyMI); - /// hasOtherReachingDefs - Return true if there are definitions of IntB + /// Return true if there are definitions of IntB /// other than BValNo val# that can reach uses of AValno val# of IntA. bool hasOtherReachingDefs(LiveInterval &IntA, LiveInterval &IntB, VNInfo *AValNo, VNInfo *BValNo); - /// removeCopyByCommutingDef - We found a non-trivially-coalescable copy. + /// We found a non-trivially-coalescable copy. /// If the source value number is defined by a commutable instruction and /// its other operand is coalesced to the copy dest register, see if we /// can transform the copy into a noop by commuting the definition. bool removeCopyByCommutingDef(const CoalescerPair &CP,MachineInstr *CopyMI); - /// reMaterializeTrivialDef - If the source of a copy is defined by a + /// If the source of a copy is defined by a /// trivial computation, replace the copy by rematerialize the definition. bool reMaterializeTrivialDef(CoalescerPair &CP, MachineInstr *CopyMI, bool &IsDefCopy); - /// canJoinPhys - Return true if a physreg copy should be joined. + /// Return true if a physreg copy should be joined. bool canJoinPhys(const CoalescerPair &CP); - /// updateRegDefsUses - Replace all defs and uses of SrcReg to DstReg and + /// Replace all defs and uses of SrcReg to DstReg and /// update the subregister number if it is not zero. If DstReg is a /// physical register and the existing subregister number of the def / use /// being updated is not zero, make sure to set it to the correct physical /// subregister. void updateRegDefsUses(unsigned SrcReg, unsigned DstReg, unsigned SubIdx); - /// eliminateUndefCopy - Handle copies of undef values. + /// Handle copies of undef values. bool eliminateUndefCopy(MachineInstr *CopyMI, const CoalescerPair &CP); public: @@ -192,10 +192,10 @@ namespace { void releaseMemory() override; - /// runOnMachineFunction - pass entry point + /// This is the pass entry point. bool runOnMachineFunction(MachineFunction&) override; - /// print - Implement the dump method. + /// Implement the dump method. void print(raw_ostream &O, const Module* = nullptr) const override; }; } /// end anonymous namespace @@ -407,7 +407,7 @@ void RegisterCoalescer::LRE_WillEraseInstruction(MachineInstr *MI) { ErasedInstrs.insert(MI); } -/// adjustCopiesBackFrom - We found a non-trivially-coalescable copy with IntA +/// We found a non-trivially-coalescable copy with IntA /// being the source and IntB being the dest, thus this defines a value number /// in IntB. If the source value number (in IntA) is defined by a copy from B, /// see if we can merge these two pieces of B into a single value number, @@ -512,7 +512,7 @@ bool RegisterCoalescer::adjustCopiesBackFrom(const CoalescerPair &CP, return true; } -/// hasOtherReachingDefs - Return true if there are definitions of IntB +/// Return true if there are definitions of IntB /// other than BValNo val# that can reach uses of AValno val# of IntA. bool RegisterCoalescer::hasOtherReachingDefs(LiveInterval &IntA, LiveInterval &IntB, @@ -542,7 +542,7 @@ bool RegisterCoalescer::hasOtherReachingDefs(LiveInterval &IntA, return false; } -/// removeCopyByCommutingDef - We found a non-trivially-coalescable copy with +/// We found a non-trivially-coalescable copy with /// IntA being the source and IntB being the dest, thus this defines a value /// number in IntB. If the source value number (in IntA) is defined by a /// commutable instruction and its other operand is coalesced to the copy dest @@ -725,7 +725,7 @@ bool RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP, return true; } -/// reMaterializeTrivialDef - If the source of a copy is defined by a trivial +/// If the source of a copy is defined by a trivial /// computation, replace the copy by rematerialize the definition. bool RegisterCoalescer::reMaterializeTrivialDef(CoalescerPair &CP, MachineInstr *CopyMI, @@ -904,7 +904,7 @@ bool RegisterCoalescer::reMaterializeTrivialDef(CoalescerPair &CP, return true; } -/// eliminateUndefCopy - ProcessImpicitDefs may leave some copies of <undef> +/// ProcessImpicitDefs may leave some copies of <undef> /// values, it only removes local variables. When we have a copy like: /// /// %vreg1 = COPY %vreg2<undef> @@ -944,11 +944,10 @@ bool RegisterCoalescer::eliminateUndefCopy(MachineInstr *CopyMI, return true; } -/// updateRegDefsUses - Replace all defs and uses of SrcReg to DstReg and -/// update the subregister number if it is not zero. If DstReg is a -/// physical register and the existing subregister number of the def / use -/// being updated is not zero, make sure to set it to the correct physical -/// subregister. +/// Replace all defs and uses of SrcReg to DstReg and update the subregister +/// number if it is not zero. If DstReg is a physical register and the existing +/// subregister number of the def / use being updated is not zero, make sure to +/// set it to the correct physical subregister. void RegisterCoalescer::updateRegDefsUses(unsigned SrcReg, unsigned DstReg, unsigned SubIdx) { @@ -966,7 +965,7 @@ void RegisterCoalescer::updateRegDefsUses(unsigned SrcReg, // the UseMI operands removes them from the SrcReg use-def chain, but when // SrcReg is DstReg we could encounter UseMI twice if it has multiple // operands mentioning the virtual register. - if (SrcReg == DstReg && !Visited.insert(UseMI)) + if (SrcReg == DstReg && !Visited.insert(UseMI).second) continue; SmallVector<unsigned,8> Ops; @@ -1003,7 +1002,7 @@ void RegisterCoalescer::updateRegDefsUses(unsigned SrcReg, } } -/// canJoinPhys - Return true if a copy involving a physreg should be joined. +/// Return true if a copy involving a physreg should be joined. bool RegisterCoalescer::canJoinPhys(const CoalescerPair &CP) { /// Always join simple intervals that are defined by a single copy from a /// reserved register. This doesn't increase register pressure, so it is @@ -1021,7 +1020,7 @@ bool RegisterCoalescer::canJoinPhys(const CoalescerPair &CP) { return false; } -/// joinCopy - Attempt to join intervals corresponding to SrcReg/DstReg, +/// Attempt to join intervals corresponding to SrcReg/DstReg, /// which are the src/dst of the copy instruction CopyMI. This returns true /// if the copy was successfully coalesced away. If it is not currently /// possible to coalesce this interval, but it may be possible if other @@ -1037,6 +1036,22 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) { return false; } + if (CP.getNewRC()) { + auto SrcRC = MRI->getRegClass(CP.getSrcReg()); + auto DstRC = MRI->getRegClass(CP.getDstReg()); + unsigned SrcIdx = CP.getSrcIdx(); + unsigned DstIdx = CP.getDstIdx(); + if (CP.isFlipped()) { + std::swap(SrcIdx, DstIdx); + std::swap(SrcRC, DstRC); + } + if (!TRI->shouldCoalesce(CopyMI, SrcRC, SrcIdx, DstRC, DstIdx, + CP.getNewRC())) { + DEBUG(dbgs() << "\tSubtarget bailed on coalescing.\n"); + return false; + } + } + // Dead code elimination. This really should be handled by MachineDCE, but // sometimes dead copies slip through, and we can't generate invalid live // ranges. @@ -1090,9 +1105,14 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) { return false; } } else { + // When possible, let DstReg be the larger interval. + if (!CP.isPartial() && LIS->getInterval(CP.getSrcReg()).size() > + LIS->getInterval(CP.getDstReg()).size()) + CP.flip(); + DEBUG({ - dbgs() << "\tConsidering merging to " << CP.getNewRC()->getName() - << " with "; + dbgs() << "\tConsidering merging to " + << TRI->getRegClassName(CP.getNewRC()) << " with "; if (CP.getDstIdx() && CP.getSrcIdx()) dbgs() << PrintReg(CP.getDstReg()) << " in " << TRI->getSubRegIndexName(CP.getDstIdx()) << " and " @@ -1102,11 +1122,6 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) { dbgs() << PrintReg(CP.getSrcReg(), TRI) << " in " << PrintReg(CP.getDstReg(), TRI, CP.getSrcIdx()) << '\n'; }); - - // When possible, let DstReg be the larger interval. - if (!CP.isPartial() && LIS->getInterval(CP.getSrcReg()).size() > - LIS->getInterval(CP.getDstReg()).size()) - CP.flip(); } // Okay, attempt to join these two intervals. On failure, this returns false. @@ -1171,7 +1186,9 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) { TRI->UpdateRegAllocHint(CP.getSrcReg(), CP.getDstReg(), *MF); DEBUG({ - dbgs() << "\tJoined. Result = "; + dbgs() << "\tSuccess: " << PrintReg(CP.getSrcReg(), TRI, CP.getSrcIdx()) + << " -> " << PrintReg(CP.getDstReg(), TRI, CP.getDstIdx()) << '\n'; + dbgs() << "\tResult = "; if (CP.isPhys()) dbgs() << PrintReg(CP.getDstReg(), TRI); else @@ -1423,7 +1440,7 @@ public: /// Add erased instructions to ErasedInstrs. /// Add foreign virtual registers to ShrinkRegs if their live range ended at /// the erased instrs. - void eraseInstrs(SmallPtrSet<MachineInstr*, 8> &ErasedInstrs, + void eraseInstrs(SmallPtrSetImpl<MachineInstr*> &ErasedInstrs, SmallVectorImpl<unsigned> &ShrinkRegs); /// Get the value assignments suitable for passing to LiveInterval::join. @@ -1936,7 +1953,7 @@ void JoinVals::pruneValues(JoinVals &Other, } } -void JoinVals::eraseInstrs(SmallPtrSet<MachineInstr*, 8> &ErasedInstrs, +void JoinVals::eraseInstrs(SmallPtrSetImpl<MachineInstr*> &ErasedInstrs, SmallVectorImpl<unsigned> &ShrinkRegs) { for (unsigned i = 0, e = LI.getNumValNums(); i != e; ++i) { // Get the def location before markUnused() below invalidates it. @@ -2035,8 +2052,7 @@ bool RegisterCoalescer::joinVirtRegs(CoalescerPair &CP) { return true; } -/// joinIntervals - Attempt to join these two intervals. On failure, this -/// returns false. +/// Attempt to join these two intervals. On failure, this returns false. bool RegisterCoalescer::joinIntervals(CoalescerPair &CP) { return CP.isPhys() ? joinReservedPhysReg(CP) : joinVirtRegs(CP); } @@ -2208,8 +2224,8 @@ bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) { MF = &fn; MRI = &fn.getRegInfo(); TM = &fn.getTarget(); - TRI = TM->getRegisterInfo(); - TII = TM->getInstrInfo(); + TRI = TM->getSubtargetImpl()->getRegisterInfo(); + TII = TM->getSubtargetImpl()->getInstrInfo(); LIS = &getAnalysis<LiveIntervals>(); AA = &getAnalysis<AliasAnalysis>(); Loops = &getAnalysis<MachineLoopInfo>(); @@ -2250,7 +2266,7 @@ bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) { continue; if (MRI->recomputeRegClass(Reg, *TM)) { DEBUG(dbgs() << PrintReg(Reg) << " inflated to " - << MRI->getRegClass(Reg)->getName() << '\n'); + << TRI->getRegClassName(MRI->getRegClass(Reg)) << '\n'); ++NumInflated; } } @@ -2261,7 +2277,7 @@ bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) { return true; } -/// print - Implement the dump method. +/// Implement the dump method. void RegisterCoalescer::print(raw_ostream &O, const Module* m) const { LIS->print(O, m); } |