diff options
author | FICTURE7 <FICTURE7@gmail.com> | 2021-05-17 03:54:53 +0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-17 01:54:53 +0200 |
commit | c805542b29975b0d9bf3ea324526f62cfe4331bf (patch) | |
tree | 7c29106997c8f08b9335f7de856518f103e7f42c /ARMeilleure/Translation/EmitterContext.cs | |
parent | 212e472c9fac8253456d710e0b071579da330c0a (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.cs | 20 |
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); } } } |