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:
parent
1f39ab8c37
commit
693a0bdbed
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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.*;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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<>();
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user