mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-11-24 14:31:15 +00:00
Refactored call-graph to be calculated on demand.
This commit is contained in:
parent
bc1dd78bd8
commit
1f39ab8c37
@ -200,7 +200,7 @@ public class Compiler {
|
|||||||
}
|
}
|
||||||
new Pass1ProcedureInline(program).execute();
|
new Pass1ProcedureInline(program).execute();
|
||||||
new PassNStatementIndices(program).step();
|
new PassNStatementIndices(program).step();
|
||||||
new PassNCallGraphAnalysis(program).step();
|
program.clearCallGraph();
|
||||||
new Pass1AssertNoRecursion(program).execute();
|
new Pass1AssertNoRecursion(program).execute();
|
||||||
new Pass1AssertInterrupts(program).execute();
|
new Pass1AssertInterrupts(program).execute();
|
||||||
|
|
||||||
@ -422,7 +422,7 @@ public class Compiler {
|
|||||||
new PassNStatementIndices(program).execute();
|
new PassNStatementIndices(program).execute();
|
||||||
|
|
||||||
getLog().append("CALL GRAPH");
|
getLog().append("CALL GRAPH");
|
||||||
new PassNCallGraphAnalysis(program).step();
|
program.clearCallGraph();
|
||||||
getLog().append(program.getCallGraph().toString());
|
getLog().append(program.getCallGraph().toString());
|
||||||
|
|
||||||
//getLog().setVerboseLiveRanges(true);
|
//getLog().setVerboseLiveRanges(true);
|
||||||
@ -443,7 +443,7 @@ public class Compiler {
|
|||||||
new PassNBlockSequencePlanner(program).step();
|
new PassNBlockSequencePlanner(program).step();
|
||||||
new Pass3AddNopBeforeCallOns(program).generate();
|
new Pass3AddNopBeforeCallOns(program).generate();
|
||||||
new PassNStatementIndices(program).execute();
|
new PassNStatementIndices(program).execute();
|
||||||
new PassNCallGraphAnalysis(program).step();
|
program.clearCallGraph();
|
||||||
new PassNStatementInfos(program).execute();
|
new PassNStatementInfos(program).execute();
|
||||||
new PassNVariableReferenceInfos(program).execute();
|
new PassNVariableReferenceInfos(program).execute();
|
||||||
new Pass3SymbolInfos(program).generateSymbolInfos();
|
new Pass3SymbolInfos(program).generateSymbolInfos();
|
||||||
|
@ -3,13 +3,13 @@ package dk.camelot64.kickc.model;
|
|||||||
import dk.camelot64.kickc.model.statements.StatementCall;
|
import dk.camelot64.kickc.model.statements.StatementCall;
|
||||||
import dk.camelot64.kickc.model.values.ProcedureRef;
|
import dk.camelot64.kickc.model.values.ProcedureRef;
|
||||||
import dk.camelot64.kickc.model.values.ScopeRef;
|
import dk.camelot64.kickc.model.values.ScopeRef;
|
||||||
import dk.camelot64.kickc.passes.PassNCallGraphAnalysis;
|
import dk.camelot64.kickc.passes.PassNCalcCallGraph;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The call graph for the entire control flow graph.
|
* The call graph for the entire control flow graph.
|
||||||
* Created by {@link PassNCallGraphAnalysis}
|
* Created by {@link PassNCalcCallGraph}
|
||||||
*/
|
*/
|
||||||
public class CallGraph {
|
public class CallGraph {
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import dk.camelot64.kickc.model.statements.StatementInfos;
|
|||||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||||
import dk.camelot64.kickc.model.values.LabelRef;
|
import dk.camelot64.kickc.model.values.LabelRef;
|
||||||
import dk.camelot64.kickc.model.values.VariableRef;
|
import dk.camelot64.kickc.model.values.VariableRef;
|
||||||
|
import dk.camelot64.kickc.passes.PassNCalcCallGraph;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -123,7 +124,7 @@ public class Program {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Save a snapshot of the dynamic parts of the program. */
|
/** Save a snapshot of the dynamic parts of the program. */
|
||||||
public void saveSnapshot() {
|
public void snapshotCreate() {
|
||||||
if(this.snapshot != null)
|
if(this.snapshot != null)
|
||||||
throw new InternalError("Snapshot already saved!");
|
throw new InternalError("Snapshot already saved!");
|
||||||
if(this.liveRangeEquivalenceClassSet != null)
|
if(this.liveRangeEquivalenceClassSet != null)
|
||||||
@ -132,7 +133,7 @@ public class Program {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Restore the snapshot of the dynamic parts of the program. Clear all cached data and the snapshot. */
|
/** Restore the snapshot of the dynamic parts of the program. Clear all cached data and the snapshot. */
|
||||||
public void restoreSnapshot() {
|
public void snapshotRestore() {
|
||||||
this.scope = snapshot.getScope();
|
this.scope = snapshot.getScope();
|
||||||
this.graph = snapshot.getGraph();
|
this.graph = snapshot.getGraph();
|
||||||
this.snapshot = null;
|
this.snapshot = null;
|
||||||
@ -239,12 +240,21 @@ public class Program {
|
|||||||
this.asm = asm;
|
this.asm = asm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the call-graph for the program. Calculates the call-graph if it has not already been calculated.
|
||||||
|
* @return The call-graph
|
||||||
|
*/
|
||||||
public CallGraph getCallGraph() {
|
public CallGraph getCallGraph() {
|
||||||
|
if(callGraph == null)
|
||||||
|
this.callGraph = new PassNCalcCallGraph(this).calculate();
|
||||||
return callGraph;
|
return callGraph;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCallGraph(CallGraph callGraph) {
|
/**
|
||||||
this.callGraph = callGraph;
|
* Clears the call-graph ensuring it will be re-calculated if used.
|
||||||
|
*/
|
||||||
|
public void clearCallGraph() {
|
||||||
|
this.callGraph = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DominatorsGraph getDominators() {
|
public DominatorsGraph getDominators() {
|
||||||
@ -354,6 +364,7 @@ public class Program {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a bunch of reserved zero-page addresses that the compiler is not allowed to use.
|
* Adds a bunch of reserved zero-page addresses that the compiler is not allowed to use.
|
||||||
|
*
|
||||||
* @param reservedZp addresses to reserve
|
* @param reservedZp addresses to reserve
|
||||||
*/
|
*/
|
||||||
public void addReservedZps(List<Number> reservedZp) {
|
public void addReservedZps(List<Number> reservedZp) {
|
||||||
@ -370,6 +381,7 @@ public class Program {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the absolute position of the program code
|
* Set the absolute position of the program code
|
||||||
|
*
|
||||||
* @param programPc The address
|
* @param programPc The address
|
||||||
*/
|
*/
|
||||||
public void setProgramPc(Number programPc) {
|
public void setProgramPc(Number programPc) {
|
||||||
|
@ -97,7 +97,7 @@ public class Pass3LoopDepthAnalysis extends Pass2Base {
|
|||||||
for(NaturalLoop loop : loopSet.getLoops()) {
|
for(NaturalLoop loop : loopSet.getLoops()) {
|
||||||
LabelRef loopHead = loop.getHead();
|
LabelRef loopHead = loop.getHead();
|
||||||
ControlFlowBlock loopHeadBlock = getGraph().getBlock(loopHead);
|
ControlFlowBlock loopHeadBlock = getGraph().getBlock(loopHead);
|
||||||
ScopeRef scopeRef = PassNCallGraphAnalysis.getScopeRef(loopHeadBlock, getProgram());
|
ScopeRef scopeRef = PassNCalcCallGraph.getScopeRef(loopHeadBlock, getProgram());
|
||||||
if(scopeRef.equals(currentScope)) {
|
if(scopeRef.equals(currentScope)) {
|
||||||
// Loop is inside current scope block!
|
// Loop is inside current scope block!
|
||||||
currentScopeLoops.add(loop);
|
currentScopeLoops.add(loop);
|
||||||
|
38
src/main/java/dk/camelot64/kickc/passes/PassNCalcBase.java
Normal file
38
src/main/java/dk/camelot64/kickc/passes/PassNCalcBase.java
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package dk.camelot64.kickc.passes;
|
||||||
|
|
||||||
|
import dk.camelot64.kickc.CompileLog;
|
||||||
|
import dk.camelot64.kickc.model.ControlFlowGraph;
|
||||||
|
import dk.camelot64.kickc.model.Program;
|
||||||
|
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pass N Calculation base class
|
||||||
|
*/
|
||||||
|
public abstract class PassNCalcBase<Data> {
|
||||||
|
|
||||||
|
private Program program;
|
||||||
|
|
||||||
|
public PassNCalcBase(Program program) {
|
||||||
|
this.program = program;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract Data calculate();
|
||||||
|
|
||||||
|
public Program getProgram() {
|
||||||
|
return program;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProgramScope getScope() {
|
||||||
|
return program.getScope();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompileLog getLog() {
|
||||||
|
return program.getLog();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ControlFlowGraph getGraph() {
|
||||||
|
return program.getGraph();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -12,15 +12,13 @@ import dk.camelot64.kickc.model.values.ProcedureRef;
|
|||||||
import dk.camelot64.kickc.model.values.ScopeRef;
|
import dk.camelot64.kickc.model.values.ScopeRef;
|
||||||
|
|
||||||
/** Finds the call graph for the control flow graph - identifies all calls in all scopes and creates a graph from these. */
|
/** Finds the call graph for the control flow graph - identifies all calls in all scopes and creates a graph from these. */
|
||||||
public class PassNCallGraphAnalysis extends Pass2SsaOptimization {
|
public class PassNCalcCallGraph extends PassNCalcBase<CallGraph> {
|
||||||
|
|
||||||
|
public PassNCalcCallGraph(Program program) {
|
||||||
public PassNCallGraphAnalysis(Program program) {
|
|
||||||
super(program);
|
super(program);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public CallGraph calculate() {
|
||||||
public boolean step() {
|
|
||||||
CallGraph callGraph = new CallGraph();
|
CallGraph callGraph = new CallGraph();
|
||||||
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
|
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
|
||||||
ScopeRef scopeRef = getScopeRef(block, getProgram());
|
ScopeRef scopeRef = getScopeRef(block, getProgram());
|
||||||
@ -32,8 +30,7 @@ public class PassNCallGraphAnalysis extends Pass2SsaOptimization {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getProgram().setCallGraph(callGraph);
|
return callGraph;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
Loading…
Reference in New Issue
Block a user