Skip to content

Commit

Permalink
Phi Branch Hoisting (mosa#1154)
Browse files Browse the repository at this point in the history
  • Loading branch information
tgiphil authored Oct 19, 2023
1 parent ea73ca4 commit 75464aa
Show file tree
Hide file tree
Showing 48 changed files with 624 additions and 75 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) MOSA Project. Licensed under the New BSD License.

using System.Diagnostics;

namespace Mosa.Compiler.Common.Exceptions;

[Serializable]
public class InvalidOperationCompilerException : CompilerException
{
/// <summary>
/// Initializes a new instance of the <see cref="InvalidOperationCompilerException"/> class.
/// </summary>
public InvalidOperationCompilerException() : base()
{
var callStack = new StackFrame(1, true);
var method = callStack.GetMethod();

BaseMessage = $"Invalid Operation: {method.DeclaringType.Name}.{method.Name} at line {callStack.GetFileLineNumber}";
}

public InvalidOperationCompilerException(string message, bool includeMethod = true) : base(message)
{
if (includeMethod)
{
var callStack = new StackFrame(1, true);
var method = callStack.GetMethod();

BaseMessage = $"{message}: {method.DeclaringType.Name}.{method.Name} at line {callStack.GetFileLineNumber}";
}
}
}
4 changes: 2 additions & 2 deletions Source/Mosa.Compiler.Framework/BaseTransform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -973,7 +973,7 @@ protected static bool Compare32(ConditionCode conditionCode, Operand a, Operand
ConditionCode.UnsignedGreaterOrEqual => a.ConstantUnsigned32 >= b.ConstantUnsigned32,
ConditionCode.UnsignedLess => a.ConstantUnsigned32 < b.ConstantUnsigned32,
ConditionCode.UnsignedLessOrEqual => a.ConstantUnsigned32 <= b.ConstantUnsigned32,
_ => throw new InvalidCompilerOperationException()
_ => throw new InvalidOperationCompilerException()
};
}

Expand All @@ -991,7 +991,7 @@ protected static bool Compare64(ConditionCode conditionCode, Operand a, Operand
ConditionCode.UnsignedGreaterOrEqual => a.ConstantUnsigned64 >= b.ConstantUnsigned64,
ConditionCode.UnsignedLess => a.ConstantUnsigned64 < b.ConstantUnsigned64,
ConditionCode.UnsignedLessOrEqual => a.ConstantUnsigned64 <= b.ConstantUnsigned64,
_ => throw new InvalidCompilerOperationException()
_ => throw new InvalidOperationCompilerException()
};
}

Expand Down
11 changes: 10 additions & 1 deletion Source/Mosa.Compiler.Framework/Context.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Copyright (c) MOSA Project. Licensed under the New BSD License.

using System.Collections.Generic;
using System.Diagnostics;

namespace Mosa.Compiler.Framework;
Expand Down Expand Up @@ -230,6 +229,11 @@ public void GotoNext()
Node = Node.Next;
}

public void NextNonEmpty()
{
Node = Node.NextNonEmpty;
}

/// <summary>
/// Gotos to the previous instruction.
/// </summary>
Expand All @@ -238,6 +242,11 @@ public void GotoPrevious()
Node = Node.Previous;
}

public void PreviousNonEmpty()
{
Node = Node.PreviousNonEmpty;
}

/// <summary>
/// Appends an (empty) instruction after the current index.
/// </summary>
Expand Down
4 changes: 2 additions & 2 deletions Source/Mosa.Compiler.Framework/InstructionNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -937,7 +937,7 @@ public InstructionNode NextNonEmpty
next = next.Next;
}

return next.IsBlockEndInstruction ? null : next;
return next;
}
}

Expand All @@ -952,7 +952,7 @@ public InstructionNode PreviousNonEmpty
previous = previous.Previous;
}

return previous.IsBlockStartInstruction ? null : previous;
return previous;
}
}

Expand Down
6 changes: 3 additions & 3 deletions Source/Mosa.Compiler.Framework/MethodCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -703,7 +703,7 @@ public void SplitOperand(Operand operand, out Operand operandLow, out Operand op
return;
}

throw new InvalidCompilerOperationException();
throw new InvalidOperationCompilerException();
}

/// <summary>
Expand Down Expand Up @@ -980,7 +980,7 @@ public BaseInstruction GetLoadParamInstruction(ElementType elementType)
ElementType.I when Is32BitPlatform => IRInstruction.LoadParam32,
ElementType.I when Is64BitPlatform => IRInstruction.LoadParam64,
ElementType.ManagedPointer => IRInstruction.LoadParamManagedPointer,
_ => throw new InvalidCompilerOperationException(),
_ => throw new InvalidOperationCompilerException(),
};
}

