Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
2eddd40
Update packages
tgiphil May 10, 2026
25a6f6f
Updated QEMU
tgiphil May 10, 2026
ed110d9
Track disabled transforms in BisectorState
tgiphil May 11, 2026
e9ce3f6
Remove redundant block transform hook logic
tgiphil May 11, 2026
59a9b48
Add FilePostfix setting for output filename customization
tgiphil May 11, 2026
14203f2
Refactor NuGet packaging for Mosa.Templates in CI
tgiphil May 11, 2026
4e81343
Add FilePostfix and SearchPaths CLI args and docs
tgiphil May 11, 2026
a838553
Fix double zero/sign-extend transforms to preserve semantics
tgiphil May 12, 2026
29e19a6
Refactor 32/64-bit integer ops for correctness
tgiphil May 13, 2026
d432e74
Update bisector plan to 'random', fix Add32 logic bug
tgiphil May 13, 2026
2bb9919
Fix typo in reduce-qemu.bat file deletion command
tgiphil May 13, 2026
57f7850
Refactor transform hook registration in Initialize()
tgiphil May 13, 2026
2f6d3a9
Rename resultOperand to result in Compare32x32.Transform
tgiphil May 13, 2026
5dd4dc0
Refactor bisector settings and supervisor handling
tgiphil May 14, 2026
3466ba2
Refactor transform disabling logic and bisector stage usage
tgiphil May 15, 2026
e65f6fe
- More unit tests
tgiphil May 15, 2026
01c0358
- Removed most fuzzy logic unit tests
tgiphil May 15, 2026
d9af68a
Refactor SCCP to use new LatticeValue class
tgiphil May 15, 2026
dac1a4d
Move Bisector to Common; update references and refactor
tgiphil May 15, 2026
71a8664
Change Main to void, use Environment.Exit for exit code
tgiphil May 15, 2026
c685126
Merge branch 'master' into 610-bisector
tgiphil May 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright (c) MOSA Project. Licensed under the New BSD License.

namespace Mosa.Compiler.Framework;
namespace Mosa.Compiler.Common;

public sealed class Bisector<TItem>
{
Expand Down
9 changes: 1 addition & 8 deletions Source/Mosa.Compiler.Common/Frame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,6 @@ namespace Mosa.Compiler.Common
{
public static class Frame
{
public static string MethodName
{
get
{
var stackTrace = new StackTrace();
return stackTrace.GetFrame(1).GetMethod().Name;
}
}
public static string MethodName => new StackTrace().GetFrame(1).GetMethod().Name;
}
}
1 change: 1 addition & 0 deletions Source/Mosa.Compiler.Framework.xUnit/BisectorTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) MOSA Project. Licensed under the New BSD License.

using Mosa.Compiler.Common;
using Xunit;

namespace Mosa.Compiler.Framework.xUnit;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) MOSA Project. Licensed under the New BSD License.

using System.Diagnostics;
using System.Text;
using Mosa.Compiler.Framework;

namespace Mosa.Compiler.Framework.Analysis;

