1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-09-08 17:54:40 +00:00

Refactored control flow graph dominators to be calculated on demand.

This commit is contained in:
jespergravgaard 2019-08-02 00:32:53 +02:00
parent 693a0bdbed
commit 1e03067814
8 changed files with 41 additions and 48 deletions

View File

@ -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());
}

View File

@ -208,7 +208,7 @@ public class KickC implements Callable<Void> {
}
if(optimizeZeroPageCoalesce) {
compiler.setEnableZeroPageCoalasce(true);
compiler.enableZeroPageCoalasce();
}
System.out.println("Compiling " + kcFile);

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -0,0 +1,8 @@
package dk.camelot64.kickc.passes;
/**
* Base interface for passes bawed on steps
*/
public interface PassStep {
boolean step();
}