Expand All @@ -995,7 +995,7 @@ public BaseInstruction GetReturnInstruction(PrimitiveType primitiveType)
PrimitiveType.Object => IRInstruction.SetReturnObject,
PrimitiveType.ValueType => IRInstruction.SetReturnCompound,
PrimitiveType.ManagedPointer => IRInstruction.SetReturnManagedPointer,
_ => throw new InvalidCompilerOperationException(),
_ => throw new InvalidOperationCompilerException(),
};
}

Expand Down
2 changes: 1 addition & 1 deletion Source/Mosa.Compiler.Framework/MosaTypeLayout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -750,7 +750,7 @@ private MosaMethod FindInterfaceMethod(MosaType type, MosaMethod interfaceMethod
if (methodFound != null)
return methodFound;

throw new InvalidCompilerOperationException($"Failed to find implicit interface implementation for type {type} and interface method {interfaceMethod}");
throw new InvalidOperationCompilerException($"Failed to find implicit interface implementation for type {type} and interface method {interfaceMethod}");
}

private MosaMethod FindImplicitInterfaceMethod(MosaType type, MosaMethod interfaceMethod)
Expand Down
1 change: 0 additions & 1 deletion Source/Mosa.Compiler.Framework/PhiHelper.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Copyright (c) MOSA Project. Licensed under the New BSD License.

using System.Collections.Generic;
using System.Diagnostics;

namespace Mosa.Compiler.Framework
Expand Down
2 changes: 1 addition & 1 deletion Source/Mosa.Compiler.Framework/Stages/CILDecoderStage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1168,7 +1168,7 @@ private BaseInstruction GetLoadInstruction(MosaType type)
else if ((type.IsI || type.IsN) && Is64BitPlatform)
return IRInstruction.Load64;

throw new InvalidCompilerOperationException();
throw new InvalidOperationCompilerException();
}

#endregion Instruction Maps
Expand Down
4 changes: 2 additions & 2 deletions Source/Mosa.Compiler.Framework/Stages/EnterSSAStage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ private int WhichPredecessor(BasicBlock y, BasicBlock x)
}
}

throw new InvalidCompilerOperationException();
throw new InvalidOperationCompilerException();
}

#endregion Helpers Methods
Expand Down Expand Up @@ -373,7 +373,7 @@ public static BaseInstruction GetPhiInstruction(PrimitiveType primitiveType)
PrimitiveType.R8 => IRInstruction.PhiR8,
PrimitiveType.Object => IRInstruction.PhiObject,
PrimitiveType.ManagedPointer => IRInstruction.PhiManagedPointer,
_ => throw new InvalidCompilerOperationException(),
_ => throw new InvalidOperationCompilerException(),
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public static class LowerTo32Transforms
new Branch64Extends(),
new Compare64x32EqualOrNotEqual(),
new Compare64x64EqualOrNotEqual(),
//Compare64x32UnsignedGreater(), //
//Compare64x32UnsignedGreater(),
new ArithShiftRight64By32(),
new ShiftRight64ByConstant32(),
new ShiftRight64ByConstant32Plus(),
Expand Down Expand Up @@ -42,7 +42,6 @@ public static class LowerTo32Transforms
new ZeroExtend32x64(),
new Move64(),

// LowerTo32 -- but try other transformations first!
new Compare64x32Rest(),
new Compare64x32RestInSSA(),
new Compare64x64Rest(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) MOSA Project. Licensed under the New BSD License.

namespace Mosa.Compiler.Framework.Transforms.Optimizations.Manual.ConstantMove;

