Use branch instead of tailcall for recursive calls (#2282)

* Use branch instead of tailcall for recursive calls

Use a branch instead of doing a tailcall for recursive calls. This
avoids having to store the dispatch address, setting up the epilogue and
keeps guest registers in host registers for longer.

The rejit check is moved down into the entry block so that the rejit
behaviour remains the same as before.

* Set PTC version

Co-authored-by: gdkchan <gab.dark.100@gmail.com>
This commit is contained in:
FICTURE7 2021-05-20 16:31:45 +04:00 committed by GitHub
parent 0181068016
commit 65ac00833a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 22 additions and 11 deletions

View file

@ -144,7 +144,14 @@ namespace ARMeilleure.Instructions
{
bool isRecursive = immediate == context.EntryAddress;
EmitJumpTableBranch(context, Const(immediate), isRecursive);
if (isRecursive)
{
context.Branch(context.GetLabel(immediate));
}
else
{
EmitJumpTableBranch(context, Const(immediate), isJump: false);
}
}
private static void EmitNativeCall(ArmEmitterContext context, Operand nativeContextPtr, Operand funcAddr, bool isJump)

View file

@ -28,7 +28,7 @@ namespace ARMeilleure.Translation.PTC
private const string OuterHeaderMagicString = "PTCohd\0\0";
private const string InnerHeaderMagicString = "PTCihd\0\0";
private const uint InternalVersion = 2279; //! To be incremented manually for each change to the ARMeilleure project.
private const uint InternalVersion = 2282; //! To be incremented manually for each change to the ARMeilleure project.
private const string ActualDir = "0";
private const string BackupDir = "1";

View file

@ -237,13 +237,6 @@ namespace ARMeilleure.Translation
Logger.StartPass(PassName.Translation);
Counter<uint> counter = null;
if (!context.HighCq)
{
EmitRejitCheck(context, out counter);
}
EmitSynchronization(context);
if (blocks[0].Address != address)
@ -251,7 +244,7 @@ namespace ARMeilleure.Translation
context.Branch(context.GetLabel(address));
}
ControlFlowGraph cfg = EmitAndGetCFG(context, blocks, out Range funcRange);
ControlFlowGraph cfg = EmitAndGetCFG(context, blocks, out Range funcRange, out Counter<uint> counter);
ulong funcSize = funcRange.End - funcRange.Start;
@ -322,8 +315,14 @@ namespace ARMeilleure.Translation
}
}
private static ControlFlowGraph EmitAndGetCFG(ArmEmitterContext context, Block[] blocks, out Range range)
private static ControlFlowGraph EmitAndGetCFG(
ArmEmitterContext context,
Block[] blocks,
out Range range,
out Counter<uint> counter)
{
counter = null;
ulong rangeStart = ulong.MaxValue;
ulong rangeEnd = 0;
@ -344,6 +343,11 @@ namespace ARMeilleure.Translation
}
}
if (block.Address == context.EntryAddress && !context.HighCq)
{
EmitRejitCheck(context, out counter);
}
context.CurrBlock = block;
context.MarkLabel(context.GetLabel(block.Address));