1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-02-18 16:30:51 +00:00

Refactored dominator calculation to happen scope by scope.

This commit is contained in:
Jesper Gravgaard 2020-02-27 12:48:23 +01:00
parent 4ef4d178b6
commit c3c2999381
2 changed files with 38 additions and 28 deletions

View File

@ -150,7 +150,7 @@ public class ControlFlowGraph implements Serializable {
} }
ControlFlowBlock mainBlock = getMainBlock(); ControlFlowBlock mainBlock = getMainBlock();
if(mainBlock != null) { if(mainBlock != null && !entryPointBlocks.contains(mainBlock)) {
entryPointBlocks.add(mainBlock); entryPointBlocks.add(mainBlock);
} }
entryPointBlocks.add(getFirstBlock()); entryPointBlocks.add(getFirstBlock());

View File

@ -1,14 +1,16 @@
package dk.camelot64.kickc.passes.calcs; package dk.camelot64.kickc.passes.calcs;
import dk.camelot64.kickc.model.ControlFlowBlock; import dk.camelot64.kickc.model.InternalError;
import dk.camelot64.kickc.model.DominatorsBlock; import dk.camelot64.kickc.model.*;
import dk.camelot64.kickc.model.DominatorsGraph; import dk.camelot64.kickc.model.symbols.Procedure;
import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.symbols.Scope;
import dk.camelot64.kickc.model.values.LabelRef; 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.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
/** Finds the dominators for the control flow graph. */ /** Finds the dominators for the control flow graph. */
public class PassNCalcDominators extends PassNCalcBase<DominatorsGraph> { public class PassNCalcDominators extends PassNCalcBase<DominatorsGraph> {
@ -29,41 +31,51 @@ public class PassNCalcDominators extends PassNCalcBase<DominatorsGraph> {
public DominatorsGraph calculate() { public DominatorsGraph calculate() {
DominatorsGraph dominatorsGraph = new DominatorsGraph(); DominatorsGraph dominatorsGraph = new DominatorsGraph();
Collection<Procedure> 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} // Initialize dominators: Dom[first]={first}, Dom[block]={all}
List<LabelRef> firstBlocks = new ArrayList<>(); List<LabelRef> firstBlocks = new ArrayList<>();
List<ControlFlowBlock> entryPointBlocks = getGraph().getEntryPointBlocks(getProgram()); LabelRef firstBlock;
for(ControlFlowBlock entryPointBlock : entryPointBlocks) { if(scope instanceof Procedure) {
LabelRef firstBlock = entryPointBlock.getLabel(); firstBlock = ((Procedure)scope).getRef().getLabelRef();
// Skip main-block, as it will be called by @begin anyways } else if(scope.getRef().equals(ScopeRef.ROOT)) {
if(firstBlock.getFullName().equals(SymbolRef.MAIN_PROC_NAME)) continue; firstBlock = new LabelRef(LabelRef.BEGIN_BLOCK_NAME);
DominatorsBlock firstDominators = dominatorsGraph.addDominators(firstBlock); } else {
firstDominators.add(firstBlock); throw new InternalError("Scope type not handled! "+scope);
firstBlocks.add(firstBlock);
} }
DominatorsBlock firstDominators = dominatorsGraph.addDominators(firstBlock);
firstDominators.add(firstBlock);
firstBlocks.add(firstBlock);
List<LabelRef> allBlocks = new ArrayList<>(); List<LabelRef> procedureBlocks = getGraph().getScopeBlocks(scope.getRef()).stream().map(ControlFlowBlock::getLabel).collect(Collectors.toList());
for(ControlFlowBlock block : getGraph().getAllBlocks()) { for(LabelRef procedureBlock : procedureBlocks) {
allBlocks.add(block.getLabel()); if(!firstBlocks.contains(procedureBlock)) {
} DominatorsBlock dominatorsBlock = dominatorsGraph.addDominators(procedureBlock);
for(ControlFlowBlock block : getGraph().getAllBlocks()) { dominatorsBlock.addAll(procedureBlocks);
if(!firstBlocks.contains(block.getLabel())) {
DominatorsBlock dominatorsBlock = dominatorsGraph.addDominators(block.getLabel());
dominatorsBlock.addAll(allBlocks);
} }
} }
// Iteratively refine dominators until they do not change // Iteratively refine dominators until they do not change
// For all nodes: // For all nodes:
// Dom[n] = {n} UNION ( INTERSECT Dom[p] for all p that are predecessors of n) // Dom[n] = {n} UNION ( INTERSECT Dom[p] for all p that are predecessors of n)
boolean change = false; boolean change;
do { do {
change = false; change = false;
for(ControlFlowBlock block : getGraph().getAllBlocks()) { for(LabelRef procedureBlock : procedureBlocks) {
if(!firstBlocks.contains(block.getLabel())) { if(!firstBlocks.contains(procedureBlock)) {
ControlFlowBlock block = getGraph().getBlock(procedureBlock);
List<ControlFlowBlock> predecessors = getGraph().getPredecessors(block); List<ControlFlowBlock> predecessors = getGraph().getPredecessors(block);
DominatorsBlock newDominators = new DominatorsBlock(); DominatorsBlock newDominators = new DominatorsBlock();
newDominators.addAll(allBlocks); newDominators.addAll(procedureBlocks);
for(ControlFlowBlock predecessor : predecessors) { for(ControlFlowBlock predecessor : predecessors) {
DominatorsBlock predecessorDominators = dominatorsGraph.getDominators(predecessor.getLabel()); DominatorsBlock predecessorDominators = dominatorsGraph.getDominators(predecessor.getLabel());
newDominators.intersect(predecessorDominators); newDominators.intersect(predecessorDominators);
@ -76,9 +88,7 @@ public class PassNCalcDominators extends PassNCalcBase<DominatorsGraph> {
} }
} }
} }
} while(change); } while(change);
return dominatorsGraph;
} }