public sealed class BranchManagedPointer : BaseTransform
{
public BranchManagedPointer() : base(IRInstruction.BranchManagedPointer, TransformType.Manual | TransformType.Optimization)
{
}

public override bool Match(Context context, TransformContext transform)
{
if (IsConstant(context.Operand2))
return false;

if (!IsConstant(context.Operand1))
return false;

if (context.Block.NextBlocks.Count == 1)
return false;

return true;
}

public override void Transform(Context context, TransformContext transform)
{
context.SetInstruction(IRInstruction.BranchManagedPointer, context.ConditionCode.GetReverse(), context.Result, context.Operand2, context.Operand1, context.BranchTargets[0]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) MOSA Project. Licensed under the New BSD License.

namespace Mosa.Compiler.Framework.Transforms.Optimizations.Manual.ConstantMove;

public sealed class BranchObject : BaseTransform
{
public BranchObject() : base(IRInstruction.BranchObject, TransformType.Manual | TransformType.Optimization)
{
}

public override bool Match(Context context, TransformContext transform)
{
if (IsConstant(context.Operand2))
return false;

if (!IsConstant(context.Operand1))
return false;

if (context.Block.NextBlocks.Count == 1)
return false;

return true;
}

public override void Transform(Context context, TransformContext transform)
{
context.SetInstruction(IRInstruction.BranchObject, context.ConditionCode.GetReverse(), context.Result, context.Operand2, context.Operand1, context.BranchTargets[0]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ public static class ManualTransforms
new ConstantMove.Compare64x64(),
new ConstantMove.Branch32(),
new ConstantMove.Branch64(),
new ConstantMove.BranchObject(),
new ConstantMove.BranchManagedPointer(),
new ConstantMove.AddCarryOut32(),
new ConstantMove.AddCarryOut64(),
new ConstantMove.AddOverflowOut32(),
Expand Down Expand Up @@ -99,7 +101,7 @@ public static class ManualTransforms
new Propagate.MoveObjectPropagate(),
new Propagate.MoveManagedPointerPropagate(),
new Propagate.MoveObjectPropagateConstant(),
// new Propagate.MoveManagedPointerPropagateConstant(),
new Propagate.MoveManagedPointerPropagateConstant(),

new Propagate.Phi32Propagate(),
new Propagate.Phi64Propagate(),
Expand Down Expand Up @@ -293,5 +295,18 @@ public static class ManualTransforms
new Useless.ZeroExtend8x32Compare32x32(),
new Useless.ZeroExtend8x64Compare32x64(),
new Useless.ZeroExtend8x64Compare64x64(),

new ConstantMove.BranchManagedPointer(),
new ConstantMove.BranchObject(),

new Phi.Phi32BranchHoisting(),
new Phi.Phi64BranchHoisting(),
new Phi.PhiObjectBranchHoisting(),
new Phi.PhiManagedPointerBranchHoisting(),

new Phi.PhiObjectDead(),
new Phi.PhiObjectUpdate(),
new Phi.PhiManagedPointerDead(),
new Phi.PhiManagedPointerUpdate(),
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright (c) MOSA Project. Licensed under the New BSD License.

namespace Mosa.Compiler.Framework.Transforms.Optimizations.Manual.Phi
{
public abstract class BasePhiTransform : BaseTransform
{
public BasePhiTransform(BaseInstruction instruction, TransformType type, bool log = false)
: base(instruction, type, log)
{ }

#region Helpers

protected static void ReplaceBranchTarget(BasicBlock source, BasicBlock oldTarget, BasicBlock newTarget)
{
for (var node = source.BeforeLast; !node.IsBlockStartInstruction; node = node.Previous)
{
if (node.IsEmptyOrNop)
continue;

if (node.Instruction.IsConditionalBranch || node.Instruction.IsUnconditionalBranch)
{
if (node.BranchTargets[0] == oldTarget)
{
node.UpdateBranchTarget(0, newTarget);
}
continue;
}

break;
}
}

#endregion Helpers

#region Phi Helpers

public static void UpdatePhiTarget(BasicBlock target, BasicBlock source, BasicBlock newSource)
{
PhiHelper.UpdatePhiTarget(target, source, newSource);
}

public static void UpdatePhiTargets(List<BasicBlock> targets, BasicBlock source, BasicBlock newSource)
{
PhiHelper.UpdatePhiTargets(targets, source, newSource);
}

public static void UpdatePhiBlocks(List<BasicBlock> phiBlocks)
{
PhiHelper.UpdatePhiBlocks(phiBlocks);
}

public static void UpdatePhiBlock(BasicBlock phiBlock)
{
PhiHelper.UpdatePhiBlock(phiBlock);
}

public static void UpdatePhi(InstructionNode node)
{
PhiHelper.UpdatePhi(node);
}

#endregion Phi Helpers
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Mosa.Compiler.Framework.Transforms.Optimizations.Manual.Phi;

public sealed class Phi32Add32 : BaseTransform
public sealed class Phi32Add32 : BasePhiTransform
{
public Phi32Add32() : base(IRInstruction.Phi32, TransformType.Manual | TransformType.Optimization)
{
Expand Down
Loading

0 comments on commit 75464aa

Please sign in to comment.