Improve StoreToContext emission (#2155)

* Improve StoreToContext emission

Hoist StoreToContext in dynamic branch fast & slow paths out into
their predecessor.

Reduces register pressure, code size and compile time because we're
throwing less stuff down the pipeline.

* Set PTC internal version

* Turn EmitDynamicTableCall private

* Re-trigger CI
This commit is contained in:
FICTURE7 2021-04-02 21:54:23 +04:00 committed by GitHub
parent d394c7ee98
commit 98ed81e4cd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 13 additions and 16 deletions

View file

@ -147,10 +147,8 @@ namespace ARMeilleure.Instructions
EmitJumpTableBranch(context, Const(immediate), isRecursive); EmitJumpTableBranch(context, Const(immediate), isRecursive);
} }
private static void EmitNativeCall(ArmEmitterContext context, Operand nativeContextPtr, Operand funcAddr, bool isJump = false) private static void EmitNativeCall(ArmEmitterContext context, Operand nativeContextPtr, Operand funcAddr, bool isJump)
{ {
context.StoreToContext();
if (isJump) if (isJump)
{ {
context.Tailcall(funcAddr, nativeContextPtr); context.Tailcall(funcAddr, nativeContextPtr);
@ -180,22 +178,17 @@ namespace ARMeilleure.Instructions
} }
} }
private static void EmitNativeCall(ArmEmitterContext context, Operand funcAddr, bool isJump = false) private static void EmitNativeCall(ArmEmitterContext context, Operand funcAddr, bool isJump)
{ {
EmitNativeCall(context, context.LoadArgument(OperandType.I64, 0), funcAddr, isJump); EmitNativeCall(context, context.LoadArgument(OperandType.I64, 0), funcAddr, isJump);
} }
public static void EmitVirtualCall(ArmEmitterContext context, Operand target) public static void EmitVirtualCall(ArmEmitterContext context, Operand target)
{ {
EmitVirtualCallOrJump(context, target, isJump: false); EmitJumpTableBranch(context, target, isJump: false);
} }
public static void EmitVirtualJump(ArmEmitterContext context, Operand target, bool isReturn) public static void EmitVirtualJump(ArmEmitterContext context, Operand target, bool isReturn)
{
EmitVirtualCallOrJump(context, target, isJump: true, isReturn: isReturn);
}
private static void EmitVirtualCallOrJump(ArmEmitterContext context, Operand target, bool isJump, bool isReturn = false)
{ {
if (isReturn) if (isReturn)
{ {
@ -203,7 +196,7 @@ namespace ARMeilleure.Instructions
} }
else else
{ {
EmitJumpTableBranch(context, target, isJump); EmitJumpTableBranch(context, target, isJump: true);
} }
} }
@ -219,15 +212,17 @@ namespace ARMeilleure.Instructions
{ {
// If we're doing a tail continue in HighCq, reserve a space in the jump table to avoid calling back // If we're doing a tail continue in HighCq, reserve a space in the jump table to avoid calling back
// to the translator. This will always try to get a HighCq version of our continue target as well. // to the translator. This will always try to get a HighCq version of our continue target as well.
EmitJumpTableBranch(context, address, true); EmitJumpTableBranch(context, address, isJump: true);
} }
else else
{ {
context.StoreToContext();
Operand fallbackAddr = context.Call(typeof(NativeInterface).GetMethod(allowRejit Operand fallbackAddr = context.Call(typeof(NativeInterface).GetMethod(allowRejit
? nameof(NativeInterface.GetFunctionAddress) ? nameof(NativeInterface.GetFunctionAddress)
: nameof(NativeInterface.GetFunctionAddressWithoutRejit)), address); : nameof(NativeInterface.GetFunctionAddressWithoutRejit)), address);
EmitNativeCall(context, fallbackAddr, true); EmitNativeCall(context, fallbackAddr, isJump: true);
} }
} }
else else
@ -251,7 +246,7 @@ namespace ARMeilleure.Instructions
EmitNativeCall(context, fallbackAddr, isJump); EmitNativeCall(context, fallbackAddr, isJump);
} }
public static void EmitDynamicTableCall(ArmEmitterContext context, Operand tableAddress, Operand address, bool isJump) private static void EmitDynamicTableCall(ArmEmitterContext context, Operand tableAddress, Operand address, bool isJump)
{ {
// Loop over elements of the dynamic table. Unrolled loop. // Loop over elements of the dynamic table. Unrolled loop.
@ -310,13 +305,15 @@ namespace ARMeilleure.Instructions
context.MarkLabel(endLabel); context.MarkLabel(endLabel);
} }
public static void EmitJumpTableBranch(ArmEmitterContext context, Operand address, bool isJump = false) private static void EmitJumpTableBranch(ArmEmitterContext context, Operand address, bool isJump)
{ {
if (address.Type == OperandType.I32) if (address.Type == OperandType.I32)
{ {
address = context.ZeroExtend32(OperandType.I64, address); address = context.ZeroExtend32(OperandType.I64, address);
} }
context.StoreToContext();
// TODO: Constant folding. Indirect calls are slower in the best case and emit more code so we want to // TODO: Constant folding. Indirect calls are slower in the best case and emit more code so we want to
// avoid them when possible. // avoid them when possible.
bool isConst = address.Kind == OperandKind.Constant; bool isConst = address.Kind == OperandKind.Constant;

View file

@ -26,7 +26,7 @@ namespace ARMeilleure.Translation.PTC
{ {
private const string HeaderMagicString = "PTChd\0\0\0"; private const string HeaderMagicString = "PTChd\0\0\0";
private const uint InternalVersion = 1990; //! To be incremented manually for each change to the ARMeilleure project. private const uint InternalVersion = 2155; //! To be incremented manually for each change to the ARMeilleure project.
private const string ActualDir = "0"; private const string ActualDir = "0";
private const string BackupDir = "1"; private const string BackupDir = "1";