Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Finish off Ssa #356

Merged
merged 13 commits into from
Sep 12, 2023
16 changes: 0 additions & 16 deletions ILCompiler/Compiler/BasicBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,5 @@ public BasicBlock(int offset)
StartOffset = offset;
Label = LabelGenerator.GetLabel(LabelType.BasicBlock);
}

public void InsertStatementAtStart(StackEntry statement)
{
var currentFirst = FirstNode;
FirstNode = statement;

var lastNodeInStatement = statement;
while (lastNodeInStatement.Next != null)
{
lastNodeInStatement = lastNodeInStatement.Next;
}

lastNodeInStatement.Next = currentFirst;

Statements.Insert(0, statement);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,6 @@ public GenericStackEntryAdapter(IGenericStackEntryVisitor genericVisitor)
public void Visit(StaticFieldEntry entry) => _genericStackEntryVisitor.Visit<StaticFieldEntry>(entry);
public void Visit(CommaEntry entry) => _genericStackEntryVisitor.Visit<CommaEntry>(entry);
public void Visit(PhiNode entry) => _genericStackEntryVisitor.Visit<PhiNode>(entry);
public void Visit(PhiArg entry) => _genericStackEntryVisitor.Visit<PhiArg>(entry);
}
}
1 change: 1 addition & 0 deletions ILCompiler/Compiler/EvaluationStack/IStackEntryVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@ public interface IStackEntryVisitor
public void Visit(StaticFieldEntry entry);
public void Visit(CommaEntry entry);
public void Visit(PhiNode entry);
public void Visit(PhiArg entry);
}
}
2 changes: 1 addition & 1 deletion ILCompiler/Compiler/EvaluationStack/LocalVariableEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
public class LocalVariableEntry : StackEntry, ILocalVariable
{
public int LocalNumber { get; }
public int SsaNumber { get; }
public int SsaNumber { get; set; }
public LocalVariableEntry(int localNumber, VarType type, int? exactSize) : base(type, exactSize)
{
LocalNumber = localNumber;
Expand Down
26 changes: 26 additions & 0 deletions ILCompiler/Compiler/EvaluationStack/PhiArg.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
namespace ILCompiler.Compiler.EvaluationStack
{
public class PhiArg : StackEntry, ILocalVariable
{
public int LocalNumber { get; }
public int SsaNumber { get; }
public BasicBlock Block { get; }

public PhiArg(VarType type, int localNumber, int ssaNumber, BasicBlock block) : base(type)
{
LocalNumber = localNumber;
SsaNumber = ssaNumber;
Block = block;
}

public override StackEntry Duplicate()
{
return new PhiArg(Type, LocalNumber, SsaNumber, Block);
}

public override void Accept(IStackEntryVisitor visitor)
{
visitor.Visit(this);
}
}
}
10 changes: 9 additions & 1 deletion ILCompiler/Compiler/EvaluationStack/PhiNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,21 @@
{
public class PhiNode : StackEntry
{
public IList<PhiArg> Arguments { get; }

public PhiNode(VarType type) : base(type)
{
Arguments = new List<PhiArg>();
}

public PhiNode(VarType type, IList<PhiArg> arguments) : base(type)
{
Arguments = arguments;
}

public override StackEntry Duplicate()
{
return new PhiNode(Type);
return new PhiNode(Type, Arguments);
}

public override void Accept(IStackEntryVisitor visitor)
Expand Down
2 changes: 2 additions & 0 deletions ILCompiler/Compiler/EvaluationStack/StackEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ public abstract class StackEntry : IVisitableStackEntry
public int? ExactSize { get; }

public StackEntry? Next { get; set; }
public StackEntry? Prev { get; set; }

public int TreeID { get; }

private static int _treeID = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ public class StoreLocalVariableEntry : StackEntry, ILocalVariable
public StackEntry Op1 { get; }

public int LocalNumber { get; }
public int SsaNumber { get; }
public int SsaNumber { get; set; }

public bool IsParameter { get; }

Expand Down
6 changes: 6 additions & 0 deletions ILCompiler/Compiler/Flowgraph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -196,11 +196,17 @@ public void Visit(PhiNode entry)
SetNext(entry);
}

public void Visit(PhiArg entry)
{
SetNext(entry);
}

private void SetNext(StackEntry entry)
{
if (Current != null)
{
Current.Next = entry;
entry.Prev = Current;
}
Current = entry;
if (First == null)
Expand Down
4 changes: 3 additions & 1 deletion ILCompiler/Compiler/Importer/AddressOfVarImporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ public bool Import(Instruction instruction, ImportContext context, IILImporterPr
{
case Code.Ldloca:
case Code.Ldloca_S:
importer.PushExpression(new LocalVariableAddressEntry(importer.ParameterCount + (instruction.OperandAs<Local>()).Index));
var localNumber = importer.ParameterCount + (instruction.OperandAs<Local>()).Index;
importer.PushExpression(new LocalVariableAddressEntry(localNumber));
importer.LocalVariableTable[localNumber].AddressExposed = true;
return true;
default:
return false;
Expand Down
6 changes: 4 additions & 2 deletions ILCompiler/Compiler/Importer/LoadArgAddressImporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ public bool Import(Instruction instruction, ImportContext context, IILImporterPr
case Code.Ldarga:
case Code.Ldarga_S:
var index = (instruction.OperandAs<Parameter>()).Index;
var lclNum = MapIlArgNum(index, importer.ReturnBufferArgIndex);
var localNumber = MapIlArgNum(index, importer.ReturnBufferArgIndex);

importer.PushExpression(new LocalVariableAddressEntry(lclNum));
importer.PushExpression(new LocalVariableAddressEntry(localNumber));

importer.LocalVariableTable[localNumber].AddressExposed = true;

return true;

Expand Down
17 changes: 16 additions & 1 deletion ILCompiler/Compiler/LIRDumper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,22 @@ public void Visit(StoreLocalVariableEntry entry)

public void Visit(PhiNode entry)
{
_sb.AppendLine($" phi");
var firstArg = true;
foreach (var argument in entry.Arguments)
{
_sb.Append(" ");
_sb.Append(firstArg ? "┌──▌" : "├──▌");
_sb.Append(" ");
_sb.AppendLine($"t{argument.TreeID}");
firstArg = false;
}

_sb.AppendLine($"t{entry.TreeID,-3} = phi");
}

public void Visit(PhiArg entry)
{
_sb.AppendLine($"t{entry.TreeID,-3} = phiarg {entry.Type} V{entry.LocalNumber:00} ssa{entry.SsaNumber}");
}

public void Visit(CallEntry entry)
Expand Down
14 changes: 12 additions & 2 deletions ILCompiler/Compiler/LocalVariableDescriptor.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using ILCompiler.Common.TypeSystem.IL;
using ILCompiler.Compiler.Lowerings;
using ILCompiler.Compiler.Ssa;

namespace ILCompiler.Compiler
{
Expand All @@ -17,5 +18,14 @@ public class LocalVariableDescriptor
public string Name = string.Empty;

public bool MustInit { get; set; } = false;
public bool Tracked { get; set; } = false;

public bool AddressExposed { get; set; } = false;

public bool InSsa { get; set; } = false;

public SsaDefList<LocalSsaVariableDescriptor> PerSsaData { get; set; } = new SsaDefList<LocalSsaVariableDescriptor>();

public LocalSsaVariableDescriptor GetPerSsaData(int ssaNumber) => PerSsaData.SsaDefinition(ssaNumber);
}
}
}
2 changes: 1 addition & 1 deletion ILCompiler/Compiler/MethodCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ public void CompileMethod(Z80MethodCodeNode methodCodeNodeNeedingCode)
flowgraph.SetBlockOrder(basicBlocks);

var ssaBuilder = _phaseFactory.Create<ISsaBuilder>();
ssaBuilder.Build(basicBlocks, _localVariableTable);
ssaBuilder.Build(basicBlocks, _localVariableTable, _configuration.DumpSsa);

if (_configuration.DumpIRTrees)
{
Expand Down
29 changes: 22 additions & 7 deletions ILCompiler/Compiler/Rationalizer.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using ILCompiler.Compiler.EvaluationStack;
using ILCompiler.Interfaces;
using System.Diagnostics;

namespace ILCompiler.Compiler
{
Expand Down Expand Up @@ -34,15 +35,29 @@ private static void RemoveCommaNodes(BasicBlock block)

private static void RemovePhiNodes(BasicBlock block)
{
var statement = block.Statements[0];
while (statement is PhiNode)
var node = block.FirstNode;
while (node is PhiArg || node is PhiNode)
{
// Remove PhiNode statement
var nextStatement = statement.Next?.Next;
block.Statements.RemoveAt(0);
block.FirstNode = nextStatement;
// Remove PhiArgs
while (node is PhiArg)
{
node = node.Next;
}

// Remove PhiNode and StoreLocalVariableEntry
Debug.Assert(node is PhiNode);
node = node.Next;
Debug.Assert(node is StoreLocalVariableEntry);
node = node.Next;

statement = nextStatement;
// Remove statement
block.Statements.RemoveAt(0);
}

block.FirstNode = node;
if (node != null)
{
node.Prev = null;
}
}
}
Expand Down
1 change: 0 additions & 1 deletion ILCompiler/Compiler/Ssa/DominatorTreeNode.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
namespace ILCompiler.Compiler.Ssa
{
// TODO: Will need ability to do a pre order traversal of this tree
internal sealed class DominatorTreeNode
{
public BasicBlock Block { get; private set; }
Expand Down
34 changes: 34 additions & 0 deletions ILCompiler/Compiler/Ssa/DominatorTreeVisitor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
namespace ILCompiler.Compiler.Ssa
{
internal class DominatorTreeVisitor
{
readonly DominatorTreeNode _root;
public DominatorTreeVisitor(DominatorTreeNode root)
{
_root = root;
}

public virtual void PreOrderVisit(BasicBlock block)
{

}

public virtual void PostOrderVisit(BasicBlock block)
{
}

public void WalkTree() => WalkTree(_root);

private void WalkTree(DominatorTreeNode node)
{
PreOrderVisit(node.Block);

foreach (var child in node.Children)
{
WalkTree(child);
}

PostOrderVisit(node.Block);
}
}
}
33 changes: 33 additions & 0 deletions ILCompiler/Compiler/Ssa/LocalSsaVariableDescriptor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
namespace ILCompiler.Compiler.Ssa
{
public class LocalSsaVariableDescriptor
{
public BasicBlock Block { get; set; }

public bool HasGlobalUse { get; private set; } = false;
public bool HasPhiUse { get; private set; } = false;

public int NumberOfUses { get; private set; } = 0;

public LocalSsaVariableDescriptor(BasicBlock block)
{
Block = block;
}

public void AddUse(BasicBlock block)
{
if (block != Block)
{
HasGlobalUse = true;
}

NumberOfUses++;
}

public void AddPhiUse(BasicBlock block)
{
HasPhiUse = true;
AddUse(block);
}
}
}
33 changes: 33 additions & 0 deletions ILCompiler/Compiler/Ssa/SsaDefList.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
namespace ILCompiler.Compiler.Ssa
{
// A resizable array of Ssa Definitions
public class SsaDefList<T>
{
readonly IList<T> _list = new List<T>();

static int MinSsaNumber { get; } = 1;

public int AllocSsaNumber(Func<T> ctor)
{
var ssaNumber = SsaDefList<T>.MinSsaNumber + _list.Count;
_list.Add(ctor());

return ssaNumber;
}

public int Count { get { return _list.Count; } }

public T SsaDefinitionByIndex(int index) => _list[index];

public bool IsValidSsaNumber(int ssaNumber) => MinSsaNumber <= ssaNumber && (ssaNumber < (MinSsaNumber + _list.Count));

public T SsaDefinition(int ssaNumber) => SsaDefinitionByIndex(ssaNumber - MinSsaNumber);

public int GetSsaNumber(T ssaDefinition)
{
var index = _list.IndexOf(ssaDefinition);
if (index == - 1) throw new ArgumentException($"Invalid ssaDefinition {ssaDefinition}.", nameof(ssaDefinition));
return index + MinSsaNumber;
}
}
}
Loading
Loading