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

Refactored variable reference infos to be calculated on demand.

This commit is contained in:
jespergravgaard 2019-08-02 00:11:54 +02:00
parent 1f39ab8c37
commit 693a0bdbed
9 changed files with 62 additions and 45 deletions

View File

@ -30,9 +30,6 @@ public class Compiler {
/** Enable the zero-page coalesce pass. It takes a lot of time, but limits the zero page usage significantly. */
private boolean enableZeroPageCoalasce = false;
/** The target platform. */
private TargetPlatform targetPlatform = TargetPlatform.DEFAULT;
public Compiler() {
this.program = new Program();
}
@ -41,11 +38,11 @@ public class Compiler {
this.upliftCombinations = upliftCombinations;
}
public void setEnableZeroPageCoalasce(boolean optimizeZeroPageCoalesce) {
void setEnableZeroPageCoalasce(boolean optimizeZeroPageCoalesce) {
this.enableZeroPageCoalasce = optimizeZeroPageCoalesce;
}
public void setTargetPlatform(TargetPlatform targetPlatform) {
void setTargetPlatform(TargetPlatform targetPlatform) {
program.setTargetPlatform(targetPlatform);
}
@ -155,8 +152,7 @@ public class Compiler {
}
}
private Program pass1GenerateSSA() {
private void pass1GenerateSSA() {
if(getLog().isVerboseStatementSequence()) {
getLog().append("\nSTATEMENTS");
getLog().append(program.getStatementSequence().toString(program));
@ -246,7 +242,6 @@ public class Compiler {
program.endPass1();
return program;
}
private void pass2AssertSSA() {
@ -281,7 +276,7 @@ public class Compiler {
optimizations.add(new PassNTypeIdSimplification(program));
optimizations.add(new PassNSizeOfSimplification(program));
optimizations.add(new PassNStatementIndices(program));
optimizations.add(new PassNVariableReferenceInfos(program));
optimizations.add(new PassNVariableReferenceInfosClear(program));
optimizations.add(new Pass2UnaryNotSimplification(program));
optimizations.add(new Pass2AliasElimination(program));
optimizations.add(new Pass2IdenticalPhiElimination(program));
@ -319,7 +314,7 @@ public class Compiler {
private void pass2UnrollLoops() {
List<Pass2SsaOptimization> loopUnrolling = new ArrayList<>();
loopUnrolling.add(new PassNStatementIndices(program));
loopUnrolling.add(new PassNVariableReferenceInfos(program));
loopUnrolling.add(new PassNVariableReferenceInfosClear(program));
loopUnrolling.add(new PassNStatementInfos(program));
loopUnrolling.add(new PassNDominatorsAnalysis(program));
loopUnrolling.add(new PassNLoopAnalysis(program));
@ -346,7 +341,7 @@ public class Compiler {
// Constant inlining optimizations - as the last step to ensure that constant identification has been completed
List<Pass2SsaOptimization> constantOptimizations = new ArrayList<>();
constantOptimizations.add(new PassNStatementIndices(program));
constantOptimizations.add(new PassNVariableReferenceInfos(program));
constantOptimizations.add(new PassNVariableReferenceInfosClear(program));
constantOptimizations.add(new Pass2NopCastInlining(program));
constantOptimizations.add(new Pass2MultiplyToShiftRewriting(program));
constantOptimizations.add(new Pass2ConstantInlining(program));
@ -428,7 +423,7 @@ public class Compiler {
//getLog().setVerboseLiveRanges(true);
new PassNStatementInfos(program).execute();
new PassNVariableReferenceInfos(program).execute();
program.clearVariableReferenceInfos();
new Pass3LiveRangesAnalysis(program).findLiveRanges();
//getLog().append("CONTROL FLOW GRAPH - LIVE RANGES FOUND");
//getLog().append(program.getGraph().toString(program));
@ -445,7 +440,7 @@ public class Compiler {
new PassNStatementIndices(program).execute();
program.clearCallGraph();
new PassNStatementInfos(program).execute();
new PassNVariableReferenceInfos(program).execute();
program.clearVariableReferenceInfos();
new Pass3SymbolInfos(program).generateSymbolInfos();
new Pass3LiveRangesAnalysis(program).findLiveRanges();
new Pass3LiveRangesEffectiveAnalysis(program).findLiveRangesEffective();

View File

@ -7,6 +7,7 @@ import dk.camelot64.kickc.model.symbols.ProgramScope;
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 java.nio.file.Path;
import java.util.ArrayList;
@ -59,9 +60,9 @@ public class Program {
/** A saved program snapshot that can be rolled back. Used to store the (DYNAMIC) state of the program while trying out a potential optimization. PASS 2 (DYNAMIC) */
private ProgramSnapshot snapshot;
/** Cached information about calls. PASS 1-4 (CACHED) */
/** Cached information about calls. PASS 1-4 (CACHED ON-DEMAND) */
private CallGraph callGraph;
/** Cached information about the variables referenced by blocks/statements. PASS 1-4 (CACHED) */
/** Cached information about the variables referenced by blocks/statements. PASS 1-4 (CACHED ON-DEMAND) */
private VariableReferenceInfos variableReferenceInfos;
/** Information about dominators of all blocks. PASS 2U-4 (CACHED) */
private DominatorsGraph dominators;
@ -257,6 +258,17 @@ public class Program {
this.callGraph = null;
}
public VariableReferenceInfos getVariableReferenceInfos() {
if(variableReferenceInfos==null)
this.variableReferenceInfos = new PassNCalcVariableReferenceInfos(this).calculate();
return variableReferenceInfos;
}
public void clearVariableReferenceInfos() {
this.variableReferenceInfos = null;
}
public DominatorsGraph getDominators() {
return dominators;
}
@ -273,13 +285,6 @@ public class Program {
this.loopSet = loopSet;
}
public VariableReferenceInfos getVariableReferenceInfos() {
return variableReferenceInfos;
}
public void setVariableReferenceInfos(VariableReferenceInfos variableReferenceInfos) {
this.variableReferenceInfos = variableReferenceInfos;
}
public StatementInfos getStatementInfos() {
return statementInfos;

View File

@ -2,7 +2,7 @@ package dk.camelot64.kickc.model;
import dk.camelot64.kickc.model.values.*;
import dk.camelot64.kickc.model.statements.Statement;
import dk.camelot64.kickc.passes.PassNVariableReferenceInfos;
import dk.camelot64.kickc.passes.PassNCalcVariableReferenceInfos;
import java.util.Collection;
import java.util.LinkedHashSet;
@ -146,7 +146,7 @@ public class VariableReferenceInfos {
* @return All referenced variables
*/
public static Collection<VariableRef> getReferencedVars(RValue rValue) {
return PassNVariableReferenceInfos.getReferencedVars(rValue);
return PassNCalcVariableReferenceInfos.getReferencedVars(rValue);
}
/**

View File

@ -33,14 +33,13 @@ public class Pass1AssertUsedVars extends Pass1Base {
public boolean step() {
new PassNStatementIndices(getProgram()).execute();
new PassNVariableReferenceInfos(getProgram()).execute();
getProgram().clearVariableReferenceInfos();
VariableReferenceInfos referenceInfos = getProgram().getVariableReferenceInfos();
ControlFlowBlock beginBlock = getProgram().getGraph().getBlock(new LabelRef(SymbolRef.BEGIN_BLOCK_NAME));
assertUsedVars(beginBlock, null, referenceInfos, new LinkedHashSet<>(), new LinkedHashSet<>());
getProgram().setVariableReferenceInfos(null);
getProgram().clearVariableReferenceInfos();
new PassNStatementIndices(getProgram()).clearStatementIndices();
return false;
}

View File

@ -1,14 +1,17 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.*;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.iterator.ProgramValue;
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
import dk.camelot64.kickc.model.values.*;
import dk.camelot64.kickc.model.symbols.ConstantVar;
import dk.camelot64.kickc.model.symbols.ProgramScope;
import dk.camelot64.kickc.model.symbols.Symbol;
import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.values.ConstantArray;
import dk.camelot64.kickc.model.values.ConstantRef;
import dk.camelot64.kickc.model.values.ConstantString;
import dk.camelot64.kickc.model.values.ConstantValue;
import java.util.*;

View File

@ -344,7 +344,7 @@ public class Pass4CodeGeneration {
for(StatementPhiBlock.PhiVariable phiVariable : ((StatementPhiBlock) statement).getPhiVariables()) {
for(StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) {
RValue phiRRValue = phiRValue.getrValue();
Collection<ConstantRef> phiRValueConstRefs = PassNVariableReferenceInfos.getReferencedConsts(phiRRValue);
Collection<ConstantRef> phiRValueConstRefs = PassNCalcVariableReferenceInfos.getReferencedConsts(phiRRValue);
for(ConstantRef phiRValueConstRef : phiRValueConstRefs) {
if(phiRValueConstRef.equals(constantVar.getRef())) {
found = true;

View File

@ -14,18 +14,17 @@ import java.util.*;
/**
* Identify variables defined/referenced for each block & statement.
*/
public class PassNVariableReferenceInfos extends Pass2SsaOptimization {
public class PassNCalcVariableReferenceInfos extends PassNCalcBase<VariableReferenceInfos> {
public PassNVariableReferenceInfos(Program program) {
public PassNCalcVariableReferenceInfos(Program program) {
super(program);
}
private LinkedHashMap<LabelRef, Collection<VariableRef>> blockDirectVarRefsMap = null;
private LinkedHashMap<LabelRef, Collection<VariableRef>> blockDirectUsedVarsMap = null;
/** Create defined/referenced maps */
@Override
public boolean step() {
public VariableReferenceInfos calculate() {
LinkedHashMap<LabelRef, Collection<VariableRef>> blockReferencedVars = new LinkedHashMap<>();
LinkedHashMap<LabelRef, Collection<VariableRef>> blockUsedVars = new LinkedHashMap<>();
LinkedHashMap<Integer, Collection<VariableRef>> stmtReferenced = new LinkedHashMap<>();
@ -34,12 +33,11 @@ public class PassNVariableReferenceInfos extends Pass2SsaOptimization {
blockDirectVarRefsMap = new LinkedHashMap<>();
blockDirectUsedVarsMap = new LinkedHashMap<>();
for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) {
LinkedHashSet<VariableRef> blockDirectVarRefs = new LinkedHashSet<>();;
LinkedHashSet<VariableRef> blockDirectUsedVars = new LinkedHashSet<>();;
LinkedHashSet<VariableRef> blockDirectVarRefs = new LinkedHashSet<>();
LinkedHashSet<VariableRef> blockDirectUsedVars = new LinkedHashSet<>();
for(Statement statement : block.getStatements()) {
LinkedHashSet<SymbolVariableRef> stmtSymbolVarRefs = new LinkedHashSet<>();
LinkedHashSet<VariableRef> stmtVarRefs = new LinkedHashSet<>();
LinkedHashSet<VariableRef> stmtUsedVars = new LinkedHashSet<>();
ProgramValueIterator.execute(statement,
(programValue, currentStmt, stmtIt, currentBlock) -> {
if(programValue.get() instanceof SymbolVariableRef)
@ -49,7 +47,7 @@ public class PassNVariableReferenceInfos extends Pass2SsaOptimization {
}
, null, null);
Collection<VariableRef> stmtDefinedVars = getDefinedVars(statement);
stmtUsedVars.addAll(stmtVarRefs);
LinkedHashSet<VariableRef> stmtUsedVars = new LinkedHashSet<>(stmtVarRefs);
stmtUsedVars.removeAll(stmtDefinedVars);
blockDirectVarRefs.addAll(stmtVarRefs);
blockDirectUsedVars.addAll(stmtUsedVars);
@ -103,8 +101,7 @@ public class PassNVariableReferenceInfos extends Pass2SsaOptimization {
}
});
}
getProgram().setVariableReferenceInfos(new VariableReferenceInfos(blockReferencedVars, blockUsedVars, stmtReferenced, stmtDefined, symbolVarReferences));
return false;
return new VariableReferenceInfos(blockReferencedVars, blockUsedVars, stmtReferenced, stmtDefined, symbolVarReferences);
}
/**
@ -129,7 +126,7 @@ public class PassNVariableReferenceInfos extends Pass2SsaOptimization {
* @param rValue The rValue
* @return All referenced constants
*/
public static Collection<ConstantRef> getReferencedConsts(RValue rValue) {
static Collection<ConstantRef> getReferencedConsts(RValue rValue) {
LinkedHashSet<ConstantRef> referencedConsts = new LinkedHashSet<>();
for(SymbolRef symbolRef : getReferenced(rValue)) {
if(symbolRef instanceof ConstantRef) {
@ -163,7 +160,6 @@ public class PassNVariableReferenceInfos extends Pass2SsaOptimization {
* @param referencedVars the set of referenced variables
* @param usedVars the set of referenced variables
* @param visited The blocks already visited during the search. Used to stop infinite recursion
* @return All used variables
*/
private void addReferencedVars(LabelRef labelRef, ControlFlowBlock block, LinkedHashSet<VariableRef> referencedVars, LinkedHashSet<VariableRef> usedVars, Collection<LabelRef> visited) {
if(labelRef == null || visited.contains(labelRef))
@ -192,7 +188,7 @@ public class PassNVariableReferenceInfos extends Pass2SsaOptimization {
StatementAssignment assignment = (StatementAssignment) stmt;
LValue lValue = assignment.getlValue();
if(lValue instanceof VariableRef) {
return Arrays.asList((VariableRef) lValue);
return Collections.singletonList((VariableRef) lValue);
}
} else if(stmt instanceof StatementPhiBlock) {
List<VariableRef> defined = new ArrayList<>();

View File

@ -31,7 +31,7 @@ public class PassNEliminateUnusedVars extends Pass2SsaOptimization {
@Override
public boolean step() {
new PassNStatementIndices(getProgram()).execute();
new PassNVariableReferenceInfos(getProgram()).execute();
getProgram().clearVariableReferenceInfos();
VariableReferenceInfos referenceInfos = getProgram().getVariableReferenceInfos();
boolean modified = false;
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
@ -139,7 +139,7 @@ public class PassNEliminateUnusedVars extends Pass2SsaOptimization {
}
}
getProgram().setVariableReferenceInfos(null);
getProgram().clearVariableReferenceInfos();
new PassNStatementIndices(getProgram()).clearStatementIndices();
return modified;
}

View File

@ -0,0 +1,19 @@
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;
}
}