From 1e03067814585cb5ff36483867dfacf9f78665c4 Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Fri, 2 Aug 2019 00:32:53 +0200 Subject: [PATCH] Refactored control flow graph dominators to be calculated on demand. --- .../java/dk/camelot64/kickc/Compiler.java | 34 +++++++++---------- src/main/java/dk/camelot64/kickc/KickC.java | 2 +- .../dk/camelot64/kickc/model/Program.java | 9 ++--- .../dk/camelot64/kickc/passes/Pass1Base.java | 2 +- .../kickc/passes/Pass2SsaOptimization.java | 2 +- .../kickc/passes/PassNDominatorsAnalysis.java | 13 ++++--- .../PassNVariableReferenceInfosClear.java | 19 ----------- .../dk/camelot64/kickc/passes/PassStep.java | 8 +++++ 8 files changed, 41 insertions(+), 48 deletions(-) delete mode 100644 src/main/java/dk/camelot64/kickc/passes/PassNVariableReferenceInfosClear.java create mode 100644 src/main/java/dk/camelot64/kickc/passes/PassStep.java diff --git a/src/main/java/dk/camelot64/kickc/Compiler.java b/src/main/java/dk/camelot64/kickc/Compiler.java index 94dc7a4ec..7c0e6b0ca 100644 --- a/src/main/java/dk/camelot64/kickc/Compiler.java +++ b/src/main/java/dk/camelot64/kickc/Compiler.java @@ -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 getPass2Optimizations() { - List optimizations = new ArrayList<>(); + private List getPass2Optimizations() { + List 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 optimizations = getPass2Optimizations(); + List optimizations = getPass2Optimizations(); pass2Execute(optimizations); } private void pass2UnrollLoops() { - List loopUnrolling = new ArrayList<>(); + List 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 constantOptimizations = new ArrayList<>(); + List 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 optimizations) { + private void pass2Execute(List 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 optimizations) { + private boolean pass2ExecuteOnce(List 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()); } diff --git a/src/main/java/dk/camelot64/kickc/KickC.java b/src/main/java/dk/camelot64/kickc/KickC.java index 6e8b212fd..7d8bddc0c 100644 --- a/src/main/java/dk/camelot64/kickc/KickC.java +++ b/src/main/java/dk/camelot64/kickc/KickC.java @@ -208,7 +208,7 @@ public class KickC implements Callable { } if(optimizeZeroPageCoalesce) { - compiler.setEnableZeroPageCoalasce(true); + compiler.enableZeroPageCoalasce(); } System.out.println("Compiling " + kcFile); diff --git a/src/main/java/dk/camelot64/kickc/model/Program.java b/src/main/java/dk/camelot64/kickc/model/Program.java index 10c3bc35f..6bdc9a4a2 100644 --- a/src/main/java/dk/camelot64/kickc/model/Program.java +++ b/src/main/java/dk/camelot64/kickc/model/Program.java @@ -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; } - } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1Base.java b/src/main/java/dk/camelot64/kickc/passes/Pass1Base.java index d3c0abeb2..123cc5611 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass1Base.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass1Base.java @@ -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; diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2SsaOptimization.java b/src/main/java/dk/camelot64/kickc/passes/Pass2SsaOptimization.java index ded52c7c3..9a10854ba 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2SsaOptimization.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2SsaOptimization.java @@ -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); diff --git a/src/main/java/dk/camelot64/kickc/passes/PassNDominatorsAnalysis.java b/src/main/java/dk/camelot64/kickc/passes/PassNDominatorsAnalysis.java index 494376d2e..171b36fac 100644 --- a/src/main/java/dk/camelot64/kickc/passes/PassNDominatorsAnalysis.java +++ b/src/main/java/dk/camelot64/kickc/passes/PassNDominatorsAnalysis.java @@ -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 { public PassNDominatorsAnalysis(Program program) { super(program); } + /** * Analyse the control flow graph to find dominators for all blocks. *

@@ -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; } diff --git a/src/main/java/dk/camelot64/kickc/passes/PassNVariableReferenceInfosClear.java b/src/main/java/dk/camelot64/kickc/passes/PassNVariableReferenceInfosClear.java deleted file mode 100644 index 8a0417db3..000000000 --- a/src/main/java/dk/camelot64/kickc/passes/PassNVariableReferenceInfosClear.java +++ /dev/null @@ -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; - } -} diff --git a/src/main/java/dk/camelot64/kickc/passes/PassStep.java b/src/main/java/dk/camelot64/kickc/passes/PassStep.java new file mode 100644 index 000000000..4686a591f --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/passes/PassStep.java @@ -0,0 +1,8 @@ +package dk.camelot64.kickc.passes; + +/** + * Base interface for passes bawed on steps + */ +public interface PassStep { + boolean step(); +}