mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +00:00 
			
		
		
		
	PR 770 - permit coallescing of registers in subset register classes.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28197 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
		| @@ -167,9 +167,11 @@ namespace llvm { | |||||||
|                                    unsigned SrcReg, unsigned DestReg, |                                    unsigned SrcReg, unsigned DestReg, | ||||||
|                                    bool isLiveIn = false); |                                    bool isLiveIn = false); | ||||||
|  |  | ||||||
|     /// Return true if the two specified registers belong to different |     /// Return true if the two specified registers belong to the same or | ||||||
|     /// register classes.  The registers may be either phys or virt regs. |     /// compatible register classes.  The registers may be either phys or | ||||||
|     bool differingRegisterClasses(unsigned RegA, unsigned RegB) const; |     /// virt regs. | ||||||
|  |     bool compatibleRegisterClasses(unsigned RegA, unsigned RegB, | ||||||
|  |                                    bool &Swap) const; | ||||||
|  |  | ||||||
|     bool AdjustIfAllOverlappingRangesAreCopiesFrom(LiveInterval &IntA, |     bool AdjustIfAllOverlappingRangesAreCopiesFrom(LiveInterval &IntA, | ||||||
|                                                    LiveInterval &IntB, |                                                    LiveInterval &IntB, | ||||||
|   | |||||||
| @@ -705,9 +705,12 @@ void LiveIntervals::joinIntervalsInMachineBB(MachineBasicBlock *MBB) { | |||||||
|           MRegisterInfo::isPhysicalRegister(DestReg)) |           MRegisterInfo::isPhysicalRegister(DestReg)) | ||||||
|         continue; |         continue; | ||||||
|  |  | ||||||
|       // If they are not of the same register class, we cannot join them. |       // If they are not of compatible register classes, we cannot join them. | ||||||
|       if (differingRegisterClasses(SrcReg, DestReg)) |       bool Swap = false; | ||||||
|  |       if (!compatibleRegisterClasses(SrcReg, DestReg, Swap)) { | ||||||
|  |         DEBUG(std::cerr << "Register classes aren't compatible!\n"); | ||||||
|         continue; |         continue; | ||||||
|  |       } | ||||||
|  |  | ||||||
|       LiveInterval &SrcInt = getInterval(SrcReg); |       LiveInterval &SrcInt = getInterval(SrcReg); | ||||||
|       LiveInterval &DestInt = getInterval(DestReg); |       LiveInterval &DestInt = getInterval(DestReg); | ||||||
| @@ -741,7 +744,7 @@ void LiveIntervals::joinIntervalsInMachineBB(MachineBasicBlock *MBB) { | |||||||
|         DestInt.join(SrcInt, MIDefIdx); |         DestInt.join(SrcInt, MIDefIdx); | ||||||
|         DEBUG(std::cerr << "Joined.  Result = " << DestInt << "\n"); |         DEBUG(std::cerr << "Joined.  Result = " << DestInt << "\n"); | ||||||
|  |  | ||||||
|         if (!MRegisterInfo::isPhysicalRegister(SrcReg)) { |         if (!Swap && !MRegisterInfo::isPhysicalRegister(SrcReg)) { | ||||||
|           r2iMap_.erase(SrcReg); |           r2iMap_.erase(SrcReg); | ||||||
|           r2rMap_[SrcReg] = DestReg; |           r2rMap_[SrcReg] = DestReg; | ||||||
|         } else { |         } else { | ||||||
| @@ -803,24 +806,33 @@ void LiveIntervals::joinIntervals() { | |||||||
|              std::cerr << "  reg " << i << " -> reg " << r2rMap_[i] << "\n"); |              std::cerr << "  reg " << i << " -> reg " << r2rMap_[i] << "\n"); | ||||||
| } | } | ||||||
|  |  | ||||||
| /// Return true if the two specified registers belong to different register | /// Return true if the two specified registers belong to same or compatible | ||||||
| /// classes.  The registers may be either phys or virt regs. | /// register classes. The registers may be either phys or virt regs. | ||||||
| bool LiveIntervals::differingRegisterClasses(unsigned RegA, | bool LiveIntervals::compatibleRegisterClasses(unsigned RegA, unsigned RegB, | ||||||
|                                              unsigned RegB) const { |                                                  bool &Swap) const { | ||||||
|  |  | ||||||
|   // Get the register classes for the first reg. |   // Get the register classes for the first reg. | ||||||
|   if (MRegisterInfo::isPhysicalRegister(RegA)) { |   if (MRegisterInfo::isPhysicalRegister(RegA)) { | ||||||
|     assert(MRegisterInfo::isVirtualRegister(RegB) && |     assert(MRegisterInfo::isVirtualRegister(RegB) && | ||||||
|            "Shouldn't consider two physregs!"); |            "Shouldn't consider two physregs!"); | ||||||
|     return !mf_->getSSARegMap()->getRegClass(RegB)->contains(RegA); |     return mf_->getSSARegMap()->getRegClass(RegB)->contains(RegA); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // Compare against the regclass for the second reg. |   // Compare against the regclass for the second reg. | ||||||
|   const TargetRegisterClass *RegClass = mf_->getSSARegMap()->getRegClass(RegA); |   const TargetRegisterClass *RegClassA = mf_->getSSARegMap()->getRegClass(RegA); | ||||||
|   if (MRegisterInfo::isVirtualRegister(RegB)) |   if (MRegisterInfo::isVirtualRegister(RegB)) { | ||||||
|     return RegClass != mf_->getSSARegMap()->getRegClass(RegB); |     const TargetRegisterClass *RegClassB=mf_->getSSARegMap()->getRegClass(RegB); | ||||||
|   else |     if (RegClassA == RegClassB) | ||||||
|     return !RegClass->contains(RegB); |       return true; | ||||||
|  |     else { | ||||||
|  |       if (RegClassB->hasSubRegClass(RegClassA)) { | ||||||
|  |         Swap = true; | ||||||
|  |         return true; | ||||||
|  |       } | ||||||
|  |       return RegClassA->hasSubRegClass(RegClassB); | ||||||
|  |     } | ||||||
|  |   } else | ||||||
|  |     return RegClassA->contains(RegB); | ||||||
| } | } | ||||||
|  |  | ||||||
| bool LiveIntervals::overlapsAliases(const LiveInterval *LHS, | bool LiveIntervals::overlapsAliases(const LiveInterval *LHS, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user