Expand All @@ -10,219 +10,9 @@ namespace Mosa.Compiler.Framework.Analysis;
/// </summary>
public sealed class SparseConditionalConstantPropagation
{
private sealed class VariableState
{
private enum VariableStatusType
{ Unknown, OverDefined, SingleConstant, MultipleConstants }

private enum ReferenceStatusType
{ Unknown, DefinedNotNull, OverDefined }

private const int MaxConstants = 4;

private VariableStatusType Status;

private ReferenceStatusType ReferenceStatus;

private int ConstantCount;

private readonly ulong[] ConstantValues = new ulong[MaxConstants];

public IEnumerable<ulong> GetConstants()
{
if (ConstantCount == 0)
yield break;

for (var i = 0; i < ConstantCount && i < ConstantValues.Length; i++)
{
yield return ConstantValues[i];
}
}

public ulong ConstantUnsignedLongInteger => ConstantValues[0];

public long ConstantSignedLongInteger => (long)ConstantValues[0];

public bool ConstantsContainZero
{
get
{
if (ConstantCount == 0)
return false;
for (var i = 0; i < ConstantCount && i < ConstantValues.Length; i++)
{
if (ConstantValues[i] == 0)
return true;
}
return false;
}
}

public Operand Operand { get; }

public bool IsOverDefined
{
get => Status == VariableStatusType.OverDefined;
set { Status = VariableStatusType.OverDefined; Debug.Assert(value); }
}

public bool IsUnknown => Status == VariableStatusType.Unknown;

public bool IsSingleConstant
{
get => Status == VariableStatusType.SingleConstant;
set { Status = VariableStatusType.SingleConstant; Debug.Assert(value); }
}

public bool HasMultipleConstants => Status == VariableStatusType.MultipleConstants;

public bool HasOnlyConstants => Status is VariableStatusType.SingleConstant or VariableStatusType.MultipleConstants;

public bool IsVirtualRegister { get; set; }

public bool IsReferenceType { get; set; }

public bool IsReferenceDefinedUnknown => ReferenceStatus == ReferenceStatusType.Unknown;

public bool IsReferenceDefinedNotNull
{
get => ReferenceStatus == ReferenceStatusType.DefinedNotNull;
set
{
Debug.Assert(value);
ReferenceStatus = ReferenceStatusType.DefinedNotNull;
}
}

public bool IsReferenceOverDefined
{
get => ReferenceStatus == ReferenceStatusType.OverDefined;
set
{
Debug.Assert(value);
ReferenceStatus = ReferenceStatusType.OverDefined;
}
}

public VariableState(Operand operand)
{
Operand = operand;

IsVirtualRegister = operand.IsVirtualRegister;
IsReferenceType = operand.IsObject;

if (IsVirtualRegister)
{
Status = VariableStatusType.Unknown;
IsVirtualRegister = true;
}
else if (operand.IsUnresolvedConstant)
{
IsOverDefined = true;
}
else if (operand.IsConstant && operand.IsInteger)
{
AddConstant(operand.ConstantUnsigned64);
}
else if (operand.IsNull)
{
AddConstant(0);
}
else
{
IsOverDefined = true;
}

if (!IsReferenceType || !IsVirtualRegister)
{
ReferenceStatus = ReferenceStatusType.OverDefined;
}
else
{
ReferenceStatus = ReferenceStatusType.Unknown;
}
}

public bool AddConstant(ulong value)
{
if (Status == VariableStatusType.OverDefined)
return false;

for (var i = 0; i < ConstantCount && i < ConstantValues.Length; i++)
{
if (ConstantValues[i] == value)
return false;
}

if (ConstantCount == 0)
{
ConstantValues[0] = value;
ConstantCount = 1;
Status = VariableStatusType.SingleConstant;
return true;
}
else if (ConstantCount < MaxConstants)
{
ConstantValues[ConstantCount] = value;
ConstantCount++;
Status = VariableStatusType.MultipleConstants;
return true;
}

ConstantCount = 0;
Status = VariableStatusType.OverDefined;
return true;
}

public void AddConstant(long value)
{
AddConstant((ulong)value);
}

public bool AreConstantsEqual(VariableState other)
{
if (!other.IsSingleConstant || !IsSingleConstant)
return false;

return other.ConstantUnsignedLongInteger == ConstantUnsignedLongInteger;
}

public override string ToString()
{
var sb = new StringBuilder();
sb.Append($"{Operand} : {Status}");

if (IsSingleConstant)
{
sb.Append($" = {ConstantUnsignedLongInteger}");
}
else if (HasMultipleConstants)
{
sb.Append($" ({ConstantCount}) =");
for (var i = 0; i < ConstantCount && i < ConstantValues.Length; i++)
{
sb.Append($" {ConstantValues[i]},");
}
if (sb.Length > 0 && sb[sb.Length - 1] == ',')
sb.Length--;
}

sb.Append(" [null: ");
if (IsReferenceOverDefined)
sb.Append("OverDefined");
else if (IsReferenceDefinedNotNull)
sb.Append("NotNull");
else if (IsReferenceDefinedUnknown)
sb.Append("Unknown");
sb.Append(']');

return sb.ToString();
}
}

private readonly bool[] blockStates;

private readonly Dictionary<Operand, VariableState> variableStates;
private readonly Dictionary<Operand, LatticeValue> variableStates;

private readonly Stack<Node> instructionWorkList;
private readonly Stack<BasicBlock> blockWorklist;
Expand All @@ -247,7 +37,7 @@ public SparseConditionalConstantPropagation(BasicBlocks basicBlocks, BaseMethodC
BasicBlocks = basicBlocks;
Is32BitPlatform = is32BitPlatform;

variableStates = new Dictionary<Operand, VariableState>();
variableStates = new Dictionary<Operand, LatticeValue>();
phiStatements = new HashSet<Node>();
instructionWorkList = new Stack<Node>();
blockWorklist = new Stack<BasicBlock>();
Expand Down Expand Up @@ -313,11 +103,11 @@ public List<BasicBlock> GetDeadBlocked()
return list;
}

private VariableState GetVariableState(Operand operand)
private LatticeValue GetVariableState(Operand operand)
{
if (!variableStates.TryGetValue(operand, out VariableState variable))
if (!variableStates.TryGetValue(operand, out LatticeValue variable))
{
variable = new VariableState(operand);
variable = new LatticeValue(operand);
variableStates.Add(operand, variable);
}

Expand Down Expand Up @@ -370,7 +160,7 @@ private void QueueInstruction(Node node)
instructionWorkList.Push(node);
}

private void QueueInstruction(VariableState variable)
private void QueueInstruction(LatticeValue variable)
{
foreach (var use in variable.Operand.Uses)
{
Expand Down Expand Up @@ -616,7 +406,7 @@ private bool ProcessInstruction(Node node)
return true;
}

private static bool? NullComparisionCheck(ConditionCode condition, VariableState operand1, VariableState operand2)
private static bool? NullComparisionCheck(ConditionCode condition, LatticeValue operand1, LatticeValue operand2)
{
// not null check
if (condition == ConditionCode.Equal)
Expand Down Expand Up @@ -675,7 +465,7 @@ private void CompareOperation(Node node)
IntegerOperation2(node);
}

private void UpdateToConstant(VariableState variable, ulong value)
private void UpdateToConstant(LatticeValue variable, ulong value)
{
Debug.Assert(!variable.IsOverDefined);

Expand All @@ -687,7 +477,7 @@ private void UpdateToConstant(VariableState variable, ulong value)
}
}

private void UpdateToOverDefined(VariableState variable)
private void UpdateToOverDefined(LatticeValue variable)
{
if (variable.IsOverDefined)
return;
Expand All @@ -699,17 +489,17 @@ private void UpdateToOverDefined(VariableState variable)
QueueInstruction(variable);
}

private void AssignedNewObject(VariableState variable)
private void AssignedNewObject(LatticeValue variable)
{
SetReferenceNotNull(variable);
}

private void SetReferenceOverdefined(VariableState variable)
private void SetReferenceOverdefined(LatticeValue variable)
{
SetReferenceNull(variable);
}

private void SetReferenceNull(VariableState variable)
private void SetReferenceNull(LatticeValue variable)
{
if (variable.IsReferenceOverDefined)
return;
Expand All @@ -721,7 +511,7 @@ private void SetReferenceNull(VariableState variable)
QueueInstruction(variable);
}

private void SetReferenceNotNull(VariableState variable)
private void SetReferenceNotNull(LatticeValue variable)
{
if (variable.IsReferenceOverDefined || variable.IsReferenceDefinedNotNull)
return;
Expand Down Expand Up @@ -774,7 +564,7 @@ private void Move(Node node)
}
}

private void CheckAndUpdateNullAssignment(VariableState result, VariableState operand)
private void CheckAndUpdateNullAssignment(LatticeValue result, LatticeValue operand)
{
if (result.IsReferenceDefinedUnknown || result.IsReferenceDefinedNotNull)
{
Expand Down
Loading
Loading