mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-01-04 18:31:55 +00:00
Refactored control flow graph dominators to be calculated on demand.
This commit is contained in:
parent
693a0bdbed
commit
1e03067814
@ -38,8 +38,8 @@ public class Compiler {
|
||||
this.upliftCombinations = upliftCombinations;
|
||||
}
|
||||
|
||||
void setEnableZeroPageCoalasce(boolean optimizeZeroPageCoalesce) {
|
||||
this.enableZeroPageCoalasce = optimizeZeroPageCoalesce;
|
||||
void enableZeroPageCoalasce() {
|
||||
this.enableZeroPageCoalasce = true;
|
||||
}
|
||||
|
||||
void setTargetPlatform(TargetPlatform targetPlatform) {
|
||||
@ -263,8 +263,8 @@ public class Compiler {
|
||||
}
|
||||
}
|
||||
|
||||
private List<Pass2SsaOptimization> getPass2Optimizations() {
|
||||
List<Pass2SsaOptimization> optimizations = new ArrayList<>();
|
||||
private List<PassStep> getPass2Optimizations() {
|
||||
List<PassStep> optimizations = new ArrayList<>();
|
||||
optimizations.add(new Pass2FixInlineConstructors(program));
|
||||
optimizations.add(new PassNAddNumberTypeConversions(program));
|
||||
optimizations.add(new PassNAddInitializerValueListTypeCasts(program));
|
||||
@ -276,7 +276,7 @@ public class Compiler {
|
||||
optimizations.add(new PassNTypeIdSimplification(program));
|
||||
optimizations.add(new PassNSizeOfSimplification(program));
|
||||
optimizations.add(new PassNStatementIndices(program));
|
||||
optimizations.add(new PassNVariableReferenceInfosClear(program));
|
||||
optimizations.add(() -> { program.clearVariableReferenceInfos(); return false; });
|
||||
optimizations.add(new Pass2UnaryNotSimplification(program));
|
||||
optimizations.add(new Pass2AliasElimination(program));
|
||||
optimizations.add(new Pass2IdenticalPhiElimination(program));
|
||||
@ -307,16 +307,16 @@ public class Compiler {
|
||||
}
|
||||
|
||||
private void pass2Optimize() {
|
||||
List<Pass2SsaOptimization> optimizations = getPass2Optimizations();
|
||||
List<PassStep> optimizations = getPass2Optimizations();
|
||||
pass2Execute(optimizations);
|
||||
}
|
||||
|
||||
private void pass2UnrollLoops() {
|
||||
List<Pass2SsaOptimization> loopUnrolling = new ArrayList<>();
|
||||
List<PassStep> loopUnrolling = new ArrayList<>();
|
||||
loopUnrolling.add(new PassNStatementIndices(program));
|
||||
loopUnrolling.add(new PassNVariableReferenceInfosClear(program));
|
||||
loopUnrolling.add(() -> { program.clearVariableReferenceInfos(); return false; });
|
||||
loopUnrolling.add(new PassNStatementInfos(program));
|
||||
loopUnrolling.add(new PassNDominatorsAnalysis(program));
|
||||
loopUnrolling.add(() -> { program.clearDominators(); return false; });
|
||||
loopUnrolling.add(new PassNLoopAnalysis(program));
|
||||
loopUnrolling.add(new Pass2LoopUnrollPhiPrepare(program));
|
||||
loopUnrolling.add(new Pass2LoopUnroll(program));
|
||||
@ -339,9 +339,9 @@ public class Compiler {
|
||||
|
||||
private void pass2InlineConstants() {
|
||||
// Constant inlining optimizations - as the last step to ensure that constant identification has been completed
|
||||
List<Pass2SsaOptimization> constantOptimizations = new ArrayList<>();
|
||||
List<PassStep> constantOptimizations = new ArrayList<>();
|
||||
constantOptimizations.add(new PassNStatementIndices(program));
|
||||
constantOptimizations.add(new PassNVariableReferenceInfosClear(program));
|
||||
constantOptimizations.add(() -> { program.clearVariableReferenceInfos(); return false; });
|
||||
constantOptimizations.add(new Pass2NopCastInlining(program));
|
||||
constantOptimizations.add(new Pass2MultiplyToShiftRewriting(program));
|
||||
constantOptimizations.add(new Pass2ConstantInlining(program));
|
||||
@ -357,12 +357,12 @@ public class Compiler {
|
||||
*
|
||||
* @param optimizations The optimizations to repeat
|
||||
*/
|
||||
private void pass2Execute(List<Pass2SsaOptimization> optimizations) {
|
||||
private void pass2Execute(List<PassStep> optimizations) {
|
||||
boolean ssaOptimized = true;
|
||||
while(ssaOptimized) {
|
||||
pass2AssertSSA();
|
||||
ssaOptimized = false;
|
||||
for(Pass2SsaOptimization optimization : optimizations) {
|
||||
for(PassStep optimization : optimizations) {
|
||||
boolean stepOptimized = true;
|
||||
while(stepOptimized) {
|
||||
stepOptimized = optimization.step();
|
||||
@ -378,9 +378,9 @@ public class Compiler {
|
||||
* @param optimizations The optimizations
|
||||
* @return true if any step performed an optimization
|
||||
*/
|
||||
private boolean pass2ExecuteOnce(List<Pass2SsaOptimization> optimizations) {
|
||||
private boolean pass2ExecuteOnce(List<PassStep> optimizations) {
|
||||
boolean ssaOptimized = false;
|
||||
for(Pass2SsaOptimization optimization : optimizations) {
|
||||
for(PassStep optimization : optimizations) {
|
||||
pass2AssertSSA();
|
||||
boolean stepOptimized = optimization.step();
|
||||
ssaOptimized = pass2LogOptimization(ssaOptimized, optimization, stepOptimized);
|
||||
@ -388,7 +388,7 @@ public class Compiler {
|
||||
return ssaOptimized;
|
||||
}
|
||||
|
||||
private boolean pass2LogOptimization(boolean ssaOptimized, Pass2SsaOptimization optimization, boolean stepOptimized) {
|
||||
private boolean pass2LogOptimization(boolean ssaOptimized, PassStep optimization, boolean stepOptimized) {
|
||||
if(stepOptimized) {
|
||||
getLog().append("Successful SSA optimization " + optimization.getClass().getSimpleName() + "");
|
||||
ssaOptimized = true;
|
||||
@ -456,7 +456,7 @@ public class Compiler {
|
||||
if(getLog().isVerboseLoopAnalysis()) {
|
||||
getLog().append("DOMINATORS");
|
||||
}
|
||||
new PassNDominatorsAnalysis(program).step();
|
||||
program.clearDominators();
|
||||
if(getLog().isVerboseLoopAnalysis()) {
|
||||
getLog().append(program.getDominators().toString());
|
||||
}
|
||||
|
@ -208,7 +208,7 @@ public class KickC implements Callable<Void> {
|
||||
}
|
||||
|
||||
if(optimizeZeroPageCoalesce) {
|
||||
compiler.setEnableZeroPageCoalasce(true);
|
||||
compiler.enableZeroPageCoalasce();
|
||||
}
|
||||
|
||||
System.out.println("Compiling " + kcFile);
|
||||
|
@ -8,6 +8,7 @@ import dk.camelot64.kickc.model.values.LabelRef;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
import dk.camelot64.kickc.passes.PassNCalcCallGraph;
|
||||
import dk.camelot64.kickc.passes.PassNCalcVariableReferenceInfos;
|
||||
import dk.camelot64.kickc.passes.PassNDominatorsAnalysis;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
@ -268,13 +269,14 @@ public class Program {
|
||||
this.variableReferenceInfos = null;
|
||||
}
|
||||
|
||||
|
||||
public DominatorsGraph getDominators() {
|
||||
if(dominators==null)
|
||||
this.dominators = new PassNDominatorsAnalysis(this).calculate();
|
||||
return dominators;
|
||||
}
|
||||
|
||||
public void setDominators(DominatorsGraph dominators) {
|
||||
this.dominators = dominators;
|
||||
public void clearDominators() {
|
||||
this.dominators = null;
|
||||
}
|
||||
|
||||
public NaturalLoopSet getLoopSet() {
|
||||
@ -405,5 +407,4 @@ public class Program {
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||
/**
|
||||
* Pass 1 (before SSA optimizations) base class
|
||||
*/
|
||||
public abstract class Pass1Base {
|
||||
public abstract class Pass1Base implements PassStep {
|
||||
|
||||
private Program program;
|
||||
|
||||
|
@ -13,7 +13,7 @@ import java.util.*;
|
||||
* Optimization on Single Static Assignment form (Control Flow Graph) performed during Compiler Pass 2.
|
||||
* Optimizations are performed repeatedly until none of them yield any result
|
||||
*/
|
||||
public abstract class Pass2SsaOptimization extends Pass1Base {
|
||||
public abstract class Pass2SsaOptimization extends Pass1Base implements PassStep {
|
||||
|
||||
public Pass2SsaOptimization(Program program) {
|
||||
super(program);
|
||||
|
@ -1,6 +1,9 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.*;
|
||||
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.values.LabelRef;
|
||||
import dk.camelot64.kickc.model.values.SymbolRef;
|
||||
|
||||
@ -8,12 +11,13 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/** Finds the dominators for the control flow graph. */
|
||||
public class PassNDominatorsAnalysis extends Pass2SsaOptimization {
|
||||
public class PassNDominatorsAnalysis extends PassNCalcBase<DominatorsGraph> {
|
||||
|
||||
public PassNDominatorsAnalysis(Program program) {
|
||||
super(program);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Analyse the control flow graph to find dominators for all blocks.
|
||||
* <p>
|
||||
@ -22,7 +26,7 @@ public class PassNDominatorsAnalysis extends Pass2SsaOptimization {
|
||||
* See http://www.cs.colostate.edu/~cs553/ClassNotes/lecture09-control-dominators.ppt.pdf
|
||||
*/
|
||||
@Override
|
||||
public boolean step() {
|
||||
public DominatorsGraph calculate() {
|
||||
DominatorsGraph dominatorsGraph = new DominatorsGraph();
|
||||
|
||||
// Initialize dominators: Dom[first]={first}, Dom[block]={all}
|
||||
@ -74,8 +78,7 @@ public class PassNDominatorsAnalysis extends Pass2SsaOptimization {
|
||||
}
|
||||
|
||||
} while(change);
|
||||
getProgram().setDominators(dominatorsGraph);
|
||||
return false;
|
||||
return dominatorsGraph;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,19 +0,0 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
|
||||
/**
|
||||
* Clear the cached variable reference infos.
|
||||
*/
|
||||
public class PassNVariableReferenceInfosClear extends Pass2SsaOptimization {
|
||||
|
||||
public PassNVariableReferenceInfosClear(Program program) {
|
||||
super(program);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean step() {
|
||||
getProgram().clearVariableReferenceInfos();
|
||||
return false;
|
||||
}
|
||||
}
|
8
src/main/java/dk/camelot64/kickc/passes/PassStep.java
Normal file
8
src/main/java/dk/camelot64/kickc/passes/PassStep.java
Normal file
@ -0,0 +1,8 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
/**
|
||||
* Base interface for passes bawed on steps
|
||||
*/
|
||||
public interface PassStep {
|
||||
boolean step();
|
||||
}
|
Loading…
Reference in New Issue
Block a user