From 796edcc05bb62ee0704876bff9114ab7c121a01c Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Sat, 11 Nov 2017 18:07:44 +0100 Subject: [PATCH] Added cached symbol table for faster uplift --- .../java/dk/camelot64/kickc/Compiler.java | 1 + .../dk/camelot64/kickc/model/Program.java | 9 +++++ .../camelot64/kickc/model/StatementInfos.java | 2 +- .../dk/camelot64/kickc/model/SymbolInfos.java | 22 +++++++++++ .../kickc/model/VariableReferenceInfos.java | 3 +- .../kickc/passes/Pass3SymbolInfos.java | 37 +++++++++++++++++++ .../Pass4RegisterUpliftCombinations.java | 2 +- 7 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 src/main/java/dk/camelot64/kickc/model/SymbolInfos.java create mode 100644 src/main/java/dk/camelot64/kickc/passes/Pass3SymbolInfos.java diff --git a/src/main/java/dk/camelot64/kickc/Compiler.java b/src/main/java/dk/camelot64/kickc/Compiler.java index 374ab2dc7..0ff4f9b6b 100644 --- a/src/main/java/dk/camelot64/kickc/Compiler.java +++ b/src/main/java/dk/camelot64/kickc/Compiler.java @@ -212,6 +212,7 @@ public class Compiler { new Pass3CallGraphAnalysis(program).findCallGraph(); new Pass3StatementInfos(program).generateStatementInfos(); new Pass3VariableReferenceInfos(program).generateVariableReferenceInfos(); + new Pass3SymbolInfos(program).generateSymbolInfos(); new Pass3LiveRangesAnalysis(program).findLiveRanges(); program.getLog().append("CONTROL FLOW GRAPH - BEFORE EFFECTIVE LIVE RANGES"); program.getLog().append(program.getGraph().toString(program)); diff --git a/src/main/java/dk/camelot64/kickc/model/Program.java b/src/main/java/dk/camelot64/kickc/model/Program.java index 6a498b317..e3d609c25 100644 --- a/src/main/java/dk/camelot64/kickc/model/Program.java +++ b/src/main/java/dk/camelot64/kickc/model/Program.java @@ -43,6 +43,7 @@ public class Program { private RegisterPotentials registerPotentials; /** Separation of live range equivalence classes into scopes - used for register uplift */ private RegisterUpliftProgram registerUpliftProgram; + private SymbolInfos symbolInfos; @JsonCreator public Program( @@ -131,6 +132,14 @@ public class Program { this.statementInfos = statementInfos; } + public SymbolInfos getSymbolInfos() { + return symbolInfos; + } + + public void setSymbolInfos(SymbolInfos symbolInfos) { + this.symbolInfos = symbolInfos; + } + public void setLiveRangeVariables(LiveRangeVariables liveRangeVariables) { this.liveRangeVariables = liveRangeVariables; } diff --git a/src/main/java/dk/camelot64/kickc/model/StatementInfos.java b/src/main/java/dk/camelot64/kickc/model/StatementInfos.java index e1890e0c9..331ddddf0 100644 --- a/src/main/java/dk/camelot64/kickc/model/StatementInfos.java +++ b/src/main/java/dk/camelot64/kickc/model/StatementInfos.java @@ -2,7 +2,7 @@ package dk.camelot64.kickc.model; import java.util.Map; -/** Cached information about statements is a part of (which block they bloing to, statement from idx, ...) */ +/** Cached information about statements (which block they belong to, statement from idx, ...) */ public class StatementInfos { /** The control flow graph. */ diff --git a/src/main/java/dk/camelot64/kickc/model/SymbolInfos.java b/src/main/java/dk/camelot64/kickc/model/SymbolInfos.java new file mode 100644 index 000000000..bf64919fe --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/model/SymbolInfos.java @@ -0,0 +1,22 @@ +package dk.camelot64.kickc.model; + +import java.util.Map; + +/** Cached information about symbols. Contains a symbol table cache for fast access. */ +public class SymbolInfos { + + private Map symbols; + + public SymbolInfos(Map symbols) { + this.symbols = symbols; + } + + public Symbol getSymbol(SymbolRef ref) { + return symbols.get(ref); + } + + public Variable getVariable(VariableRef ref) { + return (Variable) getSymbol(ref); + } + +} diff --git a/src/main/java/dk/camelot64/kickc/model/VariableReferenceInfos.java b/src/main/java/dk/camelot64/kickc/model/VariableReferenceInfos.java index 15edbdf00..d920d4b69 100644 --- a/src/main/java/dk/camelot64/kickc/model/VariableReferenceInfos.java +++ b/src/main/java/dk/camelot64/kickc/model/VariableReferenceInfos.java @@ -6,7 +6,7 @@ import java.util.Collection; import java.util.LinkedHashSet; import java.util.Map; -/** */ +/** Cached information about which variables are defined/referenced/used in statements / blocks. */ public class VariableReferenceInfos { /** Variables referenced in each block. */ @@ -39,7 +39,6 @@ public class VariableReferenceInfos { */ public Collection getReferenced(LabelRef labelRef) { return blockReferenced.get(labelRef); - } /** diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass3SymbolInfos.java b/src/main/java/dk/camelot64/kickc/passes/Pass3SymbolInfos.java new file mode 100644 index 000000000..ee339bcf0 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/passes/Pass3SymbolInfos.java @@ -0,0 +1,37 @@ +package dk.camelot64.kickc.passes; + + +import dk.camelot64.kickc.model.*; + +import java.util.LinkedHashMap; + +/** Create the symbol table cache */ +public class Pass3SymbolInfos extends Pass2Base { + + public Pass3SymbolInfos(Program program) { + super(program); + } + + /** + * Create map from statement index to block + */ + public void generateSymbolInfos() { + LinkedHashMap symbolCache = new LinkedHashMap<>(); + ProgramScope scope = getProgram().getScope(); + generateCache(symbolCache, scope); + SymbolInfos symbolInfos = new SymbolInfos(symbolCache); + getProgram().setSymbolInfos(symbolInfos); + + } + + private void generateCache(LinkedHashMap symbolCache, Scope scope) { + for (Symbol symbol : scope.getAllSymbols()) { + symbolCache.put(symbol.getRef(), symbol); + if(symbol instanceof Scope) { + generateCache(symbolCache, (Scope) symbol); + } + } + } + + +} diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftCombinations.java b/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftCombinations.java index 75d4f51a3..d2477822b 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftCombinations.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftCombinations.java @@ -223,7 +223,7 @@ public class Pass4RegisterUpliftCombinations extends Pass2Base { Collection alive = aliveCombinations.getEffectiveAliveAtStmt(callPath); Pass2AliasElimination.Aliases callPathAliases = aliveCombinations.getEffectiveAliasesAtStmt(callPath); for (VariableRef varRef : alive) { - Variable var = programScope.getVariable(varRef); + Variable var = program.getSymbolInfos().getVariable(varRef); Registers.Register allocation = var.getAllocation(); LiveRangeEquivalenceClass allocationClass = usedRegisters.get(allocation); if (allocationClass != null && !allocationClass.contains(varRef)) {