From c3c29993818097ad7fa75f15c56e40f02f770d53 Mon Sep 17 00:00:00 2001 From: Jesper Gravgaard Date: Thu, 27 Feb 2020 12:48:23 +0100 Subject: [PATCH] Refactored dominator calculation to happen scope by scope. --- .../kickc/model/ControlFlowGraph.java | 2 +- .../passes/calcs/PassNCalcDominators.java | 64 +++++++++++-------- 2 files changed, 38 insertions(+), 28 deletions(-) diff --git a/src/main/java/dk/camelot64/kickc/model/ControlFlowGraph.java b/src/main/java/dk/camelot64/kickc/model/ControlFlowGraph.java index 686840a92..b0244bd76 100644 --- a/src/main/java/dk/camelot64/kickc/model/ControlFlowGraph.java +++ b/src/main/java/dk/camelot64/kickc/model/ControlFlowGraph.java @@ -150,7 +150,7 @@ public class ControlFlowGraph implements Serializable { } ControlFlowBlock mainBlock = getMainBlock(); - if(mainBlock != null) { + if(mainBlock != null && !entryPointBlocks.contains(mainBlock)) { entryPointBlocks.add(mainBlock); } entryPointBlocks.add(getFirstBlock()); diff --git a/src/main/java/dk/camelot64/kickc/passes/calcs/PassNCalcDominators.java b/src/main/java/dk/camelot64/kickc/passes/calcs/PassNCalcDominators.java index 684eeafa8..5c802e01a 100644 --- a/src/main/java/dk/camelot64/kickc/passes/calcs/PassNCalcDominators.java +++ b/src/main/java/dk/camelot64/kickc/passes/calcs/PassNCalcDominators.java @@ -1,14 +1,16 @@ package dk.camelot64.kickc.passes.calcs; -import dk.camelot64.kickc.model.ControlFlowBlock; -import dk.camelot64.kickc.model.DominatorsBlock; -import dk.camelot64.kickc.model.DominatorsGraph; -import dk.camelot64.kickc.model.Program; +import dk.camelot64.kickc.model.InternalError; +import dk.camelot64.kickc.model.*; +import dk.camelot64.kickc.model.symbols.Procedure; +import dk.camelot64.kickc.model.symbols.Scope; import dk.camelot64.kickc.model.values.LabelRef; -import dk.camelot64.kickc.model.values.SymbolRef; +import dk.camelot64.kickc.model.values.ScopeRef; import java.util.ArrayList; +import java.util.Collection; import java.util.List; +import java.util.stream.Collectors; /** Finds the dominators for the control flow graph. */ public class PassNCalcDominators extends PassNCalcBase { @@ -29,41 +31,51 @@ public class PassNCalcDominators extends PassNCalcBase { public DominatorsGraph calculate() { DominatorsGraph dominatorsGraph = new DominatorsGraph(); + Collection procedures = getScope().getAllProcedures(true); + for(Procedure procedure : procedures) { + calculateDominators(procedure, dominatorsGraph); + } + calculateDominators(getScope(), dominatorsGraph); + + return dominatorsGraph; + } + + private void calculateDominators(Scope scope, DominatorsGraph dominatorsGraph) { // Initialize dominators: Dom[first]={first}, Dom[block]={all} List firstBlocks = new ArrayList<>(); - List entryPointBlocks = getGraph().getEntryPointBlocks(getProgram()); - for(ControlFlowBlock entryPointBlock : entryPointBlocks) { - LabelRef firstBlock = entryPointBlock.getLabel(); - // Skip main-block, as it will be called by @begin anyways - if(firstBlock.getFullName().equals(SymbolRef.MAIN_PROC_NAME)) continue; - DominatorsBlock firstDominators = dominatorsGraph.addDominators(firstBlock); - firstDominators.add(firstBlock); - firstBlocks.add(firstBlock); + LabelRef firstBlock; + if(scope instanceof Procedure) { + firstBlock = ((Procedure)scope).getRef().getLabelRef(); + } else if(scope.getRef().equals(ScopeRef.ROOT)) { + firstBlock = new LabelRef(LabelRef.BEGIN_BLOCK_NAME); + } else { + throw new InternalError("Scope type not handled! "+scope); } + DominatorsBlock firstDominators = dominatorsGraph.addDominators(firstBlock); + firstDominators.add(firstBlock); + firstBlocks.add(firstBlock); - List allBlocks = new ArrayList<>(); - for(ControlFlowBlock block : getGraph().getAllBlocks()) { - allBlocks.add(block.getLabel()); - } - for(ControlFlowBlock block : getGraph().getAllBlocks()) { - if(!firstBlocks.contains(block.getLabel())) { - DominatorsBlock dominatorsBlock = dominatorsGraph.addDominators(block.getLabel()); - dominatorsBlock.addAll(allBlocks); + List procedureBlocks = getGraph().getScopeBlocks(scope.getRef()).stream().map(ControlFlowBlock::getLabel).collect(Collectors.toList()); + for(LabelRef procedureBlock : procedureBlocks) { + if(!firstBlocks.contains(procedureBlock)) { + DominatorsBlock dominatorsBlock = dominatorsGraph.addDominators(procedureBlock); + dominatorsBlock.addAll(procedureBlocks); } } // Iteratively refine dominators until they do not change // For all nodes: // Dom[n] = {n} UNION ( INTERSECT Dom[p] for all p that are predecessors of n) - boolean change = false; + boolean change; do { change = false; - for(ControlFlowBlock block : getGraph().getAllBlocks()) { - if(!firstBlocks.contains(block.getLabel())) { + for(LabelRef procedureBlock : procedureBlocks) { + if(!firstBlocks.contains(procedureBlock)) { + ControlFlowBlock block = getGraph().getBlock(procedureBlock); List predecessors = getGraph().getPredecessors(block); DominatorsBlock newDominators = new DominatorsBlock(); - newDominators.addAll(allBlocks); + newDominators.addAll(procedureBlocks); for(ControlFlowBlock predecessor : predecessors) { DominatorsBlock predecessorDominators = dominatorsGraph.getDominators(predecessor.getLabel()); newDominators.intersect(predecessorDominators); @@ -76,9 +88,7 @@ public class PassNCalcDominators extends PassNCalcBase { } } } - } while(change); - return dominatorsGraph; }