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:
parent
4ef4d178b6
commit
c3c2999381
@ -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());
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user