mirror of
https://github.com/Ryujinx/Ryujinx.git
synced 2024-08-18 22:58:43 +02:00
* Add an early `TailMerge` pass Some translations can have a lot of guest calls and since for each guest call there is a call guard which may return. This can produce a lot of epilogue code for returns. This pass merges the epilogue into a single block. ``` Using filter 'hcq'. Using metric 'code size'. Total diff: -1648111 (-7.19 %) (bytes): Base: 22913847 Diff: 21265736 Improved: 4567, regressed: 14, unchanged: 144 ``` * Set PTC version * Address feedback * Handle `void` returning functions * Actually handle `void` returning functions * Fix `RegisterToLocal` logging
73 lines
2.3 KiB
C#
73 lines
2.3 KiB
C#
using ARMeilleure.IntermediateRepresentation;
|
|
using ARMeilleure.Translation;
|
|
using System.Diagnostics;
|
|
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
|
|
|
namespace ARMeilleure.CodeGen.Optimizations
|
|
{
|
|
static class BlockPlacement
|
|
{
|
|
public static void RunPass(ControlFlowGraph cfg)
|
|
{
|
|
bool update = false;
|
|
|
|
BasicBlock block;
|
|
BasicBlock nextBlock;
|
|
|
|
BasicBlock lastBlock = cfg.Blocks.Last;
|
|
|
|
// Move cold blocks at the end of the list, so that they are emitted away from hot code.
|
|
for (block = cfg.Blocks.First; block != null; block = nextBlock)
|
|
{
|
|
nextBlock = block.ListNext;
|
|
|
|
if (block.Frequency == BasicBlockFrequency.Cold)
|
|
{
|
|
cfg.Blocks.Remove(block);
|
|
cfg.Blocks.AddLast(block);
|
|
}
|
|
|
|
if (block == lastBlock)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (block = cfg.Blocks.First; block != null; block = nextBlock)
|
|
{
|
|
nextBlock = block.ListNext;
|
|
|
|
if (block.SuccessorsCount == 2)
|
|
{
|
|
Operation branchOp = block.Operations.Last;
|
|
|
|
Debug.Assert(branchOp.Instruction == Instruction.BranchIf);
|
|
|
|
BasicBlock falseSucc = block.GetSuccessor(0);
|
|
BasicBlock trueSucc = block.GetSuccessor(1);
|
|
|
|
// If true successor is next block in list, invert the condition. We avoid extra branching by
|
|
// making the true side the fallthrough (i.e, convert it to the false side).
|
|
if (trueSucc == block.ListNext)
|
|
{
|
|
Comparison comp = (Comparison)branchOp.GetSource(2).AsInt32();
|
|
Comparison compInv = comp.Invert();
|
|
|
|
branchOp.SetSource(2, Const((int)compInv));
|
|
|
|
block.SetSuccessor(0, trueSucc);
|
|
block.SetSuccessor(1, falseSucc);
|
|
|
|
update = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (update)
|
|
{
|
|
cfg.Update();
|
|
}
|
|
}
|
|
}
|
|
}
|