From 36ec1bc6c023811235d9f5fb664feff09bc7b4f7 Mon Sep 17 00:00:00 2001 From: FICTURE7 <FICTURE7@gmail.com> Date: Sat, 12 Sep 2020 19:32:53 +0400 Subject: 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 --- ARMeilleure/Translation/ControlFlowGraph.cs | 94 ++++++++++++----------------- 1 file changed, 37 insertions(+), 57 deletions(-) (limited to 'ARMeilleure/Translation/ControlFlowGraph.cs') diff --git a/ARMeilleure/Translation/ControlFlowGraph.cs b/ARMeilleure/Translation/ControlFlowGraph.cs index 16b406ab..34963534 100644 --- a/ARMeilleure/Translation/ControlFlowGraph.cs +++ b/ARMeilleure/Translation/ControlFlowGraph.cs @@ -8,47 +8,48 @@ namespace ARMeilleure.Translation class ControlFlowGraph { public BasicBlock Entry { get; } - public IntrusiveList<BasicBlock> Blocks { get; } - public BasicBlock[] PostOrderBlocks { get; } - public int[] PostOrderMap { get; } public ControlFlowGraph(BasicBlock entry, IntrusiveList<BasicBlock> blocks) { - Entry = entry; + Entry = entry; Blocks = blocks; RemoveUnreachableBlocks(blocks); - HashSet<BasicBlock> visited = new HashSet<BasicBlock>(); - - Stack<BasicBlock> blockStack = new Stack<BasicBlock>(); + var visited = new HashSet<BasicBlock>(); + var blockStack = new Stack<BasicBlock>(); PostOrderBlocks = new BasicBlock[blocks.Count]; - PostOrderMap = new int[blocks.Count]; visited.Add(entry); - blockStack.Push(entry); int index = 0; while (blockStack.TryPop(out BasicBlock block)) { - if (block.Next != null && visited.Add(block.Next)) - { - blockStack.Push(block); - blockStack.Push(block.Next); - } - else if (block.Branch != null && visited.Add(block.Branch)) + bool visitedNew = false; + + for (int i = 0; i < block.SuccessorCount; i++) { - blockStack.Push(block); - blockStack.Push(block.Branch); + BasicBlock succ = block.GetSuccessor(i); + + if (visited.Add(succ)) + { + blockStack.Push(block); + blockStack.Push(succ); + + visitedNew = true; + + break; + } } - else + + if (!visitedNew) { PostOrderMap[block.Index] = index; @@ -59,26 +60,24 @@ namespace ARMeilleure.Translation private void RemoveUnreachableBlocks(IntrusiveList<BasicBlock> blocks) { - HashSet<BasicBlock> visited = new HashSet<BasicBlock>(); - - Queue<BasicBlock> workQueue = new Queue<BasicBlock>(); + var visited = new HashSet<BasicBlock>(); + var workQueue = new Queue<BasicBlock>(); visited.Add(Entry); - workQueue.Enqueue(Entry); while (workQueue.TryDequeue(out BasicBlock block)) { Debug.Assert(block.Index != -1, "Invalid block index."); - if (block.Next != null && visited.Add(block.Next)) + for (int i = 0; i < block.SuccessorCount; i++) { - workQueue.Enqueue(block.Next); - } + BasicBlock succ = block.GetSuccessor(i); - if (block.Branch != null && visited.Add(block.Branch)) - { - workQueue.Enqueue(block.Branch); + if (visited.Add(succ)) + { + workQueue.Enqueue(succ); + } } } @@ -93,8 +92,10 @@ namespace ARMeilleure.Translation if (!visited.Contains(block)) { - block.Next = null; - block.Branch = null; + while (block.SuccessorCount > 0) + { + block.RemoveSuccessor(index: block.SuccessorCount - 1); + } blocks.Remove(block); } @@ -112,14 +113,12 @@ namespace ARMeilleure.Translation { BasicBlock splitBlock = new BasicBlock(Blocks.Count); - if (predecessor.Next == successor) + for (int i = 0; i < predecessor.SuccessorCount; i++) { - predecessor.Next = splitBlock; - } - - if (predecessor.Branch == successor) - { - predecessor.Branch = splitBlock; + if (predecessor.GetSuccessor(i) == successor) + { + predecessor.SetSuccessor(i, splitBlock); + } } if (splitBlock.Predecessors.Count == 0) @@ -127,26 +126,7 @@ namespace ARMeilleure.Translation throw new ArgumentException("Predecessor and successor are not connected."); } - // Insert the new block on the list of blocks. - BasicBlock succPrev = successor.ListPrevious; - - if (succPrev != null && succPrev != predecessor && succPrev.Next == successor) - { - // Can't insert after the predecessor or before the successor. - // Here, we insert it before the successor by also spliting another - // edge (the one between the block before "successor" and "successor"). - BasicBlock splitBlock2 = new BasicBlock(splitBlock.Index + 1); - - succPrev.Next = splitBlock2; - - splitBlock2.Branch = successor; - - splitBlock2.Operations.AddLast(OperationHelper.Operation(Instruction.Branch, null)); - - Blocks.AddBefore(successor, splitBlock2); - } - - splitBlock.Next = successor; + splitBlock.AddSuccessor(successor); Blocks.AddBefore(successor, splitBlock); -- cgit v1.2.3-70-g09d2