mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-02-07 05:30:43 +00:00
Working on storage strategy replacing booleans. #328
This commit is contained in:
parent
5d0fe66906
commit
97b83a929a
@ -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));
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
|
Loading…
x
Reference in New Issue
Block a user