1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-04-08 14:37:40 +00:00

Working on fixing ma_mem variable model.

This commit is contained in:
Jesper Gravgaard 2020-02-10 18:39:25 +01:00
parent bd9a403b64
commit 8f2d766e52
6 changed files with 124 additions and 10 deletions

View File

@ -0,0 +1,10 @@
ldy {m1}
sty $fe
ldy {m1}+1
sty $ff
ldy #0
lda {m2}
sta ($fe),y
iny
lda {m2}+1
sta ($fe),y

View File

@ -0,0 +1,5 @@
lda {m1}
sta $fe
lda {m1}+1
sta $ff
lda ($fe),y

View File

@ -668,14 +668,14 @@ class AsmFragmentTemplateSynthesisRule {
synths.add(new AsmFragmentTemplateSynthesisRule("pb(.)z1_derefidx_vbuaa=(.*)", twoZM1, "sta $ff" , "vb$1aa=$2", "ldy $ff\nsta ({z1}),y", mapZM1));
// Synthesize some constant pointers as constant words (remove when the above section can be included)
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_(lt|gt|le|ge|eq|neq)_p..([cz].)_then_(.*)", null, null, "$1_$2_vwu$3_then_$4", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("p..([cz].)_(lt|gt|le|ge|eq|neq)_(.*)", null, null, "vwu$1_$2_$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=p..([zc].)", null, null, "$1=vwu$2", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)_(plus|minus|bor|bxor)_p..([cz].)", null, null, "$1=$2_$3_vwu$4", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=p..([cz].)_(plus|minus|bor|bxor)_(.*)", null, null, "$1=vwu$2_$3_$4", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("p..([cz].)=(.*)_(sethi|setlo|plus|minus)_(.*)", null, null, "vwu$1=$2_$3_$4", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=p..([cz].)_(sethi|setlo|plus|minus)_(.*)", null, null, "$1=vwu$2_$3_$4", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("p..([cz].)=_(inc|dec)_p..([cz].)", null, null, "vwu$1=_$2_vwu$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)_(lt|gt|le|ge|eq|neq)_p..([czm].)_then_(.*)", null, null, "$1_$2_vwu$3_then_$4", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("p..([czm].)_(lt|gt|le|ge|eq|neq)_(.*)", null, null, "vwu$1_$2_$3", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=p..([czm].)", null, null, "$1=vwu$2", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=(.*)_(plus|minus|bor|bxor)_p..([czm].)", null, null, "$1=$2_$3_vwu$4", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=p..([czm].)_(plus|minus|bor|bxor)_(.*)", null, null, "$1=vwu$2_$3_$4", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("p..([czm].)=(.*)_(sethi|setlo|plus|minus)_(.*)", null, null, "vwu$1=$2_$3_$4", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)=p..([czm].)_(sethi|setlo|plus|minus)_(.*)", null, null, "$1=vwu$2_$3_$4", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("p..([czm].)=_(inc|dec)_p..([czm].)", null, null, "vwu$1=_$2_vwu$3", null, null));
// Synthesize constants using AA/XX/YY
synths.add(new AsmFragmentTemplateSynthesisRule("(.*)vb(.)c1(.*)", rvalAa+"|"+ derefC1, "lda #{c1}", "$1vb$2aa$3", null, null));
@ -775,7 +775,6 @@ class AsmFragmentTemplateSynthesisRule {
synths.add(new AsmFragmentTemplateSynthesisRule("vb(.)aa=_dec_(.*)", null, null, "vb$1aa=$2_minus_1", null, null));
synths.add(new AsmFragmentTemplateSynthesisRule("vw(.)z1=_inc_vw(.z.)", null, null, "vw$1z1=vw$2_plus_1", null, null));
return synths;
}

View File

@ -1,11 +1,12 @@
package dk.camelot64.kickc.model;
import dk.camelot64.kickc.model.statements.Statement;
import dk.camelot64.kickc.model.statements.StatementAssignment;
import dk.camelot64.kickc.model.statements.StatementLValue;
import dk.camelot64.kickc.model.statements.StatementPhiBlock;
import dk.camelot64.kickc.model.symbols.Label;
import dk.camelot64.kickc.model.symbols.Procedure;
import dk.camelot64.kickc.model.symbols.ProgramScope;
import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.model.values.*;
import dk.camelot64.kickc.passes.Pass2ConstantIdentification;
@ -104,6 +105,75 @@ public class ControlFlowGraph implements Serializable {
return assignments;
}
/** Any assignment of a value to a SymbolVariable.
* Potential assignments include StatementLValue, StatementPhi and Variable.initValue
* */
public static class VarAssignment {
public enum Type {
STATEMENT_LVALUE,
STATEMENT_PHI,
INIT_VALUE
}
/** The type of assignment. */
public final Type type;
/** The block containing the assignment statement. Null if type is not STATEMENT_LVALUE or STATEMENT_PHI */
public final ControlFlowBlock block;
/* The LValue-statement. Null if type is not STATEMENT_LVALUE. */
public final StatementLValue statementLValue;
/* The PHI-statement. Null if type is not STATEMENT_PHI. */
public final StatementPhiBlock statementPhi;
public final StatementPhiBlock.PhiVariable statementPhiVariable;
/* The Variable with initValue. Null if type is not INIT_VALUE. */
public final Variable variableInitValue;
public VarAssignment(Type type, ControlFlowBlock block, StatementLValue statementLValue, StatementPhiBlock statementPhi, StatementPhiBlock.PhiVariable statementPhiVariable, Variable variableInitValue) {
this.type = type;
this.block = block;
this.statementLValue = statementLValue;
this.statementPhi = statementPhi;
this.statementPhiVariable = statementPhiVariable;
this.variableInitValue = variableInitValue;
}
}
/**
* Get all assignments of value to a variable.
*
* @param variable The variable to find the assignment for
* @return All assignments of values to the variable
*/
public static List<VarAssignment> getVarAssignments(SymbolVariableRef variable, ControlFlowGraph graph, ProgramScope programScope) {
ArrayList<VarAssignment> varAssignments = new ArrayList<>();
Variable varDef = programScope.getVariable(variable);
if(varDef.getInitValue()!=null) {
varAssignments.add(new VarAssignment(VarAssignment.Type.INIT_VALUE, null, null, null, null, varDef));
}
for(ControlFlowBlock block : graph.getAllBlocks()) {
for(Statement statement : block.getStatements()) {
if(statement instanceof StatementLValue) {
StatementLValue assignment = (StatementLValue) statement;
if(variable.equals(assignment.getlValue())) {
varAssignments.add(new VarAssignment(VarAssignment.Type.STATEMENT_LVALUE, block, assignment, null, null, null));
}
} else if(statement instanceof StatementPhiBlock) {
for(StatementPhiBlock.PhiVariable phiVariable : ((StatementPhiBlock) statement).getPhiVariables()) {
if(phiVariable.getVariable().equals(variable)) {
varAssignments.add(new VarAssignment(VarAssignment.Type.STATEMENT_PHI, block, null, (StatementPhiBlock) statement, phiVariable, null));
}
}
}
}
}
return varAssignments;
}
/**
* Get the block containing the assignment of the passed variable. Assumes that only a single assignment exists.
*

View File

@ -53,6 +53,8 @@ public class VariableBuilder {
public static VariableBuilderConfig getDefaultConfig(CompileLog log) {
VariableBuilderConfig config = new VariableBuilderConfig();
//config.addSetting("ma_mem", log, null);
//config.addSetting("parameter_ssa_mem", log, null);
config.addSetting("ssa_zp", log, null);
config.addSetting("array_ma_mem", log, null);
config.addSetting("global_struct_ma_mem", log, null);

View File

@ -1,6 +1,8 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.ControlFlowBlock;
import dk.camelot64.kickc.model.ControlFlowGraph;
import dk.camelot64.kickc.model.InternalError;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.statements.*;
import dk.camelot64.kickc.model.symbols.ProgramScope;
@ -126,6 +128,31 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
if(assignment.getrValue1() == null && assignment.getOperator() == null && assignment.getrValue2() instanceof VariableRef) {
// Alias assignment
VariableRef alias = (VariableRef) assignment.getrValue2();
List<ControlFlowGraph.VarAssignment> assignments = ControlFlowGraph.getVarAssignments(alias, program.getGraph(), program.getScope());
if(assignments.size() == 0)
throw new InternalError("Error! Var is never assigned! " + variable);
else if(assignments.size() > 1)
// Multiple assignments exist
continue;
// assignments.size()==1
// Examine if the alias is assigned inside another scope
ControlFlowGraph.VarAssignment varAssignment = assignments.get(0);
if(ControlFlowGraph.VarAssignment.Type.INIT_VALUE.equals(varAssignment.type)) {
aliases.add(variable, alias);
} else {
ScopeRef varAssignmentScope = block.getScope();
ScopeRef aliasAssignmentScope = varAssignment.block.getScope();
if(!alias.isIntermediate() && (!varAssignmentScope.equals(aliasAssignmentScope) || !variable.getScopeNames().equals(alias.getScopeNames()))) {
if(program.getLog().isVerboseNonOptimization()) {
program.getLog().append("Not aliassing across scopes: " + variable + " " + alias);
}
} else {
aliases.add(variable, alias);
}
}
/*
// Examine if the alis is assigned inside another scope
ControlFlowBlock aliasAssignmentBlock = program.getGraph().getAssignmentBlock(alias);
ScopeRef aliasScope = aliasAssignmentBlock.getScope();
@ -137,6 +164,7 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
} else {
aliases.add(variable, alias);
}
*/
}
}
} else if(statement instanceof StatementPhiBlock) {