1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-04-07 06:37:31 +00:00

Moving Variable properties towards semantic names (nomodify, volatile, optimize, ...).

This commit is contained in:
jespergravgaard 2019-12-22 22:31:20 +01:00
parent 574f21b25a
commit 2fddd14a0a
17 changed files with 101 additions and 101 deletions

@ -143,7 +143,7 @@ public class LiveRangeEquivalenceClass {
public boolean hasVolatile(Program program) {
for(VariableRef varRef : variables) {
Variable variable = program.getScope().getVariable(varRef);
if(variable.isVolatile()) {
if(variable.isAnyVolatile()) {
return true;
}
}

@ -52,16 +52,16 @@ public class VariableBuilder {
*/
public Variable build() {
Variable variable = new Variable(varName, getKind(), type, scope, getMemoryArea(), dataSegment, arraySpec, null);
variable.setDeclaredConst(this.isConstant());
variable.setDeclaredVolatile(this.isVolatile());
variable.setDeclaredExport(this.isExport());
variable.setDeclaredAsRegister(this.isOptimize());
variable.setDeclaredRegister(this.getRegister());
if(variable.getDeclaredRegister() instanceof Registers.RegisterMainMem) {
((Registers.RegisterMainMem) variable.getDeclaredRegister()).setVariableRef(variable.getVariableRef());
variable.setNoModify(this.isConstant());
variable.setVolatile(this.isVolatile());
variable.setExport(this.isExport());
variable.setOptimize(this.isOptimize());
variable.setRegister(this.getRegister());
if(variable.getRegister() instanceof Registers.RegisterMainMem) {
((Registers.RegisterMainMem) variable.getRegister()).setVariableRef(variable.getVariableRef());
}
variable.setMemoryArea(this.getMemoryArea());
variable.setDeclaredAlignment(this.getAlignment());
variable.setMemoryAlignment(this.getAlignment());
scope.add(variable);
return variable;
}

@ -378,7 +378,7 @@ public abstract class Scope implements Symbol, Serializable {
if(symVar.isKindLoadStore()) {
res.append(" loadstore");
}
Registers.Register declRegister = symVar.getDeclaredRegister();
Registers.Register declRegister = symVar.getRegister();
if(declRegister != null) {
res.append(" !" + declRegister);
}

@ -58,26 +58,20 @@ public class Variable implements Symbol {
/** The type of the variable. VAR means the type is unknown, and has not been inferred yet. [ALL] */
private SymbolType type;
/** Specifies that the variable must be aligned in memory. Only allowed for arrays & strings. [Only Variables in memory and arrays] */
private Integer declaredAlignment;
/** Specifies the register the variable must be put into during execution. [Only variables] */
private Registers.Register declaredRegister;
/** Specifies that the variable is declared as const */
private boolean declaredConst;
/** Specifies that the variable is not allowed to be modified (const keyword) */
private boolean noModify;
/** Specifies that the variable must always live in memory to be available for any multi-threaded accees (eg. in interrupts). [Only Variables] */
private boolean declaredVolatile;
private boolean isVolatile;
/** Specifies that the variable must always live in memory to be available for any multi-threaded accees (eg. in interrupts). [Only variables] TODO: Remove this */
private boolean inferredVolatile;
/** Specifies that the variable must always be added to the output ASM even if it is never used anywhere. */
private boolean declaredExport;
private boolean export;
/** Specifies that the variable must live in a register if possible (CPU register or ZP-address). */
private boolean declaredAsRegister;
/** Specifies that the shoulw be optimized (register keyword). */
private boolean optimize;
/** Memory area used for storing the variable (if is is stored in memory). */
public enum MemoryArea {
@ -87,12 +81,18 @@ public class Variable implements Symbol {
/** The memory area where the variable lives (if stored in memory). [Only variables and arrays] */
private MemoryArea memoryArea;
/** Comments preceding the procedure in the source code. [ALL] */
private List<Comment> comments;
/** Specifies that the variable must be aligned in memory. Only allowed for arrays & strings. [Only Variables in memory and arrays] */
private Integer memoryAlignment;
/** The data segment to put the variable into (if it is allocated in memory). [Only variables stored in memory and arrays] */
private String dataSegment;
/** Specifies the hard-coded register the variable must be put into during execution. [Only variables] */
private Registers.Register register;
/** Comments preceding the procedure in the source code. [ALL] */
private List<Comment> comments;
/** The initial compiletime-value of the variable. Null if no initial value present. [Constants, Arrays, global/local-static loadstore-variables ] */
private ConstantValue initValue;
@ -182,12 +182,12 @@ public class Variable implements Symbol {
if(!phiMaster.isKindPhiMaster())
throw new InternalError("Cannot version non-PHI variable " + phiMaster.toString());
Variable version = new Variable(phiMaster.getName() + "#" + versionNum, Kind.PHI_VERSION, phiMaster.getType(), phiMaster.getScope(), phiMaster.getMemoryArea(), phiMaster.getDataSegment(), phiMaster.getArraySpec(), null);
version.setDeclaredAlignment(phiMaster.getDeclaredAlignment());
version.setDeclaredAsRegister(phiMaster.isDeclaredAsRegister());
version.setDeclaredConst(phiMaster.isDeclaredConst());
version.setDeclaredRegister(phiMaster.getDeclaredRegister());
version.setDeclaredVolatile(phiMaster.isDeclaredVolatile());
version.setDeclaredExport(phiMaster.isDeclaredExport());
version.setMemoryAlignment(phiMaster.getMemoryAlignment());
version.setOptimize(phiMaster.isOptimize());
version.setNoModify(phiMaster.isNoModify());
version.setRegister(phiMaster.getRegister());
version.setVolatile(phiMaster.isVolatile());
version.setExport(phiMaster.isExport());
version.setInferredVolatile(phiMaster.isInferredVolatile());
version.setComments(phiMaster.getComments());
return version;
@ -226,12 +226,12 @@ public class Variable implements Symbol {
*/
public static Variable createConstant(Variable variable, ConstantValue constantValue) {
Variable constVar = new Variable(variable.getName(), Kind.CONSTANT, variable.getType(), variable.getScope(), MemoryArea.MAIN_MEMORY, variable.getDataSegment(), variable.getArraySpec(), constantValue);
constVar.setDeclaredAlignment(variable.getDeclaredAlignment());
constVar.setDeclaredAsRegister(variable.isDeclaredAsRegister());
constVar.setDeclaredConst(variable.isDeclaredConst());
constVar.setDeclaredRegister(variable.getDeclaredRegister());
constVar.setDeclaredVolatile(variable.isDeclaredVolatile());
constVar.setDeclaredExport(variable.isDeclaredExport());
constVar.setMemoryAlignment(variable.getMemoryAlignment());
constVar.setOptimize(variable.isOptimize());
constVar.setNoModify(variable.isNoModify());
constVar.setRegister(variable.getRegister());
constVar.setVolatile(variable.isVolatile());
constVar.setExport(variable.isExport());
constVar.setInferredVolatile(variable.isInferredVolatile());
constVar.setComments(variable.getComments());
return constVar;
@ -246,12 +246,12 @@ public class Variable implements Symbol {
*/
public static Variable createCopy(String name, Scope scope, Variable original) {
Variable copy = new Variable(name, original.getKind(), original.getType(), scope, original.getMemoryArea(), original.getDataSegment(), original.getArraySpec(), original.getInitValue());
copy.setDeclaredAlignment(original.getDeclaredAlignment());
copy.setDeclaredAsRegister(original.isDeclaredAsRegister());
copy.setDeclaredConst(original.isDeclaredConst());
copy.setDeclaredVolatile(original.isDeclaredVolatile());
copy.setDeclaredExport(original.isDeclaredExport());
copy.setDeclaredRegister(original.getDeclaredRegister());
copy.setMemoryAlignment(original.getMemoryAlignment());
copy.setOptimize(original.isOptimize());
copy.setNoModify(original.isNoModify());
copy.setVolatile(original.isVolatile());
copy.setExport(original.isExport());
copy.setRegister(original.getRegister());
copy.setInferredVolatile(original.isInferredVolatile());
copy.setComments(original.getComments());
return copy;
@ -279,10 +279,10 @@ public class Variable implements Symbol {
// For others the kind is preserved from the member definition
memberVariable = new Variable(name, structVar.getKind(), memberDefinition.getType(), structVar.getScope(), memoryArea, structVar.getDataSegment(), memberDefinition.getArraySpec(), memberDefinition.getInitValue());
}
memberVariable.setDeclaredVolatile(structVar.isDeclaredVolatile());
memberVariable.setVolatile(structVar.isVolatile());
memberVariable.setInferredVolatile(structVar.isInferredVolatile());
memberVariable.setDeclaredConst(structVar.isDeclaredConst());
memberVariable.setDeclaredExport(structVar.isDeclaredExport());
memberVariable.setNoModify(structVar.isNoModify());
memberVariable.setExport(structVar.isExport());
return memberVariable;
}
@ -460,36 +460,36 @@ public class Variable implements Symbol {
}
}
public boolean isDeclaredConst() {
return declaredConst;
public boolean isNoModify() {
return noModify;
}
public void setDeclaredConst(boolean declaredConst) {
this.declaredConst = declaredConst;
public void setNoModify(boolean noModify) {
this.noModify = noModify;
}
public Integer getDeclaredAlignment() {
return declaredAlignment;
public Integer getMemoryAlignment() {
return memoryAlignment;
}
public void setDeclaredAlignment(Integer declaredAlignment) {
this.declaredAlignment = declaredAlignment;
public void setMemoryAlignment(Integer memoryAlignment) {
this.memoryAlignment = memoryAlignment;
}
public Registers.Register getDeclaredRegister() {
return declaredRegister;
public Registers.Register getRegister() {
return register;
}
public void setDeclaredRegister(Registers.Register declaredRegister) {
this.declaredRegister = declaredRegister;
public void setRegister(Registers.Register register) {
this.register = register;
}
public boolean isDeclaredVolatile() {
return declaredVolatile;
public boolean isVolatile() {
return isVolatile;
}
public void setDeclaredVolatile(boolean declaredVolatile) {
this.declaredVolatile = declaredVolatile;
public void setVolatile(boolean aVolatile) {
this.isVolatile = aVolatile;
}
public void setInferredVolatile(boolean inferredVolatile) {
@ -500,24 +500,24 @@ public class Variable implements Symbol {
return inferredVolatile;
}
public boolean isVolatile() {
return declaredVolatile || inferredVolatile;
public boolean isAnyVolatile() {
return isVolatile || inferredVolatile;
}
public boolean isDeclaredExport() {
return declaredExport;
public boolean isExport() {
return export;
}
public void setDeclaredExport(boolean declaredExport) {
this.declaredExport = declaredExport;
public void setExport(boolean export) {
this.export = export;
}
public boolean isDeclaredAsRegister() {
return declaredAsRegister;
public boolean isOptimize() {
return optimize;
}
public void setDeclaredAsRegister(boolean declaredAsRegister) {
this.declaredAsRegister = declaredAsRegister;
public void setOptimize(boolean optimize) {
this.optimize = optimize;
}
public MemoryArea getMemoryArea() {

@ -18,7 +18,7 @@ public class Pass1AssertNoConstParams extends Pass1Base {
public boolean step() {
for(Procedure procedure : getScope().getAllProcedures(true)) {
for(Variable parameter : procedure.getParameters()) {
if(parameter.isDeclaredConst()) {
if(parameter.isNoModify()) {
throw new CompileError("Error! Const parameters not supported "+parameter.getName()+" in "+ procedure.getFullName()+"()");
}
}

@ -37,7 +37,7 @@ public class Pass1EarlyConstantIdentification extends Pass1Base {
List<Statement> removeStmt = new ArrayList<>();
for(Variable variable : getProgram().getScope().getAllVariables(true)) {
SymbolVariableRef variableRef = variable.getRef();
if(!variable.isDeclaredConst() && !variable.isVolatile() && !variableRef.isIntermediate()) {
if(!variable.isNoModify() && !variable.isAnyVolatile() && !variableRef.isIntermediate()) {
if(variable.getScope() instanceof StructDefinition)
// Skip structs
continue;

@ -82,7 +82,7 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base {
private void versionAssignment(VariableRef lValueRef, ProgramValue programLValue, StatementSource source) {
Variable assignedVar = getScope().getVariable(lValueRef);
if(assignedVar.isKindPhiMaster()) {
if(assignedVar.isDeclaredConst())
if(assignedVar.isNoModify())
throw new InternalError("Error! Constants can not be versioned ", source);
Variable version = assignedVar.createVersion();
programLValue.set(version.getRef());
@ -157,7 +157,7 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base {
if(rValueVar.isKindPhiMaster()) {
// rValue needs versioning - look for version in statements
Variable rSymbol = rValueVar;
if(rSymbol.isDeclaredConst()) {
if(rSymbol.isNoModify()) {
// A constant - find the single created version
Scope scope = rSymbol.getScope();
Collection<Variable> versions = scope.getVersions(rSymbol);

@ -93,7 +93,7 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
String unversionedFullName = null;
for(VariableRef variableRef : aliasSet.getVars()) {
Variable variable = programScope.getVariable(variableRef);
if(variable.isVolatile() || variable.isKindLoadStore()) {
if(variable.isAnyVolatile() || variable.isKindLoadStore()) {
anyVolatile = true;
}
if(unversionedFullName == null) {
@ -420,7 +420,7 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
String name;
int score;
Variable variable = scope.getVariable(var);
if(variable.isDeclaredConst() || variable.isKindConstant()) {
if(variable.isNoModify() || variable.isKindConstant()) {
name = var.getFullNameUnversioned();
score = 100;
} else if(var.isVersion()) {

@ -137,7 +137,7 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
if(lValue instanceof VariableRef) {
VariableRef varRef = (VariableRef) lValue;
Variable var = getScope().getVariable(varRef);
if(var.isVolatile() || var.isKindLoadStore())
if(var.isAnyVolatile() || var.isKindLoadStore())
// Do not examine volatiles and non-versioned variables
continue;
ConstantValue constant = getConstant(assignment.getrValue2());
@ -153,7 +153,7 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
if(getConstant(phiRValue.getrValue()) != null) {
VariableRef varRef = phiVariable.getVariable();
Variable var = getScope().getVariable(varRef);
if(var.isVolatile() || var.isKindLoadStore())
if(var.isAnyVolatile() || var.isKindLoadStore())
// Do not examine volatiles and non-versioned variables
continue;
ConstantValue constant = getConstant(phiRValue.getrValue());
@ -167,7 +167,7 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
// Look for constants among non-versioned variables
for(Variable variable : getScope().getAllVariables(true)) {
if(variable.isVolatile() || !variable.isKindLoadStore())
if(variable.isAnyVolatile() || !variable.isKindLoadStore())
// Do not examine volatiles, non-constants or versioned variables
continue;
List<StatementLValue> assignments = getGraph().getAssignments(variable.getRef());

@ -97,7 +97,7 @@ public class Pass2DuplicateRValueIdentification extends Pass2SsaOptimization {
isVol.set(true);
if(programValue.get() instanceof VariableRef) {
Variable variable = getScope().getVariable((VariableRef) programValue.get());
if(variable.isVolatile())
if(variable.isAnyVolatile() )
isVol.set(true);
}
};

@ -38,7 +38,7 @@ public class Pass2IdenticalPhiElimination extends Pass2SsaOptimization {
for(StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) {
if(phiRValue.getrValue() instanceof SymbolVariableRef) {
Variable symbolVar = (Variable) getScope().getSymbol((SymbolVariableRef) phiRValue.getrValue());
if(symbolVar.getDeclaredRegister() != null) { //TODO: Handle register/memory/storage strategy differently!
if(symbolVar.getRegister() != null) { //TODO: Handle register/memory/storage strategy differently!
// Do not collapse PHI's for variables with declared registers (this prevents procedure parameters from being turned into constants)
identical = false;
break;

@ -142,7 +142,7 @@ public class Pass2LoopHeadConstantIdentification extends Pass2SsaOptimization {
}
if(programValue.get() instanceof VariableRef) {
Variable variable = getScope().getVariable((VariableRef) programValue.get());
if(variable.isVolatile())
if(variable.isAnyVolatile())
isVol.set(true);
}
}, null, null);

@ -477,7 +477,7 @@ public class Pass4CodeGeneration {
// Add any comments
generateComments(asm, constantVar.getComments());
// Add any alignment
Integer declaredAlignment = constantVar.getDeclaredAlignment();
Integer declaredAlignment = constantVar.getMemoryAlignment();
if(declaredAlignment != null) {
String alignment = AsmFormat.getAsmNumber(declaredAlignment);
asm.addDataAlignment(alignment);
@ -522,7 +522,7 @@ public class Pass4CodeGeneration {
// Add any comments
generateComments(asm, variable.getComments());
// Add any alignment
Integer declaredAlignment = variable.getDeclaredAlignment();
Integer declaredAlignment = variable.getMemoryAlignment();
if(declaredAlignment != null) {
String alignment = AsmFormat.getAsmNumber(declaredAlignment);
asm.addDataAlignment(alignment);

@ -33,7 +33,7 @@ public class Pass4LiveRangeEquivalenceClassesFinalize extends Pass2Base {
// Add all versions of volatile variables to the same equivalence class
for(Variable variable : getSymbols().getAllVariables(true)) {
if(variable.isKindPhiVersion() && variable.isVolatile()) {
if(variable.isKindPhiVersion() && variable.isAnyVolatile()) {
// Found a volatile non-versioned variable
for(Variable otherVariable : variable.getScope().getAllVariables(false)) {
if(otherVariable.isKindPhiVersion()) {

@ -28,15 +28,15 @@ public class Pass4RegisterUpliftPotentialInitialize extends Pass2Base {
int bytes = -1;
for(VariableRef varRef : equivalenceClass.getVariables()) {
Variable variable = getProgram().getScope().getVariable(varRef);
if(variable.getDeclaredRegister() != null) {
if(declaredRegister != null && !declaredRegister.equals(variable.getDeclaredRegister())) {
if(variable.getRegister() != null) {
if(declaredRegister != null && !declaredRegister.equals(variable.getRegister())) {
throw new CompileError("Equivalence class has variables with different declared registers \n" +
" - equivalence class: " + equivalenceClass.toString(true) + "\n" +
" - one register: " + declaredRegister.toString() + "\n" +
" - other register: " + variable.getDeclaredRegister().toString()
" - other register: " + variable.getRegister().toString()
);
}
declaredRegister = variable.getDeclaredRegister();
declaredRegister = variable.getRegister();
bytes = variable.getType().getSizeBytes();
}
}
@ -78,7 +78,7 @@ public class Pass4RegisterUpliftPotentialInitialize extends Pass2Base {
private boolean varVolatile(LiveRangeEquivalenceClass equivalenceClass) {
for(VariableRef variableRef : equivalenceClass.getVariables()) {
Variable variable = getSymbols().getVariable(variableRef);
if(variable.isVolatile() || variable.isKindLoadStore()) {
if(variable.isAnyVolatile() || variable.isKindLoadStore()) {
return true;
}
}

@ -37,8 +37,8 @@ public class Pass4RegistersFinalize extends Pass2Base {
}
// Add all ZP's declared hardcoded register for a live variable
for(Variable variable : getSymbols().getAllVariables(true)) {
if(variable.getDeclaredRegister() instanceof Registers.RegisterZpMem) {
int zp = ((Registers.RegisterZpMem) variable.getDeclaredRegister()).getZp();
if(variable.getRegister() instanceof Registers.RegisterZpMem) {
int zp = ((Registers.RegisterZpMem) variable.getRegister()).getZp();
int sizeBytes = variable.getType().getSizeBytes();
for(int i=0;i<sizeBytes; i++) {
if(!reservedZp.contains(zp+i))
@ -53,7 +53,7 @@ public class Pass4RegistersFinalize extends Pass2Base {
for(LiveRangeEquivalenceClass equivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) {
for(VariableRef variableRef : equivalenceClass.getVariables()) {
Variable variable = getProgram().getScope().getVariable(variableRef);
Registers.Register declaredRegister = variable.getDeclaredRegister(); //TODO: Handle register/memory/storage strategy differently!
Registers.Register declaredRegister = variable.getRegister(); //TODO: Handle register/memory/storage strategy differently!
Registers.Register register = declaredRegister;
if(declaredRegister !=null) {
if(declaredRegister instanceof Registers.RegisterZpMem) {

@ -44,10 +44,10 @@ public class PassNEliminateUnusedVars extends Pass2SsaOptimization {
if(variable == null) {
// Already deleted
eliminate = true;
} else if(!variable.isVolatile() && !variable.isDeclaredExport()) {
} else if(!variable.isAnyVolatile() && !variable.isExport()) {
// Not volatile
eliminate = true;
} else if(variable.isVolatile() && variable.getType() instanceof SymbolTypeStruct) {
} else if(variable.isAnyVolatile() && variable.getType() instanceof SymbolTypeStruct) {
if(assignment.getOperator()==null && assignment.getrValue2() instanceof StructUnwoundPlaceholder) {
eliminate = true;
}
@ -72,7 +72,7 @@ public class PassNEliminateUnusedVars extends Pass2SsaOptimization {
LValue lValue = call.getlValue();
if(lValue instanceof VariableRef && referenceInfos.isUnused((VariableRef) lValue)) {
Variable variable = getScope().getVariable((VariableRef) lValue);
if(!variable.isVolatile()) {
if(!variable.isAnyVolatile()) {
if(pass2 || getLog().isVerbosePass1CreateSsa()) {
getLog().append("Eliminating unused variable - keeping the call " + lValue.toString(getProgram()));
}
@ -88,7 +88,7 @@ public class PassNEliminateUnusedVars extends Pass2SsaOptimization {
LValue lValue = call.getlValue();
if(lValue instanceof VariableRef && referenceInfos.isUnused((VariableRef) lValue)) {
Variable variable = getScope().getVariable((VariableRef) lValue);
if(!variable.isVolatile()) {
if(!variable.isAnyVolatile()) {
if(pass2 || getLog().isVerbosePass1CreateSsa()) {
getLog().append("Eliminating unused variable - keeping the call " + lValue.toString(getProgram()));
}
@ -104,7 +104,7 @@ public class PassNEliminateUnusedVars extends Pass2SsaOptimization {
LValue lValue = call.getlValue();
if(lValue instanceof VariableRef && referenceInfos.isUnused((VariableRef) lValue)) {
Variable variable = getScope().getVariable((VariableRef) lValue);
if(!variable.isVolatile()) {
if(!variable.isAnyVolatile()) {
if(pass2 || getLog().isVerbosePass1CreateSsa()) {
getLog().append("Eliminating unused variable - keeping the call " + lValue.toString(getProgram()));
}
@ -123,7 +123,7 @@ public class PassNEliminateUnusedVars extends Pass2SsaOptimization {
VariableRef variableRef = phiVariable.getVariable();
if(referenceInfos.isUnused(variableRef)) {
Variable variable = getScope().getVariable(variableRef);
if(!variable.isVolatile()) {
if(!variable.isAnyVolatile()) {
if(pass2 || getLog().isVerbosePass1CreateSsa()) {
getLog().append("Eliminating unused variable - keeping the phi block " + variableRef.toString(getProgram()));
}
@ -143,7 +143,7 @@ public class PassNEliminateUnusedVars extends Pass2SsaOptimization {
for(Variable constant : allConstants) {
if(!(constant.getScope() instanceof EnumDefinition) && !(constant.getScope() instanceof StructDefinition)) {
if(referenceInfos.isUnused(constant.getRef())) {
if(constant.isDeclaredExport()) {
if(constant.isExport()) {
// Do not eliminate constants declared as export
continue;
}