1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-09-29 03:56:15 +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.symbols.Label;
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.types.SymbolType;
import dk.camelot64.kickc.model.values.ConstantInteger;
@ -80,12 +81,12 @@ public class AsmFragmentTemplate {
// Generate a dummy instance to find clobber & cycles
ProgramScope scope = new ProgramScope();
LinkedHashMap<String, Value> bindings = new LinkedHashMap<>();
Variable v1 = new Variable("$tmp1", scope, SymbolType.BYTE, null, true, false, false);
Variable v2 = new Variable("$tmp2", scope, SymbolType.BYTE, null, true, false, false);
Variable v3 = new Variable("$tmp3", scope, SymbolType.BYTE, null, true, false, false);
Variable v4 = new Variable("$tmp4", scope, SymbolType.BYTE, null, true, false, false);
Variable v5 = new Variable("$tmp5", scope, SymbolType.BYTE, null, true, false, false);
Variable v6 = new Variable("$tmp6", 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, SymbolVariable.StorageStrategy.PHI_VERSION, 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, SymbolVariable.StorageStrategy.PHI_VERSION, 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, SymbolVariable.StorageStrategy.PHI_VERSION, true, false, false);
v1.setAllocation(new Registers.RegisterZpByte(2));
v2.setAllocation(new Registers.RegisterZpByte(4));
v3.setAllocation(new Registers.RegisterZpByte(6));

View File

@ -12,7 +12,7 @@ public class ConstantVar extends SymbolVariable {
private ConstantValue value;
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;
}

View File

@ -100,12 +100,12 @@ public abstract class Scope implements Symbol, Serializable {
}
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() {
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) {
res.append(" " + asmName);
}
if(symVar.getStorageStrategy().equals(SymbolVariable.StorageStrategy.MEMORY)) {
if(SymbolVariable.StorageStrategy.MEMORY.equals(symVar.getStorageStrategy())) {
res.append(" memory");
}
Registers.Register declRegister = symVar.getDeclaredRegister();

View File

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

View File

@ -25,7 +25,7 @@ public class Variable extends SymbolVariable {
private boolean isPhiMaster;
/** 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)*/
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. */
private Registers.Register allocation;
public Variable(String name, Scope scope, SymbolType type, String dataSegment, boolean isIntermediate, boolean isPhiVersion, boolean isPhiMaster) {
super(name, scope, type, dataSegment);
public Variable(String name, Scope scope, SymbolType type, String dataSegment, StorageStrategy storageStrategy, boolean isIntermediate, boolean isPhiVersion, boolean isPhiMaster) {
super(name, scope, type, storageStrategy, dataSegment);
this.isIntermediate = isIntermediate;
this.isPhiVersion = isPhiVersion;
this.isPhiMaster = isPhiMaster;
if(isPhiMaster)
this.nextVersionNumber = 0;
this.nextPhiVersionNumber = 0;
}
/**
@ -48,13 +48,12 @@ public class Variable extends SymbolVariable {
* @param version The version number
*/
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.setDeclaredAsRegister(phiMaster.isDeclaredAsRegister());
this.setDeclaredAsMemory(phiMaster.isDeclaredAsMemory());
this.setDeclaredRegister(phiMaster.getDeclaredRegister());
this.setDeclaredMemoryAddress(phiMaster.getDeclaredMemoryAddress());
this.setStorageStrategy(phiMaster.getStorageStrategy());
this.setDeclaredVolatile(phiMaster.isDeclaredVolatile());
this.setDeclaredExport(phiMaster.isDeclaredExport());
this.setInferedVolatile(phiMaster.isInferedVolatile());
@ -74,6 +73,14 @@ public class Variable extends SymbolVariable {
}
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;
}
@ -92,7 +99,7 @@ public class Variable extends SymbolVariable {
public Variable createVersion() {
if(!isPhiMaster)
throw new InternalError("Cannot version non-PHI variable");
Variable version = new Variable(this, nextVersionNumber++);
Variable version = new Variable(this, nextPhiVersionNumber++);
getScope().add(version);
return version;
}

View File

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

View File

@ -212,7 +212,7 @@ public class Pass1UnwindStructValues extends Pass1Base {
for(Variable member : structDefinition.getAllVariables(false)) {
Variable memberVariable;
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 {
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.iterator.ProgramValue;
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.Value;
import dk.camelot64.kickc.model.values.VariableRef;
@ -28,7 +30,8 @@ public class Pass2AssertRValues extends Pass2SsaAssertion {
}
if(rValue instanceof VariableRef) {
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());
}
}

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.StatementAssignment;
import dk.camelot64.kickc.model.statements.StatementPhiBlock;
import dk.camelot64.kickc.model.symbols.ConstantVar;
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.symbols.*;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypeConversion;
import dk.camelot64.kickc.model.types.SymbolTypeInference;
@ -88,7 +85,6 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
constantVar.setDeclaredRegister(variable.getDeclaredRegister());
constantVar.setDeclaredAsMemory(variable.isDeclaredAsMemory());
constantVar.setDeclaredMemoryAddress(variable.getDeclaredMemoryAddress());
constantVar.setStorageStrategy(variable.getStorageStrategy());
constantVar.setDeclaredExport(variable.isDeclaredExport());
if(variable.getComments().size() > 0) {
constantVar.setComments(variable.getComments());