aboutsummaryrefslogtreecommitdiff
path: root/ARMeilleure/Translation/EmitterContext.cs
diff options
context:
space:
mode:
authorFICTURE7 <FICTURE7@gmail.com>2020-09-12 19:32:53 +0400
committerGitHub <noreply@github.com>2020-09-12 12:32:53 -0300
commit36ec1bc6c023811235d9f5fb664feff09bc7b4f7 (patch)
tree98d74ad92cdce8294bb5116bf7cd06acb55ff9da /ARMeilleure/Translation/EmitterContext.cs
parent3d055da5fc77f462e9c7099e08570213c0220cd4 (diff)
Relax block ordering constraints (#1535)
* Relax block ordering constraints Before `block.Next` had to follow `block.ListNext`, now it does not. Instead `CodeGenerator` will now emit the necessary jump instructions to ensure control flow. This makes control flow and block order modifications easier. It also eliminates some simple cases of redundant branches. * Set PPTC version
Diffstat (limited to 'ARMeilleure/Translation/EmitterContext.cs')
-rw-r--r--ARMeilleure/Translation/EmitterContext.cs44
1 files changed, 27 insertions, 17 deletions
diff --git a/ARMeilleure/Translation/EmitterContext.cs b/ARMeilleure/Translation/EmitterContext.cs
index a6cc55df..2261fb87 100644
--- a/ARMeilleure/Translation/EmitterContext.cs
+++ b/ARMeilleure/Translation/EmitterContext.cs
@@ -13,18 +13,17 @@ namespace ARMeilleure.Translation
class EmitterContext
{
- private Dictionary<Operand, BasicBlock> _irLabels;
-
- private IntrusiveList<BasicBlock> _irBlocks;
+ private readonly Dictionary<Operand, BasicBlock> _irLabels;
+ private readonly IntrusiveList<BasicBlock> _irBlocks;
private BasicBlock _irBlock;
+ private BasicBlock _ifBlock;
private bool _needsNewBlock;
public EmitterContext()
{
_irLabels = new Dictionary<Operand, BasicBlock>();
-
_irBlocks = new IntrusiveList<BasicBlock>();
_needsNewBlock = true;
@@ -57,16 +56,16 @@ namespace ARMeilleure.Translation
public void Branch(Operand label)
{
- Add(Instruction.Branch, null);
+ NewNextBlockIfNeeded();
- BranchToLabel(label);
+ BranchToLabel(label, uncond: true);
}
public void BranchIf(Operand label, Operand op1, Operand op2, Comparison comp)
{
Add(Instruction.BranchIf, null, op1, op2, Const((int)comp));
- BranchToLabel(label);
+ BranchToLabel(label, uncond: false);
}
public void BranchIfFalse(Operand label, Operand op1)
@@ -574,10 +573,7 @@ namespace ARMeilleure.Translation
private Operand Add(Intrinsic intrin, Operand dest, params Operand[] sources)
{
- if (_needsNewBlock)
- {
- NewNextBlock();
- }
+ NewNextBlockIfNeeded();
IntrinsicOperation operation = new IntrinsicOperation(intrin, dest, sources);
@@ -586,7 +582,7 @@ namespace ARMeilleure.Translation
return dest;
}
- private void BranchToLabel(Operand label)
+ private void BranchToLabel(Operand label, bool uncond)
{
if (!_irLabels.TryGetValue(label, out BasicBlock branchBlock))
{
@@ -595,7 +591,15 @@ namespace ARMeilleure.Translation
_irLabels.Add(label, branchBlock);
}
- _irBlock.Branch = branchBlock;
+ if (uncond)
+ {
+ _irBlock.AddSuccessor(branchBlock);
+ }
+ else
+ {
+ // Defer registration of successor to _irBlock so that the order of successors is correct.
+ _ifBlock = branchBlock;
+ }
_needsNewBlock = true;
}
@@ -629,9 +633,16 @@ namespace ARMeilleure.Translation
private void NextBlock(BasicBlock nextBlock)
{
- if (_irBlock != null && !EndsWithUnconditional(_irBlock))
+ if (_irBlock != null && _irBlock.SuccessorCount == 0 && !EndsWithUnconditional(_irBlock))
{
- _irBlock.Next = nextBlock;
+ _irBlock.AddSuccessor(nextBlock);
+
+ if (_ifBlock != null)
+ {
+ _irBlock.AddSuccessor(_ifBlock);
+
+ _ifBlock = null;
+ }
}
_irBlock = nextBlock;
@@ -642,8 +653,7 @@ namespace ARMeilleure.Translation
private static bool EndsWithUnconditional(BasicBlock block)
{
return block.Operations.Last is Operation lastOp &&
- (lastOp.Instruction == Instruction.Branch ||
- lastOp.Instruction == Instruction.Return ||
+ (lastOp.Instruction == Instruction.Return ||
lastOp.Instruction == Instruction.Tailcall);
}