* dotnet format style --severity info Some changes were manually reverted. * dotnet format analyzers --serverity info Some changes have been minimally adapted. * Restore a few unused methods and variables * Silence dotnet format IDE0060 warnings * Silence dotnet format IDE0052 warnings * Address or silence dotnet format IDE1006 warnings * Address or silence dotnet format CA2208 warnings * Address dotnet format CA1822 warnings * Address or silence dotnet format CA1069 warnings * Silence CA1806 and CA1834 issues * Address dotnet format CA1401 warnings * Fix new dotnet-format issues after rebase * Address review comments * Address dotnet format CA2208 warnings properly * Fix formatting for switch expressions * Address most dotnet format whitespace warnings * Apply dotnet format whitespace formatting A few of them have been manually reverted and the corresponding warning was silenced * Add previously silenced warnings back I have no clue how these disappeared * Revert formatting changes for OpCodeTable.cs * Enable formatting for a few cases again * Format if-blocks correctly * Enable formatting for a few more cases again * Fix inline comment alignment * Run dotnet format after rebase and remove unused usings - analyzers - style - whitespace * Disable 'prefer switch expression' rule * Add comments to disabled warnings * Remove a few unused parameters * Adjust namespaces * Simplify properties and array initialization, Use const when possible, Remove trailing commas * Start working on disabled warnings * Fix and silence a few dotnet-format warnings again * Address IDE0251 warnings * Address a few disabled IDE0060 warnings * Silence IDE0060 in .editorconfig * Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas" This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e. * dotnet format whitespace after rebase * First dotnet format pass * Remove unnecessary formatting exclusion * Add unsafe dotnet format changes * Change visibility of JitSupportDarwin to internal
183 lines
5.8 KiB
C#
183 lines
5.8 KiB
C#
using ARMeilleure.IntermediateRepresentation;
|
|
using System;
|
|
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
|
|
|
namespace ARMeilleure.CodeGen.Optimizations
|
|
{
|
|
static class Simplification
|
|
{
|
|
public static void RunPass(Operation operation)
|
|
{
|
|
switch (operation.Instruction)
|
|
{
|
|
case Instruction.Add:
|
|
if (operation.GetSource(0).Relocatable ||
|
|
operation.GetSource(1).Relocatable)
|
|
{
|
|
break;
|
|
}
|
|
|
|
TryEliminateBinaryOpComutative(operation, 0);
|
|
break;
|
|
|
|
case Instruction.BitwiseAnd:
|
|
TryEliminateBitwiseAnd(operation);
|
|
break;
|
|
|
|
case Instruction.BitwiseOr:
|
|
TryEliminateBitwiseOr(operation);
|
|
break;
|
|
|
|
case Instruction.BitwiseExclusiveOr:
|
|
TryEliminateBitwiseExclusiveOr(operation);
|
|
break;
|
|
|
|
case Instruction.ConditionalSelect:
|
|
TryEliminateConditionalSelect(operation);
|
|
break;
|
|
|
|
case Instruction.Divide:
|
|
TryEliminateBinaryOpY(operation, 1);
|
|
break;
|
|
|
|
case Instruction.Multiply:
|
|
TryEliminateBinaryOpComutative(operation, 1);
|
|
break;
|
|
|
|
case Instruction.ShiftLeft:
|
|
case Instruction.ShiftRightSI:
|
|
case Instruction.ShiftRightUI:
|
|
case Instruction.Subtract:
|
|
TryEliminateBinaryOpY(operation, 0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
private static void TryEliminateBitwiseAnd(Operation operation)
|
|
{
|
|
// Try to recognize and optimize those 3 patterns (in order):
|
|
// x & 0xFFFFFFFF == x, 0xFFFFFFFF & y == y,
|
|
// x & 0x00000000 == 0x00000000, 0x00000000 & y == 0x00000000
|
|
Operand x = operation.GetSource(0);
|
|
Operand y = operation.GetSource(1);
|
|
|
|
if (IsConstEqual(x, AllOnes(x.Type)))
|
|
{
|
|
operation.TurnIntoCopy(y);
|
|
}
|
|
else if (IsConstEqual(y, AllOnes(y.Type)))
|
|
{
|
|
operation.TurnIntoCopy(x);
|
|
}
|
|
else if (IsConstEqual(x, 0) || IsConstEqual(y, 0))
|
|
{
|
|
operation.TurnIntoCopy(Const(x.Type, 0));
|
|
}
|
|
}
|
|
|
|
private static void TryEliminateBitwiseOr(Operation operation)
|
|
{
|
|
// Try to recognize and optimize those 3 patterns (in order):
|
|
// x | 0x00000000 == x, 0x00000000 | y == y,
|
|
// x | 0xFFFFFFFF == 0xFFFFFFFF, 0xFFFFFFFF | y == 0xFFFFFFFF
|
|
Operand x = operation.GetSource(0);
|
|
Operand y = operation.GetSource(1);
|
|
|
|
if (IsConstEqual(x, 0))
|
|
{
|
|
operation.TurnIntoCopy(y);
|
|
}
|
|
else if (IsConstEqual(y, 0))
|
|
{
|
|
operation.TurnIntoCopy(x);
|
|
}
|
|
else if (IsConstEqual(x, AllOnes(x.Type)) || IsConstEqual(y, AllOnes(y.Type)))
|
|
{
|
|
operation.TurnIntoCopy(Const(AllOnes(x.Type)));
|
|
}
|
|
}
|
|
|
|
private static void TryEliminateBitwiseExclusiveOr(Operation operation)
|
|
{
|
|
// Try to recognize and optimize those 2 patterns (in order):
|
|
// x ^ y == 0x00000000 when x == y
|
|
// 0x00000000 ^ y == y, x ^ 0x00000000 == x
|
|
Operand x = operation.GetSource(0);
|
|
Operand y = operation.GetSource(1);
|
|
|
|
if (x == y && x.Type.IsInteger())
|
|
{
|
|
operation.TurnIntoCopy(Const(x.Type, 0));
|
|
}
|
|
else
|
|
{
|
|
TryEliminateBinaryOpComutative(operation, 0);
|
|
}
|
|
}
|
|
|
|
private static void TryEliminateBinaryOpY(Operation operation, ulong comparand)
|
|
{
|
|
Operand x = operation.GetSource(0);
|
|
Operand y = operation.GetSource(1);
|
|
|
|
if (IsConstEqual(y, comparand))
|
|
{
|
|
operation.TurnIntoCopy(x);
|
|
}
|
|
}
|
|
|
|
private static void TryEliminateBinaryOpComutative(Operation operation, ulong comparand)
|
|
{
|
|
Operand x = operation.GetSource(0);
|
|
Operand y = operation.GetSource(1);
|
|
|
|
if (IsConstEqual(x, comparand))
|
|
{
|
|
operation.TurnIntoCopy(y);
|
|
}
|
|
else if (IsConstEqual(y, comparand))
|
|
{
|
|
operation.TurnIntoCopy(x);
|
|
}
|
|
}
|
|
|
|
private static void TryEliminateConditionalSelect(Operation operation)
|
|
{
|
|
Operand cond = operation.GetSource(0);
|
|
|
|
if (cond.Kind != OperandKind.Constant)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// The condition is constant, we can turn it into a copy, and select
|
|
// the source based on the condition value.
|
|
int srcIndex = cond.Value != 0 ? 1 : 2;
|
|
|
|
Operand source = operation.GetSource(srcIndex);
|
|
|
|
operation.TurnIntoCopy(source);
|
|
}
|
|
|
|
private static bool IsConstEqual(Operand operand, ulong comparand)
|
|
{
|
|
if (operand.Kind != OperandKind.Constant || !operand.Type.IsInteger())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return operand.Value == comparand;
|
|
}
|
|
|
|
private static ulong AllOnes(OperandType type)
|
|
{
|
|
return type switch
|
|
{
|
|
OperandType.I32 => ~0U,
|
|
OperandType.I64 => ~0UL,
|
|
_ => throw new ArgumentException("Invalid operand type \"" + type + "\"."),
|
|
};
|
|
}
|
|
}
|
|
}
|