mirror of
				https://github.com/Ryujinx/Ryujinx.git
				synced 2025-10-31 18:03:11 +00:00 
			
		
		
		
	JIT: Coalesce copies on LSRA with simple register preferencing (#6950)
* JIT: Coalesce copies on LSRA with simple register preferencing * PPTC version bump
This commit is contained in:
		
							parent
							
								
									d25a084858
								
							
						
					
					
						commit
						0afa8f2c14
					
				| @ -251,7 +251,20 @@ namespace ARMeilleure.CodeGen.RegisterAllocators | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             int selectedReg = GetHighestValueIndex(freePositions); | ||||
|             // If this is a copy destination variable, we prefer the register used for the copy source. | ||||
|             // If the register is available, then the copy can be eliminated later as both source | ||||
|             // and destination will use the same register. | ||||
|             int selectedReg; | ||||
| 
 | ||||
|             if (current.TryGetCopySourceRegister(out int preferredReg) && freePositions[preferredReg] >= current.GetEnd()) | ||||
|             { | ||||
|                 selectedReg = preferredReg; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 selectedReg = GetHighestValueIndex(freePositions); | ||||
|             } | ||||
| 
 | ||||
|             int selectedNextUse = freePositions[selectedReg]; | ||||
| 
 | ||||
|             // Intervals starts and ends at odd positions, unless they span an entire | ||||
| @ -431,7 +444,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         private static int GetHighestValueIndex(Span<int> span) | ||||
|         private static int GetHighestValueIndex(ReadOnlySpan<int> span) | ||||
|         { | ||||
|             int highest = int.MinValue; | ||||
| 
 | ||||
| @ -798,12 +811,12 @@ namespace ARMeilleure.CodeGen.RegisterAllocators | ||||
|             // The "visited" state is stored in the MSB of the local's value. | ||||
|             const ulong VisitedMask = 1ul << 63; | ||||
| 
 | ||||
|             bool IsVisited(Operand local) | ||||
|             static bool IsVisited(Operand local) | ||||
|             { | ||||
|                 return (local.GetValueUnsafe() & VisitedMask) != 0; | ||||
|             } | ||||
| 
 | ||||
|             void SetVisited(Operand local) | ||||
|             static void SetVisited(Operand local) | ||||
|             { | ||||
|                 local.GetValueUnsafe() |= VisitedMask; | ||||
|             } | ||||
| @ -826,9 +839,25 @@ namespace ARMeilleure.CodeGen.RegisterAllocators | ||||
|                         { | ||||
|                             dest.NumberLocal(_intervals.Count); | ||||
| 
 | ||||
|                             _intervals.Add(new LiveInterval(dest)); | ||||
|                             LiveInterval interval = new LiveInterval(dest); | ||||
|                             _intervals.Add(interval); | ||||
| 
 | ||||
|                             SetVisited(dest); | ||||
| 
 | ||||
|                             // If this is a copy (or copy-like operation), set the copy source interval as well. | ||||
|                             // This is used for register preferencing later on, which allows the copy to be eliminated | ||||
|                             // in some cases. | ||||
|                             if (node.Instruction == Instruction.Copy || node.Instruction == Instruction.ZeroExtend32) | ||||
|                             { | ||||
|                                 Operand source = node.GetSource(0); | ||||
| 
 | ||||
|                                 if (source.Kind == OperandKind.LocalVariable && | ||||
|                                     source.GetLocalNumber() > 0 && | ||||
|                                     (node.Instruction == Instruction.Copy || source.Type == OperandType.I32)) | ||||
|                                 { | ||||
|                                     interval.SetCopySource(_intervals[source.GetLocalNumber()]); | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
| @ -19,6 +19,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators | ||||
|             public LiveRange CurrRange; | ||||
| 
 | ||||
|             public LiveInterval Parent; | ||||
|             public LiveInterval CopySource; | ||||
| 
 | ||||
|             public UseList Uses; | ||||
|             public LiveIntervalList Children; | ||||
| @ -37,6 +38,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators | ||||
|         private ref LiveRange CurrRange => ref _data->CurrRange; | ||||
|         private ref LiveRange PrevRange => ref _data->PrevRange; | ||||
|         private ref LiveInterval Parent => ref _data->Parent; | ||||
|         private ref LiveInterval CopySource => ref _data->CopySource; | ||||
|         private ref UseList Uses => ref _data->Uses; | ||||
|         private ref LiveIntervalList Children => ref _data->Children; | ||||
| 
 | ||||
| @ -78,6 +80,25 @@ namespace ARMeilleure.CodeGen.RegisterAllocators | ||||
|             Register = register; | ||||
|         } | ||||
| 
 | ||||
|         public void SetCopySource(LiveInterval copySource) | ||||
|         { | ||||
|             CopySource = copySource; | ||||
|         } | ||||
| 
 | ||||
|         public bool TryGetCopySourceRegister(out int copySourceRegIndex) | ||||
|         { | ||||
|             if (CopySource._data != null) | ||||
|             { | ||||
|                 copySourceRegIndex = CopySource.Register.Index; | ||||
| 
 | ||||
|                 return true; | ||||
|             } | ||||
| 
 | ||||
|             copySourceRegIndex = 0; | ||||
| 
 | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         public void Reset() | ||||
|         { | ||||
|             PrevRange = default; | ||||
|  | ||||
| @ -29,7 +29,7 @@ namespace ARMeilleure.Translation.PTC | ||||
|         private const string OuterHeaderMagicString = "PTCohd\0\0"; | ||||
|         private const string InnerHeaderMagicString = "PTCihd\0\0"; | ||||
| 
 | ||||
|         private const uint InternalVersion = 6634; //! To be incremented manually for each change to the ARMeilleure project. | ||||
|         private const uint InternalVersion = 6950; //! To be incremented manually for each change to the ARMeilleure project. | ||||
| 
 | ||||
|         private const string ActualDir = "0"; | ||||
|         private const string BackupDir = "1"; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 gdkchan
						gdkchan