Refactoring and optimization on CPU translation (#661)
* Refactoring and optimization on CPU translation * Remove now unused property * Rename ilBlock -> block (local) * Change equality comparison on RegisterMask for consistency Co-Authored-By: gdkchan <gab.dark.100@gmail.com> * Add back the aggressive inlining attribute to the Synchronize method * Implement IEquatable on the Register struct * Fix identation
This commit is contained in:
parent
2b8eac1bce
commit
8a7d99cdea
48 changed files with 1257 additions and 1280 deletions
122
ChocolArm64/IntermediateRepresentation/BasicBlock.cs
Normal file
122
ChocolArm64/IntermediateRepresentation/BasicBlock.cs
Normal file
|
@ -0,0 +1,122 @@
|
|||
using ChocolArm64.State;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using static ChocolArm64.State.RegisterConsts;
|
||||
|
||||
namespace ChocolArm64.IntermediateRepresentation
|
||||
{
|
||||
class BasicBlock
|
||||
{
|
||||
public int Index { get; set; }
|
||||
|
||||
public RegisterMask RegInputs { get; private set; }
|
||||
public RegisterMask RegOutputs { get; private set; }
|
||||
|
||||
public bool HasStateLoad { get; private set; }
|
||||
|
||||
private List<Operation> _operations;
|
||||
|
||||
public int Count => _operations.Count;
|
||||
|
||||
private BasicBlock _next;
|
||||
private BasicBlock _branch;
|
||||
|
||||
public BasicBlock Next
|
||||
{
|
||||
get => _next;
|
||||
set => _next = AddSuccessor(_next, value);
|
||||
}
|
||||
|
||||
public BasicBlock Branch
|
||||
{
|
||||
get => _branch;
|
||||
set => _branch = AddSuccessor(_branch, value);
|
||||
}
|
||||
|
||||
public List<BasicBlock> Predecessors { get; }
|
||||
|
||||
public BasicBlock(int index = 0)
|
||||
{
|
||||
Index = index;
|
||||
|
||||
_operations = new List<Operation>();
|
||||
|
||||
Predecessors = new List<BasicBlock>();
|
||||
}
|
||||
|
||||
private BasicBlock AddSuccessor(BasicBlock oldBlock, BasicBlock newBlock)
|
||||
{
|
||||
oldBlock?.Predecessors.Remove(this);
|
||||
newBlock?.Predecessors.Add(this);
|
||||
|
||||
return newBlock;
|
||||
}
|
||||
|
||||
public void Add(Operation operation)
|
||||
{
|
||||
if (operation.Type == OperationType.LoadLocal ||
|
||||
operation.Type == OperationType.StoreLocal)
|
||||
{
|
||||
int index = operation.GetArg<int>(0);
|
||||
|
||||
if (IsRegIndex(index))
|
||||
{
|
||||
long intMask = 0;
|
||||
long vecMask = 0;
|
||||
|
||||
switch (operation.GetArg<RegisterType>(1))
|
||||
{
|
||||
case RegisterType.Flag: intMask = (1L << RegsCount) << index; break;
|
||||
case RegisterType.Int: intMask = 1L << index; break;
|
||||
case RegisterType.Vector: vecMask = 1L << index; break;
|
||||
}
|
||||
|
||||
RegisterMask mask = new RegisterMask(intMask, vecMask);
|
||||
|
||||
if (operation.Type == OperationType.LoadLocal)
|
||||
{
|
||||
RegInputs |= mask & ~RegOutputs;
|
||||
}
|
||||
else
|
||||
{
|
||||
RegOutputs |= mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (operation.Type == OperationType.LoadContext)
|
||||
{
|
||||
HasStateLoad = true;
|
||||
}
|
||||
|
||||
operation.Parent = this;
|
||||
|
||||
_operations.Add(operation);
|
||||
}
|
||||
|
||||
public static bool IsRegIndex(int index)
|
||||
{
|
||||
return (uint)index < RegsCount;
|
||||
}
|
||||
|
||||
public Operation GetOperation(int index)
|
||||
{
|
||||
if ((uint)index >= _operations.Count)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
}
|
||||
|
||||
return _operations[index];
|
||||
}
|
||||
|
||||
public Operation GetLastOp()
|
||||
{
|
||||
if (Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return _operations[Count - 1];
|
||||
}
|
||||
}
|
||||
}
|
4
ChocolArm64/IntermediateRepresentation/ILLabel.cs
Normal file
4
ChocolArm64/IntermediateRepresentation/ILLabel.cs
Normal file
|
@ -0,0 +1,4 @@
|
|||
namespace ChocolArm64.IntermediateRepresentation
|
||||
{
|
||||
class ILLabel { }
|
||||
}
|
112
ChocolArm64/IntermediateRepresentation/Operation.cs
Normal file
112
ChocolArm64/IntermediateRepresentation/Operation.cs
Normal file
|
@ -0,0 +1,112 @@
|
|||
using ChocolArm64.State;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
|
||||
namespace ChocolArm64.IntermediateRepresentation
|
||||
{
|
||||
class Operation
|
||||
{
|
||||
public BasicBlock Parent { get; set; }
|
||||
|
||||
public OperationType Type { get; }
|
||||
|
||||
private object[] _arguments { get; }
|
||||
|
||||
private Operation(OperationType type, params object[] arguments)
|
||||
{
|
||||
Type = type;
|
||||
_arguments = arguments;
|
||||
}
|
||||
|
||||
public T GetArg<T>(int index)
|
||||
{
|
||||
return (T)GetArg(index);
|
||||
}
|
||||
|
||||
public object GetArg(int index)
|
||||
{
|
||||
if ((uint)index >= _arguments.Length)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
}
|
||||
|
||||
return _arguments[index];
|
||||
}
|
||||
|
||||
public static Operation Call(MethodInfo info)
|
||||
{
|
||||
return new Operation(OperationType.Call, info);
|
||||
}
|
||||
|
||||
public static Operation CallVirtual(MethodInfo info)
|
||||
{
|
||||
return new Operation(OperationType.CallVirtual, info);
|
||||
}
|
||||
|
||||
public static Operation IL(OpCode ilOp)
|
||||
{
|
||||
return new Operation(OperationType.IL, ilOp);
|
||||
}
|
||||
|
||||
public static Operation ILBranch(OpCode ilOp, ILLabel target)
|
||||
{
|
||||
return new Operation(OperationType.ILBranch, ilOp, target);
|
||||
}
|
||||
|
||||
public static Operation LoadArgument(int index)
|
||||
{
|
||||
return new Operation(OperationType.LoadArgument, index);
|
||||
}
|
||||
|
||||
public static Operation LoadConstant(int value)
|
||||
{
|
||||
return new Operation(OperationType.LoadConstant, value);
|
||||
}
|
||||
|
||||
public static Operation LoadConstant(long value)
|
||||
{
|
||||
return new Operation(OperationType.LoadConstant, value);
|
||||
}
|
||||
|
||||
public static Operation LoadConstant(float value)
|
||||
{
|
||||
return new Operation(OperationType.LoadConstant, value);
|
||||
}
|
||||
|
||||
public static Operation LoadConstant(double value)
|
||||
{
|
||||
return new Operation(OperationType.LoadConstant, value);
|
||||
}
|
||||
|
||||
public static Operation LoadContext()
|
||||
{
|
||||
return new Operation(OperationType.LoadContext);
|
||||
}
|
||||
|
||||
public static Operation LoadField(FieldInfo info)
|
||||
{
|
||||
return new Operation(OperationType.LoadField, info);
|
||||
}
|
||||
|
||||
public static Operation LoadLocal(int index, RegisterType type, RegisterSize size)
|
||||
{
|
||||
return new Operation(OperationType.LoadLocal, index, type, size);
|
||||
}
|
||||
|
||||
public static Operation MarkLabel(ILLabel label)
|
||||
{
|
||||
return new Operation(OperationType.MarkLabel, label);
|
||||
}
|
||||
|
||||
public static Operation StoreContext()
|
||||
{
|
||||
return new Operation(OperationType.StoreContext);
|
||||
}
|
||||
|
||||
public static Operation StoreLocal(int index, RegisterType type, RegisterSize size)
|
||||
{
|
||||
return new Operation(OperationType.StoreLocal, index, type, size);
|
||||
}
|
||||
}
|
||||
}
|
18
ChocolArm64/IntermediateRepresentation/OperationType.cs
Normal file
18
ChocolArm64/IntermediateRepresentation/OperationType.cs
Normal file
|
@ -0,0 +1,18 @@
|
|||
namespace ChocolArm64.IntermediateRepresentation
|
||||
{
|
||||
enum OperationType
|
||||
{
|
||||
Call,
|
||||
CallVirtual,
|
||||
IL,
|
||||
ILBranch,
|
||||
LoadArgument,
|
||||
LoadConstant,
|
||||
LoadContext,
|
||||
LoadField,
|
||||
LoadLocal,
|
||||
MarkLabel,
|
||||
StoreContext,
|
||||
StoreLocal
|
||||
}
|
||||
}
|
56
ChocolArm64/IntermediateRepresentation/RegisterMask.cs
Normal file
56
ChocolArm64/IntermediateRepresentation/RegisterMask.cs
Normal file
|
@ -0,0 +1,56 @@
|
|||
using System;
|
||||
|
||||
namespace ChocolArm64.IntermediateRepresentation
|
||||
{
|
||||
struct RegisterMask : IEquatable<RegisterMask>
|
||||
{
|
||||
public long IntMask { get; set; }
|
||||
public long VecMask { get; set; }
|
||||
|
||||
public RegisterMask(long intMask, long vecMask)
|
||||
{
|
||||
IntMask = intMask;
|
||||
VecMask = vecMask;
|
||||
}
|
||||
|
||||
public static RegisterMask operator &(RegisterMask x, RegisterMask y)
|
||||
{
|
||||
return new RegisterMask(x.IntMask & y.IntMask, x.VecMask & y.VecMask);
|
||||
}
|
||||
|
||||
public static RegisterMask operator |(RegisterMask x, RegisterMask y)
|
||||
{
|
||||
return new RegisterMask(x.IntMask | y.IntMask, x.VecMask | y.VecMask);
|
||||
}
|
||||
|
||||
public static RegisterMask operator ~(RegisterMask x)
|
||||
{
|
||||
return new RegisterMask(~x.IntMask, ~x.VecMask);
|
||||
}
|
||||
|
||||
public static bool operator ==(RegisterMask x, RegisterMask y)
|
||||
{
|
||||
return x.Equals(y);
|
||||
}
|
||||
|
||||
public static bool operator !=(RegisterMask x, RegisterMask y)
|
||||
{
|
||||
return !x.Equals(y);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is RegisterMask regMask && Equals(regMask);
|
||||
}
|
||||
|
||||
public bool Equals(RegisterMask other)
|
||||
{
|
||||
return IntMask == other.IntMask && VecMask == other.VecMask;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(IntMask, VecMask);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue