aboutsummaryrefslogtreecommitdiff
path: root/ARMeilleure
diff options
context:
space:
mode:
authorFICTURE7 <FICTURE7@gmail.com>2021-05-17 03:54:53 +0400
committerGitHub <noreply@github.com>2021-05-17 01:54:53 +0200
commitc805542b29975b0d9bf3ea324526f62cfe4331bf (patch)
tree7c29106997c8f08b9335f7de856518f103e7f42c /ARMeilleure
parent212e472c9fac8253456d710e0b071579da330c0a (diff)
Allow `LocalVariable` to be assigned more than once (#2288)
* Allow `LocalVariable` to be assigned more than once This allows us to write flow controls like loops and if-elses with LocalVariables participating in phi nodes. * Add `GetLocalNumber` to operand
Diffstat (limited to 'ARMeilleure')
-rw-r--r--ARMeilleure/CodeGen/RegisterAllocators/HybridAllocator.cs19
-rw-r--r--ARMeilleure/CodeGen/RegisterAllocators/LinearScanAllocator.cs2
-rw-r--r--ARMeilleure/IntermediateRepresentation/Operand.cs8
-rw-r--r--ARMeilleure/Translation/ControlFlowGraph.cs4
-rw-r--r--ARMeilleure/Translation/EmitterContext.cs20
-rw-r--r--ARMeilleure/Translation/SsaConstruction.cs10
6 files changed, 47 insertions, 16 deletions
diff --git a/ARMeilleure/CodeGen/RegisterAllocators/HybridAllocator.cs b/ARMeilleure/CodeGen/RegisterAllocators/HybridAllocator.cs
index aa10aea0..2f68c43f 100644
--- a/ARMeilleure/CodeGen/RegisterAllocators/HybridAllocator.cs
+++ b/ARMeilleure/CodeGen/RegisterAllocators/HybridAllocator.cs
@@ -83,9 +83,10 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
int intFreeRegisters = regMasks.IntAvailableRegisters;
int vecFreeRegisters = regMasks.VecAvailableRegisters;
- BlockInfo[] blockInfo = new BlockInfo[cfg.Blocks.Count];
+ var blockInfo = new BlockInfo[cfg.Blocks.Count];
- List<LocalInfo> locInfo = new List<LocalInfo>();
+ var locInfo = new List<LocalInfo>();
+ var locVisited = new HashSet<Operand>();
for (int index = cfg.PostOrderBlocks.Length - 1; index >= 0; index--)
{
@@ -109,7 +110,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
if (source.Kind == OperandKind.LocalVariable)
{
- locInfo[source.AsInt32() - 1].SetBlockIndex(block.Index);
+ locInfo[source.GetLocalNumber() - 1].SetBlockIndex(block.Index);
}
else if (source.Kind == OperandKind.Memory)
{
@@ -117,12 +118,12 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
if (memOp.BaseAddress != null)
{
- locInfo[memOp.BaseAddress.AsInt32() - 1].SetBlockIndex(block.Index);
+ locInfo[memOp.BaseAddress.GetLocalNumber() - 1].SetBlockIndex(block.Index);
}
if (memOp.Index != null)
{
- locInfo[memOp.Index.AsInt32() - 1].SetBlockIndex(block.Index);
+ locInfo[memOp.Index.GetLocalNumber() - 1].SetBlockIndex(block.Index);
}
}
}
@@ -135,9 +136,9 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
{
LocalInfo info;
- if (dest.Value != 0)
+ if (!locVisited.Add(dest))
{
- info = locInfo[dest.AsInt32() - 1];
+ info = locInfo[dest.GetLocalNumber() - 1];
}
else
{
@@ -198,7 +199,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
void AllocateRegister(Operand source, MemoryOperand memOp, int srcIndex)
{
- LocalInfo info = locInfo[source.AsInt32() - 1];
+ LocalInfo info = locInfo[source.GetLocalNumber() - 1];
info.UseCount++;
@@ -317,7 +318,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
continue;
}
- LocalInfo info = locInfo[dest.AsInt32() - 1];
+ LocalInfo info = locInfo[dest.GetLocalNumber() - 1];
if (info.UseCount == 0 && !info.PreAllocated)
{
diff --git a/ARMeilleure/CodeGen/RegisterAllocators/LinearScanAllocator.cs b/ARMeilleure/CodeGen/RegisterAllocators/LinearScanAllocator.cs
index cd36bdc0..88adeeb0 100644
--- a/ARMeilleure/CodeGen/RegisterAllocators/LinearScanAllocator.cs
+++ b/ARMeilleure/CodeGen/RegisterAllocators/LinearScanAllocator.cs
@@ -976,7 +976,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
{
if (operand.Kind == OperandKind.LocalVariable)
{
- return operand.AsInt32();
+ return operand.GetLocalNumber();
}
else if (operand.Kind == OperandKind.Register)
{
diff --git a/ARMeilleure/IntermediateRepresentation/Operand.cs b/ARMeilleure/IntermediateRepresentation/Operand.cs
index 7b486c55..ec023939 100644
--- a/ARMeilleure/IntermediateRepresentation/Operand.cs
+++ b/ARMeilleure/IntermediateRepresentation/Operand.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Runtime.CompilerServices;
namespace ARMeilleure.IntermediateRepresentation
@@ -91,6 +92,13 @@ namespace ARMeilleure.IntermediateRepresentation
return new Register((int)Value & 0xffffff, (RegisterType)(Value >> 24));
}
+ public int GetLocalNumber()
+ {
+ Debug.Assert(Kind == OperandKind.LocalVariable);
+
+ return (int)Value;
+ }
+
public byte AsByte()
{
return (byte)Value;
diff --git a/ARMeilleure/Translation/ControlFlowGraph.cs b/ARMeilleure/Translation/ControlFlowGraph.cs
index ee1a245e..4c76d5dd 100644
--- a/ARMeilleure/Translation/ControlFlowGraph.cs
+++ b/ARMeilleure/Translation/ControlFlowGraph.cs
@@ -10,15 +10,17 @@ namespace ARMeilleure.Translation
private BasicBlock[] _postOrderBlocks;
private int[] _postOrderMap;
+ public int LocalsCount { get; }
public BasicBlock Entry { get; }
public IntrusiveList<BasicBlock> Blocks { get; }
public BasicBlock[] PostOrderBlocks => _postOrderBlocks;
public int[] PostOrderMap => _postOrderMap;
- public ControlFlowGraph(BasicBlock entry, IntrusiveList<BasicBlock> blocks)
+ public ControlFlowGraph(BasicBlock entry, IntrusiveList<BasicBlock> blocks, int localsCount)
{
Entry = entry;
Blocks = blocks;
+ LocalsCount = localsCount;
Update(removeUnreachableBlocks: true);
}
diff --git a/ARMeilleure/Translation/EmitterContext.cs b/ARMeilleure/Translation/EmitterContext.cs
index 5c608b3d..cc2205ce 100644
--- a/ARMeilleure/Translation/EmitterContext.cs
+++ b/ARMeilleure/Translation/EmitterContext.cs
@@ -12,6 +12,8 @@ namespace ARMeilleure.Translation
{
class EmitterContext
{
+ private int _localsCount;
+
private readonly Dictionary<Operand, BasicBlock> _irLabels;
private readonly IntrusiveList<BasicBlock> _irBlocks;
@@ -23,6 +25,8 @@ namespace ARMeilleure.Translation
public EmitterContext()
{
+ _localsCount = 0;
+
_irLabels = new Dictionary<Operand, BasicBlock>();
_irBlocks = new IntrusiveList<BasicBlock>();
@@ -30,6 +34,15 @@ namespace ARMeilleure.Translation
_nextBlockFreq = BasicBlockFrequency.Default;
}
+ public Operand AllocateLocal(OperandType type)
+ {
+ Operand local = Local(type);
+
+ local.NumberLocal(++_localsCount);
+
+ return local;
+ }
+
public Operand Add(Operand op1, Operand op2)
{
return Add(Instruction.Add, Local(op1.Type), op1, op2);
@@ -223,9 +236,10 @@ namespace ARMeilleure.Translation
public Operand Copy(Operand dest, Operand op1)
{
- if (dest.Kind != OperandKind.Register)
+ if (dest.Kind != OperandKind.Register &&
+ (dest.Kind != OperandKind.LocalVariable || dest.GetLocalNumber() == 0))
{
- throw new ArgumentException($"Invalid dest operand kind \"{dest.Kind}\".");
+ throw new ArgumentException($"Destination operand must be a Register or a numbered LocalVariable.");
}
return Add(Instruction.Copy, dest, op1);
@@ -670,7 +684,7 @@ namespace ARMeilleure.Translation
public ControlFlowGraph GetControlFlowGraph()
{
- return new ControlFlowGraph(_irBlocks.First, _irBlocks);
+ return new ControlFlowGraph(_irBlocks.First, _irBlocks, _localsCount);
}
}
}
diff --git a/ARMeilleure/Translation/SsaConstruction.cs b/ARMeilleure/Translation/SsaConstruction.cs
index 1c6e83c9..76cb9a44 100644
--- a/ARMeilleure/Translation/SsaConstruction.cs
+++ b/ARMeilleure/Translation/SsaConstruction.cs
@@ -45,7 +45,7 @@ namespace ARMeilleure.Translation
public static void Construct(ControlFlowGraph cfg)
{
var globalDefs = new DefMap[cfg.Blocks.Count];
- var localDefs = new Operand[RegisterConsts.TotalCount];
+ var localDefs = new Operand[cfg.LocalsCount + RegisterConsts.TotalCount];
var dfPhiBlocks = new Queue<BasicBlock>();
@@ -264,6 +264,12 @@ namespace ARMeilleure.Translation
return true;
}
+ else if (operand is { Kind: OperandKind.LocalVariable } && operand.GetLocalNumber() > 0)
+ {
+ result = RegisterConsts.TotalCount + operand.GetLocalNumber() - 1;
+
+ return true;
+ }
result = -1;
@@ -274,7 +280,7 @@ namespace ARMeilleure.Translation
{
if (!TryGetId(operand, out int key))
{
- Debug.Fail("OperandKind must be Register.");
+ Debug.Fail("OperandKind must be Register or a numbered LocalVariable.");
}
return key;