1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-02-21 07:29:14 +00:00

Working on storage strategy replacing booleans. #328

This commit is contained in:
Jesper Gravgaard 2019-09-29 09:19:31 +02:00
parent 5d0fe66906
commit 97b83a929a
9 changed files with 37 additions and 35 deletions

View File

@ -7,6 +7,7 @@ import dk.camelot64.kickc.model.Registers;
import dk.camelot64.kickc.model.statements.StatementSource; import dk.camelot64.kickc.model.statements.StatementSource;
import dk.camelot64.kickc.model.symbols.Label; import dk.camelot64.kickc.model.symbols.Label;
import dk.camelot64.kickc.model.symbols.ProgramScope; import dk.camelot64.kickc.model.symbols.ProgramScope;
import dk.camelot64.kickc.model.symbols.SymbolVariable;
import dk.camelot64.kickc.model.symbols.Variable; import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.values.ConstantInteger; import dk.camelot64.kickc.model.values.ConstantInteger;
@ -80,12 +81,12 @@ public class AsmFragmentTemplate {
// Generate a dummy instance to find clobber & cycles // Generate a dummy instance to find clobber & cycles
ProgramScope scope = new ProgramScope(); ProgramScope scope = new ProgramScope();
LinkedHashMap<String, Value> bindings = new LinkedHashMap<>(); LinkedHashMap<String, Value> bindings = new LinkedHashMap<>();
Variable v1 = new Variable("$tmp1", scope, SymbolType.BYTE, null, true, false, false); Variable v1 = new Variable("$tmp1", scope, SymbolType.BYTE, null, SymbolVariable.StorageStrategy.PHI_VERSION, true, false, false);
Variable v2 = new Variable("$tmp2", scope, SymbolType.BYTE, null, true, false, false); Variable v2 = new Variable("$tmp2", scope, SymbolType.BYTE, null, SymbolVariable.StorageStrategy.PHI_VERSION, true, false, false);
Variable v3 = new Variable("$tmp3", scope, SymbolType.BYTE, null, true, false, false); Variable v3 = new Variable("$tmp3", scope, SymbolType.BYTE, null, SymbolVariable.StorageStrategy.PHI_VERSION, true, false, false);
Variable v4 = new Variable("$tmp4", scope, SymbolType.BYTE, null, true, false, false); Variable v4 = new Variable("$tmp4", scope, SymbolType.BYTE, null, SymbolVariable.StorageStrategy.PHI_VERSION, true, false, false);
Variable v5 = new Variable("$tmp5", scope, SymbolType.BYTE, null, true, false, false); Variable v5 = new Variable("$tmp5", scope, SymbolType.BYTE, null, SymbolVariable.StorageStrategy.PHI_VERSION, true, false, false);
Variable v6 = new Variable("$tmp6", scope, SymbolType.BYTE, null, true, false, false); Variable v6 = new Variable("$tmp6", scope, SymbolType.BYTE, null, SymbolVariable.StorageStrategy.PHI_VERSION, true, false, false);
v1.setAllocation(new Registers.RegisterZpByte(2)); v1.setAllocation(new Registers.RegisterZpByte(2));
v2.setAllocation(new Registers.RegisterZpByte(4)); v2.setAllocation(new Registers.RegisterZpByte(4));
v3.setAllocation(new Registers.RegisterZpByte(6)); v3.setAllocation(new Registers.RegisterZpByte(6));

View File

@ -12,7 +12,7 @@ public class ConstantVar extends SymbolVariable {
private ConstantValue value; private ConstantValue value;
public ConstantVar(String name, Scope scope, SymbolType type, ConstantValue value, String dataSegment) { public ConstantVar(String name, Scope scope, SymbolType type, ConstantValue value, String dataSegment) {
super(name, scope, type, dataSegment); super(name, scope, type, StorageStrategy.CONSTANT, dataSegment);
this.value = value; this.value = value;
} }

View File

@ -100,12 +100,12 @@ public abstract class Scope implements Symbol, Serializable {
} }
public Variable addVariablePhiMaster(String name, SymbolType type, String dataSegment) { public Variable addVariablePhiMaster(String name, SymbolType type, String dataSegment) {
return add(new Variable(name, this, type, dataSegment, false, false, true)); return add(new Variable(name, this, type, dataSegment, SymbolVariable.StorageStrategy.PHI_MASTER, false, false, true));
} }
public Variable addVariableIntermediate() { public Variable addVariableIntermediate() {
String name = allocateIntermediateVariableName(); String name = allocateIntermediateVariableName();
return add(new Variable(name, this, SymbolType.VAR, getSegmentData(), true, false, false)); return add(new Variable(name, this, SymbolType.VAR, getSegmentData(), SymbolVariable.StorageStrategy.INTERMEDIATE, true, false, false));
} }
/** /**
@ -347,7 +347,7 @@ public abstract class Scope implements Symbol, Serializable {
if(asmName != null) { if(asmName != null) {
res.append(" " + asmName); res.append(" " + asmName);
} }
if(symVar.getStorageStrategy().equals(SymbolVariable.StorageStrategy.MEMORY)) { if(SymbolVariable.StorageStrategy.MEMORY.equals(symVar.getStorageStrategy())) {
res.append(" memory"); res.append(" memory");
} }
Registers.Register declRegister = symVar.getDeclaredRegister(); Registers.Register declRegister = symVar.getDeclaredRegister();

View File

@ -60,7 +60,7 @@ public abstract class SymbolVariable implements Symbol {
* <li>CONSTANT-variables are constant. * <li>CONSTANT-variables are constant.
* </ul> * </ul>
**/ **/
public enum StorageStrategy {PHI_REGISTER, MEMORY, CONSTANT } public enum StorageStrategy {PHI_MASTER, PHI_VERSION, INTERMEDIATE, MEMORY, CONSTANT }
/** The storage strategy for the variable. */ /** The storage strategy for the variable. */
private StorageStrategy storageStrategy; private StorageStrategy storageStrategy;
@ -75,14 +75,14 @@ public abstract class SymbolVariable implements Symbol {
private String dataSegment; private String dataSegment;
public SymbolVariable(String name, Scope scope, SymbolType type, String dataSegment) { public SymbolVariable(String name, Scope scope, SymbolType type, StorageStrategy storageStrategy, String dataSegment) {
this.name = name; this.name = name;
this.scope = scope; this.scope = scope;
this.type = type; this.type = type;
this.inferredType = false; this.inferredType = false;
this.comments = new ArrayList<>(); this.comments = new ArrayList<>();
this.dataSegment = dataSegment; this.dataSegment = dataSegment;
this.storageStrategy = StorageStrategy.PHI_REGISTER; this.storageStrategy = storageStrategy;
setFullName(); setFullName();
} }

View File

@ -25,7 +25,7 @@ public class Variable extends SymbolVariable {
private boolean isPhiMaster; private boolean isPhiMaster;
/** The number of the next version (only used for PHI masters)*/ /** The number of the next version (only used for PHI masters)*/
private Integer nextVersionNumber; private Integer nextPhiVersionNumber;
/* true if the variable is a PHI version. (the "master" variable has storage strategy PHI)*/ /* true if the variable is a PHI version. (the "master" variable has storage strategy PHI)*/
private boolean isPhiVersion; private boolean isPhiVersion;
@ -33,13 +33,13 @@ public class Variable extends SymbolVariable {
/** If the variable is assigned to a specific "register", this contains the register. If null the variable has no allocation (yet). Constants are never assigned to registers. */ /** If the variable is assigned to a specific "register", this contains the register. If null the variable has no allocation (yet). Constants are never assigned to registers. */
private Registers.Register allocation; private Registers.Register allocation;
public Variable(String name, Scope scope, SymbolType type, String dataSegment, boolean isIntermediate, boolean isPhiVersion, boolean isPhiMaster) { public Variable(String name, Scope scope, SymbolType type, String dataSegment, StorageStrategy storageStrategy, boolean isIntermediate, boolean isPhiVersion, boolean isPhiMaster) {
super(name, scope, type, dataSegment); super(name, scope, type, storageStrategy, dataSegment);
this.isIntermediate = isIntermediate; this.isIntermediate = isIntermediate;
this.isPhiVersion = isPhiVersion; this.isPhiVersion = isPhiVersion;
this.isPhiMaster = isPhiMaster; this.isPhiMaster = isPhiMaster;
if(isPhiMaster) if(isPhiMaster)
this.nextVersionNumber = 0; this.nextPhiVersionNumber = 0;
} }
/** /**
@ -48,13 +48,12 @@ public class Variable extends SymbolVariable {
* @param version The version number * @param version The version number
*/ */
public Variable(Variable phiMaster, int version) { public Variable(Variable phiMaster, int version) {
super(phiMaster.getName()+"#"+version, phiMaster.getScope(), phiMaster.getType(), phiMaster.getDataSegment()); super(phiMaster.getName()+"#"+version, phiMaster.getScope(), phiMaster.getType(), StorageStrategy.PHI_VERSION, phiMaster.getDataSegment());
this.setDeclaredAlignment(phiMaster.getDeclaredAlignment()); this.setDeclaredAlignment(phiMaster.getDeclaredAlignment());
this.setDeclaredAsRegister(phiMaster.isDeclaredAsRegister()); this.setDeclaredAsRegister(phiMaster.isDeclaredAsRegister());
this.setDeclaredAsMemory(phiMaster.isDeclaredAsMemory()); this.setDeclaredAsMemory(phiMaster.isDeclaredAsMemory());
this.setDeclaredRegister(phiMaster.getDeclaredRegister()); this.setDeclaredRegister(phiMaster.getDeclaredRegister());
this.setDeclaredMemoryAddress(phiMaster.getDeclaredMemoryAddress()); this.setDeclaredMemoryAddress(phiMaster.getDeclaredMemoryAddress());
this.setStorageStrategy(phiMaster.getStorageStrategy());
this.setDeclaredVolatile(phiMaster.isDeclaredVolatile()); this.setDeclaredVolatile(phiMaster.isDeclaredVolatile());
this.setDeclaredExport(phiMaster.isDeclaredExport()); this.setDeclaredExport(phiMaster.isDeclaredExport());
this.setInferedVolatile(phiMaster.isInferedVolatile()); this.setInferedVolatile(phiMaster.isInferedVolatile());
@ -74,6 +73,14 @@ public class Variable extends SymbolVariable {
} }
public boolean isPhiMaster() { public boolean isPhiMaster() {
/*
if(isPhiMaster) {
if(!StorageStrategy.PHI_MASTER.equals(getStorageStrategy())) {
System.out.println("PHI master mismatch!");
};
}
return StorageStrategy.PHI_MASTER.equals(getStorageStrategy());
*/
return isPhiMaster; return isPhiMaster;
} }
@ -92,7 +99,7 @@ public class Variable extends SymbolVariable {
public Variable createVersion() { public Variable createVersion() {
if(!isPhiMaster) if(!isPhiMaster)
throw new InternalError("Cannot version non-PHI variable"); throw new InternalError("Cannot version non-PHI variable");
Variable version = new Variable(this, nextVersionNumber++); Variable version = new Variable(this, nextPhiVersionNumber++);
getScope().add(version); getScope().add(version);
return version; return version;
} }

View File

@ -260,9 +260,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
this.visitDeclTypes(ctx.declTypes()); this.visitDeclTypes(ctx.declTypes());
SymbolType type = declVarType; SymbolType type = declVarType;
List<Directive> directives = declVarDirectives; List<Directive> directives = declVarDirectives;
Variable param = new Variable(ctx.NAME().getText(), getCurrentScope(), type, currentDataSegment, false, false, true); Variable param = new Variable(ctx.NAME().getText(), getCurrentScope(), type, currentDataSegment, SymbolVariable.StorageStrategy.PHI_MASTER, false, false, true);
// Set initial storage strategy
param.setStorageStrategy(SymbolVariable.StorageStrategy.PHI_REGISTER);
// Add directives // Add directives
addDirectives(param, type, directives, new StatementSource(ctx)); addDirectives(param, type, directives, new StatementSource(ctx));
exitDeclTypes(); exitDeclTypes();
@ -619,13 +617,12 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
} catch(CompileError e) { } catch(CompileError e) {
throw new CompileError(e.getMessage(), new StatementSource(ctx)); throw new CompileError(e.getMessage(), new StatementSource(ctx));
} }
// Set initial storage strategy
lValue.setStorageStrategy(SymbolVariable.StorageStrategy.PHI_REGISTER);
// Add directives // Add directives
addDirectives(lValue, type, directives, new StatementSource(ctx)); addDirectives(lValue, type, directives, new StatementSource(ctx));
// Array / String variables are implicitly constant // Array / String variables are implicitly constant
if(type instanceof SymbolTypeArray || type.equals(SymbolType.STRING)) { if(type instanceof SymbolTypeArray || type.equals(SymbolType.STRING)) {
lValue.setDeclaredConstant(true); lValue.setDeclaredConstant(true);
lValue.setStorageStrategy(SymbolVariable.StorageStrategy.CONSTANT);
} }
if(lValue.isDeclaredConstant()) { if(lValue.isDeclaredConstant()) {
// Add comments to constant // Add comments to constant
@ -704,7 +701,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
} else if(directive instanceof DirectiveRegister) { } else if(directive instanceof DirectiveRegister) {
DirectiveRegister directiveRegister = (DirectiveRegister) directive; DirectiveRegister directiveRegister = (DirectiveRegister) directive;
lValue.setDeclaredAsRegister(true); lValue.setDeclaredAsRegister(true);
lValue.setStorageStrategy(SymbolVariable.StorageStrategy.PHI_REGISTER); lValue.setStorageStrategy(SymbolVariable.StorageStrategy.PHI_MASTER);
if(directiveRegister.name != null) { if(directiveRegister.name != null) {
// Ignore register directive without parameter (all variables are placed on ZP and attempted register uplift anyways) // Ignore register directive without parameter (all variables are placed on ZP and attempted register uplift anyways)
Registers.Register register = Registers.getRegister(directiveRegister.name); Registers.Register register = Registers.getRegister(directiveRegister.name);
@ -1206,8 +1203,6 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
} catch(CompileError e) { } catch(CompileError e) {
throw new CompileError(e.getMessage(), statementSource); throw new CompileError(e.getMessage(), statementSource);
} }
// Set initial storage strategy
lValue.setStorageStrategy(SymbolVariable.StorageStrategy.PHI_REGISTER);
// Add directives // Add directives
addDirectives(lValue, varType, varDirectives, statementSource); addDirectives(lValue, varType, varDirectives, statementSource);
} else { } else {

View File

@ -212,7 +212,7 @@ public class Pass1UnwindStructValues extends Pass1Base {
for(Variable member : structDefinition.getAllVariables(false)) { for(Variable member : structDefinition.getAllVariables(false)) {
Variable memberVariable; Variable memberVariable;
if(variable.getRef().isIntermediate()) { if(variable.getRef().isIntermediate()) {
memberVariable = scope.add(new Variable(variable.getLocalName() + "_" + member.getLocalName(), scope, member.getType(), variable.getDataSegment(), true, false, false)); memberVariable = scope.add(new Variable(variable.getLocalName() + "_" + member.getLocalName(), scope, member.getType(), variable.getDataSegment(), SymbolVariable.StorageStrategy.INTERMEDIATE, true, false, false));
} else { } else {
memberVariable = scope.addVariablePhiMaster(variable.getLocalName() + "_" + member.getLocalName(), member.getType(), variable.getDataSegment()); memberVariable = scope.addVariablePhiMaster(variable.getLocalName() + "_" + member.getLocalName(), member.getType(), variable.getDataSegment());
} }

View File

@ -4,6 +4,8 @@ import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.model.Program; import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.iterator.ProgramValue; import dk.camelot64.kickc.model.iterator.ProgramValue;
import dk.camelot64.kickc.model.iterator.ProgramValueIterator; import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
import dk.camelot64.kickc.model.symbols.SymbolVariable;
import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.model.values.ForwardVariableRef; import dk.camelot64.kickc.model.values.ForwardVariableRef;
import dk.camelot64.kickc.model.values.Value; import dk.camelot64.kickc.model.values.Value;
import dk.camelot64.kickc.model.values.VariableRef; import dk.camelot64.kickc.model.values.VariableRef;
@ -28,7 +30,8 @@ public class Pass2AssertRValues extends Pass2SsaAssertion {
} }
if(rValue instanceof VariableRef) { if(rValue instanceof VariableRef) {
VariableRef variableRef = (VariableRef) rValue; VariableRef variableRef = (VariableRef) rValue;
if(!variableRef.isIntermediate() && !variableRef.isVersion()) { Variable variable = getScope().getVariable(variableRef);
if(variable.getStorageStrategy().equals(SymbolVariable.StorageStrategy.PHI_MASTER)) {
throw new CompileError("No unversioned variable references allowed "+currentStmt.toString(getProgram(), false), currentStmt.getSource()); throw new CompileError("No unversioned variable references allowed "+currentStmt.toString(getProgram(), false), currentStmt.getSource());
} }
} }

View File

@ -11,10 +11,7 @@ import dk.camelot64.kickc.model.operators.Operators;
import dk.camelot64.kickc.model.statements.Statement; import dk.camelot64.kickc.model.statements.Statement;
import dk.camelot64.kickc.model.statements.StatementAssignment; import dk.camelot64.kickc.model.statements.StatementAssignment;
import dk.camelot64.kickc.model.statements.StatementPhiBlock; import dk.camelot64.kickc.model.statements.StatementPhiBlock;
import dk.camelot64.kickc.model.symbols.ConstantVar; import dk.camelot64.kickc.model.symbols.*;
import dk.camelot64.kickc.model.symbols.ProgramScope;
import dk.camelot64.kickc.model.symbols.Scope;
import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypeConversion; import dk.camelot64.kickc.model.types.SymbolTypeConversion;
import dk.camelot64.kickc.model.types.SymbolTypeInference; import dk.camelot64.kickc.model.types.SymbolTypeInference;
@ -88,7 +85,6 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
constantVar.setDeclaredRegister(variable.getDeclaredRegister()); constantVar.setDeclaredRegister(variable.getDeclaredRegister());
constantVar.setDeclaredAsMemory(variable.isDeclaredAsMemory()); constantVar.setDeclaredAsMemory(variable.isDeclaredAsMemory());
constantVar.setDeclaredMemoryAddress(variable.getDeclaredMemoryAddress()); constantVar.setDeclaredMemoryAddress(variable.getDeclaredMemoryAddress());
constantVar.setStorageStrategy(variable.getStorageStrategy());
constantVar.setDeclaredExport(variable.isDeclaredExport()); constantVar.setDeclaredExport(variable.isDeclaredExport());
if(variable.getComments().size() > 0) { if(variable.getComments().size() > 0) {
constantVar.setComments(variable.getComments()); constantVar.setComments(variable.getComments());