From aceea6d8ecc6d2ed44ad44f94cbe0b3fd87e8bc7 Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Fri, 2 Aug 2019 01:25:32 +0200 Subject: [PATCH] Refactored more program data to be calculated on demand. --- .../java/dk/camelot64/kickc/Compiler.java | 18 ++-- .../kickc/model/LiveRangeVariables.java | 4 +- .../model/LiveRangeVariablesEffective.java | 3 +- .../camelot64/kickc/model/NaturalLoopSet.java | 4 +- .../dk/camelot64/kickc/model/Program.java | 95 ++++++++++--------- .../kickc/model/symbols/ProgramScope.java | 2 +- .../camelot64/kickc/model/symbols/Scope.java | 2 +- ....java => PassNCalcLiveRangeVariables.java} | 8 +- ...java => PassNCalcLiveRangesEffective.java} | 19 ++-- ...oopAnalysis.java => PassNCalcLoopSet.java} | 10 +- ...va => PassNCalcRegisterUpliftProgram.java} | 18 ++-- ...nfos.java => PassNCalcStatementInfos.java} | 9 +- ...a => PassNCalcVariableRegisterWeight.java} | 52 +++++----- 13 files changed, 120 insertions(+), 124 deletions(-) rename src/main/java/dk/camelot64/kickc/passes/{Pass3LiveRangesAnalysis.java => PassNCalcLiveRangeVariables.java} (98%) rename src/main/java/dk/camelot64/kickc/passes/{Pass3LiveRangesEffectiveAnalysis.java => PassNCalcLiveRangesEffective.java} (96%) rename src/main/java/dk/camelot64/kickc/passes/{PassNLoopAnalysis.java => PassNCalcLoopSet.java} (95%) rename src/main/java/dk/camelot64/kickc/passes/{Pass4RegisterUpliftScopeAnalysis.java => PassNCalcRegisterUpliftProgram.java} (88%) rename src/main/java/dk/camelot64/kickc/passes/{PassNStatementInfos.java => PassNCalcStatementInfos.java} (77%) rename src/main/java/dk/camelot64/kickc/passes/{Pass3VariableRegisterWeightAnalysis.java => PassNCalcVariableRegisterWeight.java} (63%) diff --git a/src/main/java/dk/camelot64/kickc/Compiler.java b/src/main/java/dk/camelot64/kickc/Compiler.java index 2e89fafe3..6e7110a4a 100644 --- a/src/main/java/dk/camelot64/kickc/Compiler.java +++ b/src/main/java/dk/camelot64/kickc/Compiler.java @@ -315,9 +315,9 @@ public class Compiler { List loopUnrolling = new ArrayList<>(); loopUnrolling.add(new PassNStatementIndices(program)); loopUnrolling.add(() -> { program.clearVariableReferenceInfos(); return false; }); - loopUnrolling.add(new PassNStatementInfos(program)); + loopUnrolling.add(() -> { program.clearStatementInfos(); return false; }); loopUnrolling.add(() -> { program.clearDominators(); return false; }); - loopUnrolling.add(new PassNLoopAnalysis(program)); + loopUnrolling.add(() -> { program.clearLoopSet(); return false; }); loopUnrolling.add(new Pass2LoopUnrollPhiPrepare(program)); loopUnrolling.add(new Pass2LoopUnroll(program)); @@ -422,9 +422,8 @@ public class Compiler { //getLog().setVerboseLiveRanges(true); - new PassNStatementInfos(program).execute(); + program.clearStatementInfos(); program.clearVariableReferenceInfos(); - new Pass3LiveRangesAnalysis(program).findLiveRanges(); //getLog().append("CONTROL FLOW GRAPH - LIVE RANGES FOUND"); //getLog().append(program.getGraph().toString(program)); pass2AssertSSA(); @@ -439,10 +438,10 @@ public class Compiler { new Pass3AddNopBeforeCallOns(program).generate(); new PassNStatementIndices(program).execute(); program.clearCallGraph(); - new PassNStatementInfos(program).execute(); + program.clearStatementInfos(); program.clearVariableReferenceInfos(); - new Pass3LiveRangesAnalysis(program).findLiveRanges(); - new Pass3LiveRangesEffectiveAnalysis(program).findLiveRangesEffective(); + program.clearLiveRangeVariables(); + program.clearLiveRangeVariablesEffective(); pass2AssertSSA(); getLog().append("\nFINAL CONTROL FLOW GRAPH"); @@ -463,7 +462,7 @@ public class Compiler { if(getLog().isVerboseLoopAnalysis()) { getLog().append("NATURAL LOOPS"); } - new PassNLoopAnalysis(program).step(); + program.clearLoopSet(); if(getLog().isVerboseLoopAnalysis()) { getLog().append(program.getLoopSet().toString()); } @@ -477,7 +476,7 @@ public class Compiler { } getLog().append("\nVARIABLE REGISTER WEIGHTS"); - new Pass3VariableRegisterWeightAnalysis(program).findWeights(); + program.getVariableRegisterWeights(); getLog().append(program.getScope().toString(program, Variable.class)); new Pass4LiveRangeEquivalenceClassesFinalize(program).allocate(); @@ -502,7 +501,6 @@ public class Compiler { // Find register uplift scopes getLog().append("REGISTER UPLIFT SCOPES"); - new Pass4RegisterUpliftScopeAnalysis(program).findScopes(); getLog().append(program.getRegisterUpliftProgram().toString((program.getVariableRegisterWeights()))); // Attempt uplifting registers through a lot of combinations diff --git a/src/main/java/dk/camelot64/kickc/model/LiveRangeVariables.java b/src/main/java/dk/camelot64/kickc/model/LiveRangeVariables.java index 03892225f..9b7a306e3 100644 --- a/src/main/java/dk/camelot64/kickc/model/LiveRangeVariables.java +++ b/src/main/java/dk/camelot64/kickc/model/LiveRangeVariables.java @@ -1,7 +1,7 @@ package dk.camelot64.kickc.model; import dk.camelot64.kickc.model.values.VariableRef; -import dk.camelot64.kickc.passes.Pass3LiveRangesAnalysis; +import dk.camelot64.kickc.passes.PassNCalcLiveRangeVariables; import java.util.ArrayList; import java.util.LinkedHashMap; @@ -10,7 +10,7 @@ import java.util.Map; /** * Live ranges for all variables. - * Created by {@link Pass3LiveRangesAnalysis} + * Created by {@link PassNCalcLiveRangeVariables} */ public class LiveRangeVariables { diff --git a/src/main/java/dk/camelot64/kickc/model/LiveRangeVariablesEffective.java b/src/main/java/dk/camelot64/kickc/model/LiveRangeVariablesEffective.java index f69a89384..13c55a983 100644 --- a/src/main/java/dk/camelot64/kickc/model/LiveRangeVariablesEffective.java +++ b/src/main/java/dk/camelot64/kickc/model/LiveRangeVariablesEffective.java @@ -8,13 +8,14 @@ import dk.camelot64.kickc.model.statements.Statement; import dk.camelot64.kickc.model.symbols.Procedure; import dk.camelot64.kickc.model.symbols.Scope; import dk.camelot64.kickc.passes.Pass2AliasElimination; +import dk.camelot64.kickc.passes.PassNCalcLiveRangesEffective; import java.util.*; /** * Effective variable live ranges for all statements. * (Including variables alive in calling methods). - * Created by {@link dk.camelot64.kickc.passes.Pass3LiveRangesEffectiveAnalysis} + * Created by {@link PassNCalcLiveRangesEffective} */ public class LiveRangeVariablesEffective { diff --git a/src/main/java/dk/camelot64/kickc/model/NaturalLoopSet.java b/src/main/java/dk/camelot64/kickc/model/NaturalLoopSet.java index be00f6b70..c4a72130c 100644 --- a/src/main/java/dk/camelot64/kickc/model/NaturalLoopSet.java +++ b/src/main/java/dk/camelot64/kickc/model/NaturalLoopSet.java @@ -1,14 +1,14 @@ package dk.camelot64.kickc.model; import dk.camelot64.kickc.model.values.LabelRef; -import dk.camelot64.kickc.passes.PassNLoopAnalysis; +import dk.camelot64.kickc.passes.PassNCalcLoopSet; import java.util.*; /** * A set of natural loops in a control flow graph. *

For definitions and more see http://www.cs.colostate.edu/~cs553/ClassNotes/lecture09-control-dominators.ppt.pdf - *

Created by {@link PassNLoopAnalysis} + *

Created by {@link PassNCalcLoopSet} */ public class NaturalLoopSet { diff --git a/src/main/java/dk/camelot64/kickc/model/Program.java b/src/main/java/dk/camelot64/kickc/model/Program.java index c5ea851f2..2c42a0071 100644 --- a/src/main/java/dk/camelot64/kickc/model/Program.java +++ b/src/main/java/dk/camelot64/kickc/model/Program.java @@ -51,6 +51,8 @@ public class Program { private ProgramScope scope; /** The control flow graph. PASS 1-5 (DYNAMIC) */ private ControlFlowGraph graph; + /** Registers potentially usable as allocation for each live range equivalence class. PASS 4 (DYNAMIC) */ + private RegisterPotentials registerPotentials; /** Live range equivalence classes containing variables that do not have overlapping live ranges. PASS 3-5 (DYNAMIC) */ private LiveRangeEquivalenceClassSet liveRangeEquivalenceClassSet; /** The 6502 ASM program. PASS 4-5 (DYNAMIC) */ @@ -67,22 +69,19 @@ public class Program { private DominatorsGraph dominators; /** Cached information about symbols. Contains a symbol table cache for fast access. PASS 3-4 (CACHED ON-DEMAND) */ private SymbolInfos symbolInfos; - /** Cached phi transitions into each block. PASS 4 (CACHED) */ + /** Cached phi transitions into each block. PASS 4 (CACHED ON-DEMAND) */ private Map phiTransitions; - /** The live ranges of all variables. PASS 3-4 (CACHED) */ + /** The live ranges of all variables. PASS 3-4 (CACHED ON-DEMAND) */ private LiveRangeVariables liveRangeVariables; - /** The effective live ranges of all variables. PASS 3-4 (CACHED) */ + /** The effective live ranges of all variables. PASS 3-4 (CACHED ON-DEMAND) */ private LiveRangeVariablesEffective liveRangeVariablesEffective; - /** Registers potentially usable as allocation for each live range equivalence class. PASS 4 (CACHED) */ - private RegisterPotentials registerPotentials; - /** Separation of live range equivalence classes into scopes - used for register uplift. PASS 4 (CACHED) */ + /** Separation of live range equivalence classes into scopes - used for register uplift. PASS 4 (CACHED ON-DEMAND) */ private RegisterUpliftProgram registerUpliftProgram; - - /** Cached information about which block is each statement a part of. PASS 2U-5 (CACHED) */ + /** Cached information about which block is each statement a part of. PASS 2U-5 (CACHED ON-DEMAND) */ private StatementInfos statementInfos; - /** Information about loops. PASS 2U-5 (CACHED) */ + /** Information about loops. PASS 2U-5 (CACHED ON-DEMAND) */ private NaturalLoopSet loopSet; - /** The register weight of all variables describing how much the variable would theoretically gain from being in a register. PASS 3-5 (CACHED) */ + /** The register weight of all variables describing how much the variable would theoretically gain from being in a register. PASS 3-5 (CACHED ON-DEMAND) */ private VariableRegisterWeights variableRegisterWeights; public Program() { @@ -279,22 +278,28 @@ public class Program { this.phiTransitions = null; } - - public NaturalLoopSet getLoopSet() { - return loopSet; + public LiveRangeVariables getLiveRangeVariables() { + if(liveRangeVariables==null) + this.liveRangeVariables = new PassNCalcLiveRangeVariables(this).calculate(); + return liveRangeVariables; } - public void setLoopSet(NaturalLoopSet loopSet) { - this.loopSet = loopSet; + public void setLiveRangeVariables(LiveRangeVariables liveRangeVariables) { + this.liveRangeVariables = liveRangeVariables; } + public void clearLiveRangeVariables() { + this.liveRangeVariables = null; + } public StatementInfos getStatementInfos() { + if(statementInfos==null) + this.statementInfos = new PassNCalcStatementInfos(this).calculate(); return statementInfos; } - public void setStatementInfos(StatementInfos statementInfos) { - this.statementInfos = statementInfos; + public void clearStatementInfos() { + this.statementInfos = null; } public SymbolInfos getSymbolInfos() { @@ -303,20 +308,40 @@ public class Program { return symbolInfos; } - public LiveRangeVariables getLiveRangeVariables() { - return liveRangeVariables; - } - - public void setLiveRangeVariables(LiveRangeVariables liveRangeVariables) { - this.liveRangeVariables = liveRangeVariables; - } - public LiveRangeVariablesEffective getLiveRangeVariablesEffective() { + if(liveRangeVariablesEffective==null) + this.liveRangeVariablesEffective = new PassNCalcLiveRangesEffective(this).calculate(); return liveRangeVariablesEffective; } - public void setLiveRangeVariablesEffective(LiveRangeVariablesEffective liveRangeVariablesEffective) { - this.liveRangeVariablesEffective = liveRangeVariablesEffective; + public void clearLiveRangeVariablesEffective() { + this.liveRangeVariablesEffective = null; + } + + public RegisterUpliftProgram getRegisterUpliftProgram() { + if(registerUpliftProgram==null) + this.registerUpliftProgram = new PassNCalcRegisterUpliftProgram(this).calculate(); + return registerUpliftProgram; + } + + public NaturalLoopSet getLoopSet() { + if(loopSet==null) + this.loopSet = new PassNCalcLoopSet(this).calculate(); + return loopSet; + } + + public void clearLoopSet() { + this.loopSet = null; + } + + public VariableRegisterWeights getVariableRegisterWeights() { + if(variableRegisterWeights==null) + this.variableRegisterWeights = new PassNCalcVariableRegisterWeight(this).calculate(); + return variableRegisterWeights; + } + + public VariableRegisterWeights getOrNullVariableRegisterWeights() { + return variableRegisterWeights; } public LiveRangeEquivalenceClassSet getLiveRangeEquivalenceClassSet() { @@ -327,14 +352,6 @@ public class Program { this.liveRangeEquivalenceClassSet = liveRangeEquivalenceClassSet; } - public VariableRegisterWeights getVariableRegisterWeights() { - return variableRegisterWeights; - } - - public void setVariableRegisterWeights(VariableRegisterWeights variableRegisterWeights) { - this.variableRegisterWeights = variableRegisterWeights; - } - public RegisterPotentials getRegisterPotentials() { return registerPotentials; } @@ -343,14 +360,6 @@ public class Program { this.registerPotentials = registerPotentials; } - public RegisterUpliftProgram getRegisterUpliftProgram() { - return registerUpliftProgram; - } - - public void setRegisterUpliftProgram(RegisterUpliftProgram registerUpliftProgram) { - this.registerUpliftProgram = registerUpliftProgram; - } - public Collection getEarlyIdentifiedConstants() { return earlyIdentifiedConstants; } diff --git a/src/main/java/dk/camelot64/kickc/model/symbols/ProgramScope.java b/src/main/java/dk/camelot64/kickc/model/symbols/ProgramScope.java index 7f6036f7c..96202d685 100644 --- a/src/main/java/dk/camelot64/kickc/model/symbols/ProgramScope.java +++ b/src/main/java/dk/camelot64/kickc/model/symbols/ProgramScope.java @@ -28,7 +28,7 @@ public class ProgramScope extends Scope { if(liveRangeEquivalenceClassSet != null) { out.append("\n"); for(LiveRangeEquivalenceClass liveRangeEquivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) { - out.append(liveRangeEquivalenceClass); + out.append(liveRangeEquivalenceClass.toString()); out.append("\n"); } } diff --git a/src/main/java/dk/camelot64/kickc/model/symbols/Scope.java b/src/main/java/dk/camelot64/kickc/model/symbols/Scope.java index f530db95f..fc26e38fd 100644 --- a/src/main/java/dk/camelot64/kickc/model/symbols/Scope.java +++ b/src/main/java/dk/camelot64/kickc/model/symbols/Scope.java @@ -324,7 +324,7 @@ public abstract class Scope implements Symbol { } public String toString(Program program, Class symbolClass) { - VariableRegisterWeights registerWeights = program.getVariableRegisterWeights(); + VariableRegisterWeights registerWeights = program.getOrNullVariableRegisterWeights(); StringBuilder res = new StringBuilder(); Set names = symbols.keySet(); List sortedNames = new ArrayList<>(names); diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass3LiveRangesAnalysis.java b/src/main/java/dk/camelot64/kickc/passes/PassNCalcLiveRangeVariables.java similarity index 98% rename from src/main/java/dk/camelot64/kickc/passes/Pass3LiveRangesAnalysis.java rename to src/main/java/dk/camelot64/kickc/passes/PassNCalcLiveRangeVariables.java index 9d2234f0b..29799abac 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass3LiveRangesAnalysis.java +++ b/src/main/java/dk/camelot64/kickc/passes/PassNCalcLiveRangeVariables.java @@ -18,13 +18,14 @@ import java.util.Arrays; import java.util.Collection; import java.util.List; -public class Pass3LiveRangesAnalysis extends Pass2Base { +public class PassNCalcLiveRangeVariables extends PassNCalcBase { - public Pass3LiveRangesAnalysis(Program program) { + public PassNCalcLiveRangeVariables(Program program) { super(program); } - public void findLiveRanges() { + @Override + public LiveRangeVariables calculate() { LiveRangeVariables liveRanges = new LiveRangeVariables(getProgram()); boolean propagating; do { @@ -36,6 +37,7 @@ public class Pass3LiveRangesAnalysis extends Pass2Base { getLog().append(getProgram().getGraph().toString(getProgram())); } } while(propagating); + return liveRanges; } /** diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass3LiveRangesEffectiveAnalysis.java b/src/main/java/dk/camelot64/kickc/passes/PassNCalcLiveRangesEffective.java similarity index 96% rename from src/main/java/dk/camelot64/kickc/passes/Pass3LiveRangesEffectiveAnalysis.java rename to src/main/java/dk/camelot64/kickc/passes/PassNCalcLiveRangesEffective.java index 04d82407a..53780bc4b 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass3LiveRangesEffectiveAnalysis.java +++ b/src/main/java/dk/camelot64/kickc/passes/PassNCalcLiveRangesEffective.java @@ -1,21 +1,24 @@ package dk.camelot64.kickc.passes; import dk.camelot64.kickc.model.*; -import dk.camelot64.kickc.model.values.*; import dk.camelot64.kickc.model.statements.Statement; import dk.camelot64.kickc.model.statements.StatementAssignment; -import dk.camelot64.kickc.model.statements.StatementCall; import dk.camelot64.kickc.model.statements.StatementPhiBlock; import dk.camelot64.kickc.model.symbols.Procedure; import dk.camelot64.kickc.model.symbols.Scope; import dk.camelot64.kickc.model.symbols.Variable; +import dk.camelot64.kickc.model.values.*; import java.util.*; /** * Find effective alive intervals for all variables in all statements. Add the intervals to the Program. */ -public class Pass3LiveRangesEffectiveAnalysis extends Pass2Base { +public class PassNCalcLiveRangesEffective extends PassNCalcBase { + + public PassNCalcLiveRangesEffective(Program program) { + super(program); + } /** * Call-paths for all procedures. @@ -32,18 +35,14 @@ public class Pass3LiveRangesEffectiveAnalysis extends Pass2Base { */ private VariableReferenceInfos referenceInfo; - - public Pass3LiveRangesEffectiveAnalysis(Program program) { - super(program); - } - - public void findLiveRangesEffective() { + @Override + public LiveRangeVariablesEffective calculate() { this.liveRangeVariables = getProgram().getLiveRangeVariables(); this.referenceInfo = getProgram().getVariableReferenceInfos(); this.procedureCallPaths = new LinkedHashMap<>(); populateProcedureCallPaths(); LiveRangeVariablesEffective aliveEffective = new LiveRangeVariablesEffective(getProgram(), procedureCallPaths, liveRangeVariables, referenceInfo); - getProgram().setLiveRangeVariablesEffective(aliveEffective); + return aliveEffective; //getLog().append("Calculated effective variable live ranges"); } diff --git a/src/main/java/dk/camelot64/kickc/passes/PassNLoopAnalysis.java b/src/main/java/dk/camelot64/kickc/passes/PassNCalcLoopSet.java similarity index 95% rename from src/main/java/dk/camelot64/kickc/passes/PassNLoopAnalysis.java rename to src/main/java/dk/camelot64/kickc/passes/PassNCalcLoopSet.java index 850cc01e2..a8054cf4d 100644 --- a/src/main/java/dk/camelot64/kickc/passes/PassNLoopAnalysis.java +++ b/src/main/java/dk/camelot64/kickc/passes/PassNCalcLoopSet.java @@ -11,13 +11,12 @@ import java.util.*; *

* See http://www.cs.colostate.edu/~cs553/ClassNotes/lecture09-control-dominators.ppt.pdf */ -public class PassNLoopAnalysis extends Pass2SsaOptimization { +public class PassNCalcLoopSet extends PassNCalcBase { - public PassNLoopAnalysis(Program program) { + public PassNCalcLoopSet(Program program) { super(program); } - /** * Finds loops and nested loops in the control flow graph. * Uses the dominators of the graph to find loops. @@ -25,7 +24,7 @@ public class PassNLoopAnalysis extends Pass2SsaOptimization { * See http://www.cs.colostate.edu/~cs553/ClassNotes/lecture09-control-dominators.ppt.pdf */ @Override - public boolean step() { + public NaturalLoopSet calculate() { DominatorsGraph dominators = getProgram().getDominators(); Collection blocks = getGraph().getAllBlocks(); @@ -74,8 +73,7 @@ public class PassNLoopAnalysis extends Pass2SsaOptimization { while(coalesceMore) { coalesceMore = coalesceLoops(loopSet); } - getProgram().setLoopSet(loopSet); - return false; + return loopSet; } /** diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftScopeAnalysis.java b/src/main/java/dk/camelot64/kickc/passes/PassNCalcRegisterUpliftProgram.java similarity index 88% rename from src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftScopeAnalysis.java rename to src/main/java/dk/camelot64/kickc/passes/PassNCalcRegisterUpliftProgram.java index c26778b42..72007495f 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftScopeAnalysis.java +++ b/src/main/java/dk/camelot64/kickc/passes/PassNCalcRegisterUpliftProgram.java @@ -1,9 +1,9 @@ package dk.camelot64.kickc.passes; import dk.camelot64.kickc.model.*; +import dk.camelot64.kickc.model.symbols.Scope; import dk.camelot64.kickc.model.values.ScopeRef; import dk.camelot64.kickc.model.values.VariableRef; -import dk.camelot64.kickc.model.symbols.Scope; import java.util.ArrayList; import java.util.Collection; @@ -11,26 +11,25 @@ import java.util.Collections; import java.util.List; /*** Find the variable equivalence classes to attempt to uplift in each scope */ -public class Pass4RegisterUpliftScopeAnalysis extends Pass2Base { +public class PassNCalcRegisterUpliftProgram extends PassNCalcBase { - public Pass4RegisterUpliftScopeAnalysis(Program program) { + public PassNCalcRegisterUpliftProgram(Program program) { super(program); } - /*** Find the variable equivalence classes to attempt to uplift in each scope */ - public void findScopes() { + /*** Find the variable equivalence classes to attempt to uplift in each scope */ + @Override + public RegisterUpliftProgram calculate() { LiveRangeEquivalenceClassSet equivalenceClassSet = getProgram().getLiveRangeEquivalenceClassSet(); final VariableRegisterWeights registerWeights = getProgram().getVariableRegisterWeights(); RegisterUpliftProgram registerUpliftProgram = new RegisterUpliftProgram(); - Collection allScopes = getProgram().getScope().getAllScopes(true); - allScopes.add(getSymbols()); + allScopes.add(getScope()); for(Scope scope : allScopes) { ScopeRef scopeRef = scope.getRef(); RegisterUpliftScope registerUpliftScope = registerUpliftProgram.addRegisterUpliftScope(scopeRef); - // Find live range equivalence classes for the scope List equivalenceClasses = new ArrayList<>(); for(LiveRangeEquivalenceClass equivalenceClass : equivalenceClassSet.getEquivalenceClasses()) { @@ -43,12 +42,11 @@ public class Pass4RegisterUpliftScopeAnalysis extends Pass2Base { registerUpliftScope.setEquivalenceClasses(equivalenceClasses); } - List upliftScopes = registerUpliftProgram.getRegisterUpliftScopes(); Collections.sort(upliftScopes, (o1, o2) -> Double.compare(registerWeights.getTotalWeights(o2), registerWeights.getTotalWeights(o1))); registerUpliftProgram.setRegisterUpliftScopes(upliftScopes); - getProgram().setRegisterUpliftProgram(registerUpliftProgram); + return registerUpliftProgram; } diff --git a/src/main/java/dk/camelot64/kickc/passes/PassNStatementInfos.java b/src/main/java/dk/camelot64/kickc/passes/PassNCalcStatementInfos.java similarity index 77% rename from src/main/java/dk/camelot64/kickc/passes/PassNStatementInfos.java rename to src/main/java/dk/camelot64/kickc/passes/PassNCalcStatementInfos.java index 43f9b8ab9..72bc4daab 100644 --- a/src/main/java/dk/camelot64/kickc/passes/PassNStatementInfos.java +++ b/src/main/java/dk/camelot64/kickc/passes/PassNCalcStatementInfos.java @@ -11,9 +11,9 @@ import java.util.LinkedHashMap; /** * Identify the block for each statement. */ -public class PassNStatementInfos extends Pass2SsaOptimization { +public class PassNCalcStatementInfos extends PassNCalcBase { - public PassNStatementInfos(Program program) { + public PassNCalcStatementInfos(Program program) { super(program); } @@ -22,7 +22,7 @@ public class PassNStatementInfos extends Pass2SsaOptimization { * Create map from statement index to block */ @Override - public boolean step() { + public StatementInfos calculate() { LinkedHashMap stmtBlocks = new LinkedHashMap<>(); LinkedHashMap stmtIdx = new LinkedHashMap<>(); for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) { @@ -31,8 +31,7 @@ public class PassNStatementInfos extends Pass2SsaOptimization { stmtIdx.put(statement.getIndex(), statement); } } - getProgram().setStatementInfos(new StatementInfos(getProgram(), stmtBlocks, stmtIdx)); - return false; + return new StatementInfos(getProgram(), stmtBlocks, stmtIdx); } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass3VariableRegisterWeightAnalysis.java b/src/main/java/dk/camelot64/kickc/passes/PassNCalcVariableRegisterWeight.java similarity index 63% rename from src/main/java/dk/camelot64/kickc/passes/Pass3VariableRegisterWeightAnalysis.java rename to src/main/java/dk/camelot64/kickc/passes/PassNCalcVariableRegisterWeight.java index 66e60f650..6df2ffaa7 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass3VariableRegisterWeightAnalysis.java +++ b/src/main/java/dk/camelot64/kickc/passes/PassNCalcVariableRegisterWeight.java @@ -1,12 +1,11 @@ package dk.camelot64.kickc.passes; import dk.camelot64.kickc.model.*; -import dk.camelot64.kickc.model.values.*; import dk.camelot64.kickc.model.statements.Statement; import dk.camelot64.kickc.model.statements.StatementAssignment; import dk.camelot64.kickc.model.statements.StatementConditionalJump; import dk.camelot64.kickc.model.statements.StatementPhiBlock; -import dk.camelot64.kickc.model.symbols.Variable; +import dk.camelot64.kickc.model.values.*; /** * Finds register weights for all variables. @@ -17,24 +16,20 @@ import dk.camelot64.kickc.model.symbols.Variable; *

* Based on ComputeWeight from http://compilers.cs.ucla.edu/fernando/projects/soc/reports/short_tech.pdf */ -public class Pass3VariableRegisterWeightAnalysis extends Pass2Base { +public class PassNCalcVariableRegisterWeight extends PassNCalcBase { - private NaturalLoopSet loopSet; - private VariableRegisterWeights variableRegisterWeights; - private LiveRangeVariables liveRangeVariables; - - public Pass3VariableRegisterWeightAnalysis(Program program) { + public PassNCalcVariableRegisterWeight(Program program) { super(program); } /** * Find register weights for all variables */ - public void findWeights() { - - variableRegisterWeights = new VariableRegisterWeights(); - loopSet = getProgram().getLoopSet(); - liveRangeVariables = getProgram().getLiveRangeVariables(); + @Override + public VariableRegisterWeights calculate() { + NaturalLoopSet loopSet = getProgram().getLoopSet(); + LiveRangeVariables liveRangeVariables = getProgram().getLiveRangeVariables(); + VariableRegisterWeights variableRegisterWeights = new VariableRegisterWeights(); for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) { for(Statement statement : block.getStatements()) { @@ -44,47 +39,44 @@ public class Pass3VariableRegisterWeightAnalysis extends Pass2Base { VariableRef philVariable = phiVariable.getVariable(); for(StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) { if(phiRValue.getrValue() instanceof VariableRef) { - double w = addWeight(philVariable, phiRValue.getPredecessor()); + double w = addWeight(philVariable, phiRValue.getPredecessor(), variableRegisterWeights, loopSet, liveRangeVariables); //log.append("Definition of " + philVariable + " w+:" + w + " - [" + statement.getIndex()+"]"); } } // Add weights for each usage of a variable for(StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) { - addUsageWeightRValue(phiRValue.getrValue(), statement, phiRValue.getPredecessor()); + addUsageWeightRValue(phiRValue.getrValue(), statement, phiRValue.getPredecessor(), variableRegisterWeights, loopSet, liveRangeVariables); } } } else if(statement instanceof StatementAssignment) { // Add weights for the definition of the variable - addUsageWeightRValue(((StatementAssignment) statement).getlValue(), statement, block.getLabel()); + addUsageWeightRValue(((StatementAssignment) statement).getlValue(), statement, block.getLabel(), variableRegisterWeights, loopSet, liveRangeVariables); // Add weights for each usage of variables - addUsageWeightRValue(((StatementAssignment) statement).getrValue1(), statement, block.getLabel()); - addUsageWeightRValue(((StatementAssignment) statement).getrValue2(), statement, block.getLabel()); + addUsageWeightRValue(((StatementAssignment) statement).getrValue1(), statement, block.getLabel(), variableRegisterWeights, loopSet, liveRangeVariables); + addUsageWeightRValue(((StatementAssignment) statement).getrValue2(), statement, block.getLabel(), variableRegisterWeights, loopSet, liveRangeVariables); } else if(statement instanceof StatementConditionalJump) { // Add weights for each usage of variables - addUsageWeightRValue(((StatementConditionalJump) statement).getrValue1(), statement, block.getLabel()); - addUsageWeightRValue(((StatementConditionalJump) statement).getrValue2(), statement, block.getLabel()); + addUsageWeightRValue(((StatementConditionalJump) statement).getrValue1(), statement, block.getLabel(), variableRegisterWeights, loopSet, liveRangeVariables); + addUsageWeightRValue(((StatementConditionalJump) statement).getrValue2(), statement, block.getLabel(), variableRegisterWeights, loopSet, liveRangeVariables); } } } - - getProgram().setVariableRegisterWeights(variableRegisterWeights); - + return variableRegisterWeights; } - private void addUsageWeightRValue(Value rValue, Statement statement, LabelRef block) { + private static void addUsageWeightRValue(Value rValue, Statement statement, LabelRef block, VariableRegisterWeights variableRegisterWeights, NaturalLoopSet loopSet, LiveRangeVariables liveRangeVariables) { if(rValue instanceof VariableRef) { - double w = addWeight((VariableRef) rValue, block); + double w = addWeight((VariableRef) rValue, block, variableRegisterWeights, loopSet, liveRangeVariables); //log.append("Usage of " + rValue + " w+:" + w + " - [" + statement.getIndex()+"]"); } else if(rValue instanceof PointerDereferenceSimple) { - addUsageWeightRValue(((PointerDereferenceSimple) rValue).getPointer(), statement, block); + addUsageWeightRValue(((PointerDereferenceSimple) rValue).getPointer(), statement, block, variableRegisterWeights, loopSet, liveRangeVariables); } else if(rValue instanceof PointerDereferenceIndexed) { - addUsageWeightRValue(((PointerDereferenceIndexed) rValue).getPointer(), statement, block); - addUsageWeightRValue(((PointerDereferenceIndexed) rValue).getIndex(), statement, block); + addUsageWeightRValue(((PointerDereferenceIndexed) rValue).getPointer(), statement, block, variableRegisterWeights, loopSet, liveRangeVariables); + addUsageWeightRValue(((PointerDereferenceIndexed) rValue).getIndex(), statement, block, variableRegisterWeights, loopSet, liveRangeVariables); } } - private double addWeight(VariableRef variable, LabelRef block) { - Variable var = getProgram().getScope().getVariable(variable); + private static double addWeight(VariableRef variable, LabelRef block, VariableRegisterWeights variableRegisterWeights, NaturalLoopSet loopSet, LiveRangeVariables liveRangeVariables) { int depth = loopSet.getMaxLoopDepth(block); double w = 1.0 + Math.pow(10.0, depth); LiveRange liveRange = liveRangeVariables.getLiveRange(variable);