aboutsummaryrefslogtreecommitdiff
path: root/ARMeilleure/Translation/EmitterContext.cs
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/Translation/EmitterContext.cs
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/Translation/EmitterContext.cs')
-rw-r--r--ARMeilleure/Translation/EmitterContext.cs20
1 files changed, 17 insertions, 3 deletions
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);
}
}
}