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:
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.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));
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user