aboutsummaryrefslogtreecommitdiff
path: root/ARMeilleure/CodeGen/Optimizations/Optimizer.cs
diff options
context:
space:
mode:
authorFicture Seven <FICTURE7@gmail.com>2020-08-05 02:52:33 +0400
committerGitHub <noreply@github.com>2020-08-05 08:52:33 +1000
commitee22517d92c48eab9643b6fc8ce4dac2b7e95f57 (patch)
tree5df92a3e83f9daafba44ad11862683af8185ffaf /ARMeilleure/CodeGen/Optimizations/Optimizer.cs
parenta33dc2f4919f7fdc8ea9db41c4c70c38cedfd3df (diff)
Improve branch operations (#1442)
* Add Compare instruction * Add BranchIf instruction * Use test when BranchIf & Compare against 0 * Propagate Compare into BranchIfTrue/False use - Propagate Compare operations into their BranchIfTrue/False use and turn these into a BranchIf. - Clean up Comparison enum. * Replace BranchIfTrue/False with BranchIf * Use BranchIf in EmitPtPointerLoad - Using BranchIf early instead of BranchIfTrue/False improves LCQ and reduces the amount of work needed by the Optimizer. EmitPtPointerLoader was a/the big producer of BranchIfTrue/False. - Fix asserts firing when assembling BitwiseAnd because of type mismatch in EmitStoreExclusive. This is harmless and should not cause any diffs. * Increment PPTC interval version * Improve IRDumper for BranchIf & Compare * Use BranchIf in EmitNativeCall * Clean up * Do not emit test when immediately preceded by and
Diffstat (limited to 'ARMeilleure/CodeGen/Optimizations/Optimizer.cs')
-rw-r--r--ARMeilleure/CodeGen/Optimizations/Optimizer.cs114
1 files changed, 109 insertions, 5 deletions
diff --git a/ARMeilleure/CodeGen/Optimizations/Optimizer.cs b/ARMeilleure/CodeGen/Optimizations/Optimizer.cs
index 06118bfd..438010a2 100644
--- a/ARMeilleure/CodeGen/Optimizations/Optimizer.cs
+++ b/ARMeilleure/CodeGen/Optimizations/Optimizer.cs
@@ -2,6 +2,8 @@ using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.Translation;
using System.Diagnostics;
+using static ARMeilleure.IntermediateRepresentation.OperandHelper;
+
namespace ARMeilleure.CodeGen.Optimizations
{
static class Optimizer
@@ -42,13 +44,25 @@ namespace ARMeilleure.CodeGen.Optimizations
Simplification.RunPass(operation);
- if (DestIsLocalVar(operation) && IsPropagableCopy(operation))
- {
- PropagateCopy(operation);
+ if (DestIsLocalVar(operation))
+ {
+ if (IsPropagableCompare(operation))
+ {
+ modified |= PropagateCompare(operation);
- RemoveNode(block, node);
+ if (modified && IsUnused(operation))
+ {
+ RemoveNode(block, node);
+ }
+ }
+ else if (IsPropagableCopy(operation))
+ {
+ PropagateCopy(operation);
- modified = true;
+ RemoveNode(block, node);
+
+ modified = true;
+ }
}
node = nextNode;
@@ -88,6 +102,91 @@ namespace ARMeilleure.CodeGen.Optimizations
while (modified);
}
+ private static bool PropagateCompare(Operation compOp)
+ {
+ // Try to propagate Compare operations into their BranchIf uses, when these BranchIf uses are in the form
+ // of:
+ //
+ // - BranchIf %x, 0x0, Equal ;; i.e BranchIfFalse %x
+ // - BranchIf %x, 0x0, NotEqual ;; i.e BranchIfTrue %x
+ //
+ // The commutative property of Equal and NotEqual is taken into consideration as well.
+ //
+ // For example:
+ //
+ // %x = Compare %a, %b, comp
+ // BranchIf %x, 0x0, NotEqual
+ //
+ // =>
+ //
+ // BranchIf %a, %b, comp
+
+ static bool IsZeroBranch(Operation operation, out Comparison compType)
+ {
+ compType = Comparison.Equal;
+
+ if (operation.Instruction != Instruction.BranchIf)
+ {
+ return false;
+ }
+
+ Operand src1 = operation.GetSource(0);
+ Operand src2 = operation.GetSource(1);
+ Operand comp = operation.GetSource(2);
+
+ compType = (Comparison)comp.AsInt32();
+
+ return (src1.Kind == OperandKind.Constant && src1.Value == 0) ||
+ (src2.Kind == OperandKind.Constant && src2.Value == 0);
+ }
+
+ bool modified = false;
+
+ Operand dest = compOp.Destination;
+ Operand src1 = compOp.GetSource(0);
+ Operand src2 = compOp.GetSource(1);
+ Operand comp = compOp.GetSource(2);
+
+ Comparison compType = (Comparison)comp.AsInt32();
+
+ Node[] uses = dest.Uses.ToArray();
+
+ foreach (Node use in uses)
+ {
+ if (!(use is Operation operation))
+ {
+ continue;
+ }
+
+ // If operation is a BranchIf and has a constant value 0 in its RHS or LHS source operands.
+ if (IsZeroBranch(operation, out Comparison otherCompType))
+ {
+ Comparison propCompType;
+
+ if (otherCompType == Comparison.NotEqual)
+ {
+ propCompType = compType;
+ }
+ else if (otherCompType == Comparison.Equal)
+ {
+ propCompType = compType.Invert();
+ }
+ else
+ {
+ continue;
+ }
+
+ operation.SetSource(0, src1);
+ operation.SetSource(1, src2);
+ operation.SetSource(2, Const((int)propCompType));
+
+ modified = true;
+ }
+ }
+
+ return modified;
+ }
+
private static void PropagateCopy(Operation copyOp)
{
// Propagate copy source operand to all uses of the destination operand.
@@ -143,6 +242,11 @@ namespace ARMeilleure.CodeGen.Optimizations
|| operation.Instruction == Instruction.CompareAndSwap8);
}
+ private static bool IsPropagableCompare(Operation operation)
+ {
+ return operation.Instruction == Instruction.Compare;
+ }
+
private static bool IsPropagableCopy(Operation operation)
{
if (operation.Instruction != Instruction.Copy)