1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-07-03 20:29:34 +00:00

working on struct strategy

This commit is contained in:
jespergravgaard 2019-12-14 09:50:26 +01:00
parent 56fdce0d5c
commit 3b297ef85d
34 changed files with 283 additions and 222 deletions

View File

@ -1,8 +1,7 @@
package dk.camelot64.kickc.model;
import dk.camelot64.kickc.model.values.LValue;
import dk.camelot64.kickc.model.values.RValue;
import dk.camelot64.kickc.model.values.SymbolVariableRef;
import dk.camelot64.kickc.model.values.VariableRef;
import java.util.ArrayList;
import java.util.LinkedHashMap;
@ -68,8 +67,8 @@ public class StructUnwinding {
* @param memberName The member name
* @return The new variable
*/
public LValue getMemberUnwinding(String memberName) {
return (LValue) this.memberUnwinding.get(memberName);
public RValue getMemberUnwinding(String memberName) {
return this.memberUnwinding.get(memberName);
}
}
@ -84,11 +83,11 @@ public class StructUnwinding {
List<String> getMemberNames();
/**
* Get the LValue that a specific member was unwound to
* Get the RValue that a specific member was unwound to
*
* @param memberName The member name
* @return The unwinding of the member
*/
LValue getMemberUnwinding(String memberName);
RValue getMemberUnwinding(String memberName);
}
}

View File

@ -936,7 +936,7 @@ public interface ProgramValue {
@Override
public Value get() {
return variable.getArraySpec().getArraySize();
return variable.getArraySize();
}
@Override

View File

@ -2,7 +2,8 @@ package dk.camelot64.kickc.model.symbols;
import dk.camelot64.kickc.model.values.ConstantValue;
/** Specification of array properties of a variable.
/**
* Specification of array properties of a variable.
* The presence of this means the variable is an array.
* If the size of the array is fixed this will contain the size.
* */

View File

@ -116,7 +116,7 @@ public abstract class Scope implements Symbol, Serializable {
for(Symbol symbol : symbols.values()) {
if(symbol instanceof Variable) {
Variable variable = (Variable) symbol;
if(variable.isVariable() && variable.isKindPhiVersion() && variable.getVersionOf().equals(unversioned)) {
if(variable.isVariable() && variable.isKindPhiVersion() && variable.getPhiMaster().equals(unversioned)) {
versions.add(variable);
}
}
@ -365,6 +365,13 @@ public abstract class Scope implements Symbol, Serializable {
if(!onlyVars || symVar.isVariable()) {
// Output if not instructed to only output variables - or if it is a variable
res.append(symbol.toString(program));
if(symVar.isArray()) {
res.append("[");
if(symVar.getArraySize()!=null) {
res.append(symVar.getArraySize().toString(program));
}
res.append("] ");
}
if(symVar.getAsmName() != null && !symVar.getName().equals(symVar.getAsmName())) {
res.append(" " + symVar.getAsmName());
}

View File

@ -43,7 +43,7 @@ public class StructDefinition extends Scope {
if(structMember.equals(member)) {
break;
} else {
byteOffset += SymbolTypeStruct.getMemberSizeBytes(structMember.getType(), structMember.getArraySpec(), programScope);
byteOffset += SymbolTypeStruct.getMemberSizeBytes(structMember.getType(), structMember.getArraySize(), programScope);
}
}
return byteOffset;

View File

@ -6,6 +6,7 @@ import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.Registers;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypePointer;
import dk.camelot64.kickc.model.types.SymbolTypeStruct;
import dk.camelot64.kickc.model.values.ConstantRef;
import dk.camelot64.kickc.model.values.ConstantValue;
import dk.camelot64.kickc.model.values.SymbolVariableRef;
@ -15,7 +16,12 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/** A Variable symbol (can either be a runtime variable or a compile-time constant) */
/** A Variable symbol (can either be a runtime variable or a compile-time constant).
* <p>
* Array values are implemented as {@link Kind#CONSTANT}s with the array data in {@link #getConstantValue()} and the declared size in {@link #getArraySpec()}.
* Struct values are implemented as {@link Kind#LOAD_STORE}s with the initial data in {@link #getConstantValue()} and the strategy for accessing it in {@link #getStructStrategy()}.
* </p>
**/
public class Variable implements Symbol {
/**
@ -27,7 +33,7 @@ public class Variable implements Symbol {
* <li>PHI_VERSION variables are versions of a PHI-master. A PHI-version lives in memory or a register at runtime.</li>
* <li>INTERMEDIATE variables are created when expressions are broken into smaller statements. The type of intermediate variables must be inferred by the compiler. An intermediate variable lives in memory or a register at runtime.</li>
* <li>LOAD_STORE variables are accessed through load/store operations. They can have hardcoded memory addresses. A load/store-variable lives in memory or a register at runtime</li>
* <li>CONSTANT variables are compile-time constants. They do not live in memory at runtime. An array is a compile-time constant pointer. The array itself lives in memory but the pointer does not.
* <li>CONSTANT variables are compile-time constants. They do not live in memory at runtime. As a special case arrays are compile-time constants. The array itself lives in memory. The variable holding the array cannot be assigned and hence is constant.
* </ul>
**/
public enum Kind {
@ -73,6 +79,11 @@ public class Variable implements Symbol {
/** Specifies that the variable must live in a register if possible (CPU register or ZP-address). */
private boolean declaredAsRegister;
/** Memory area used for storing the variable (if is is stored in memory). */
public enum MemoryArea {
ZEROPAGE_MEMORY, MAIN_MEMORY
}
/** The memory area where the variable lives (if stored in memory). [Only variables and arrays] */
private MemoryArea memoryArea;
@ -88,17 +99,23 @@ public class Variable implements Symbol {
/** Non-null if the variable is an array. [Only constants that are arrays] */
private ArraySpec arraySpec;
/** Strategy for handling a struct variable during compilation. */
public enum StructStrategy {
/** The struct is stored in memory and accessed using OFFSET's */
CSTANDARD,
/** The struct is unwound and handled as if each member was a separate variable. */
UNWINDING
}
/** Non-null if the variable is a struct value. Strategy for how to handle the struct value. [Only constants that are structs] */
private StructStrategy structStrategy;
/** The number of the next version (only used for PHI masters) [Only PHI masters] */
private Integer nextPhiVersionNumber;
/** 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. [Only variables - not constants and not PHI masters] */
private Registers.Register allocation;
/** Memory area used for storing the variable (if is is stored in memory). */
public enum MemoryArea {
ZEROPAGE_MEMORY, MAIN_MEMORY
}
/**
* Create a variable (or constant)
*
@ -111,7 +128,7 @@ public class Variable implements Symbol {
* @param arraySpec The array specification of the variable (if it is an array)
* @param constantValue The constant value of the variable (if it is constant)
*/
private Variable(String name, Kind kind, SymbolType type, Scope scope, MemoryArea memoryArea, String dataSegment, ArraySpec arraySpec, ConstantValue constantValue) {
private Variable(String name, Kind kind, SymbolType type, Scope scope, MemoryArea memoryArea, String dataSegment, ArraySpec arraySpec, StructStrategy structStrategy, ConstantValue constantValue) {
this.name = name;
this.kind = kind;
if(Kind.PHI_MASTER.equals(kind))
@ -119,6 +136,7 @@ public class Variable implements Symbol {
this.type = type;
this.scope = scope;
this.arraySpec = arraySpec;
this.structStrategy = structStrategy;
this.constantValue = constantValue;
this.dataSegment = dataSegment;
this.memoryArea = memoryArea;
@ -135,7 +153,7 @@ public class Variable implements Symbol {
* @return The new intermediate variable
*/
public static Variable createIntermediate(String name, Scope scope, String dataSegment) {
return new Variable(name, Kind.INTERMEDIATE, SymbolType.VAR, scope, MemoryArea.ZEROPAGE_MEMORY, dataSegment, null, null);
return new Variable(name, Kind.INTERMEDIATE, SymbolType.VAR, scope, MemoryArea.ZEROPAGE_MEMORY, dataSegment, null, null, null);
}
/**
@ -149,7 +167,7 @@ public class Variable implements Symbol {
* @return The new PHI-master variable
*/
public static Variable createLoadStore(String name, SymbolType type, Scope scope, Variable.MemoryArea memoryArea, String dataSegment) {
return new Variable(name, Kind.LOAD_STORE, type, scope, memoryArea, dataSegment, null, null);
return new Variable(name, Kind.LOAD_STORE, type, scope, memoryArea, dataSegment, null, null, null);
}
/**
@ -163,7 +181,7 @@ public class Variable implements Symbol {
* @return The new PHI-master variable
*/
public static Variable createPhiMaster(String name, SymbolType type, Scope scope, Variable.MemoryArea memoryArea, String dataSegment) {
return new Variable(name, Kind.PHI_MASTER, type, scope, memoryArea, dataSegment, null, null);
return new Variable(name, Kind.PHI_MASTER, type, scope, memoryArea, dataSegment, null, null, null);
}
/**
@ -173,7 +191,9 @@ public class Variable implements Symbol {
* @param versionNum The version number
*/
public static Variable createPhiVersion(Variable phiMaster, int versionNum) {
Variable version = new Variable(phiMaster.getName() + "#" + versionNum, Kind.PHI_VERSION, phiMaster.getType(), phiMaster.getScope(), phiMaster.getMemoryArea(), phiMaster.getDataSegment(), phiMaster.getArraySpec(), null);
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(), phiMaster.getStructStrategy(), null);
version.setDeclaredAlignment(phiMaster.getDeclaredAlignment());
version.setDeclaredAsRegister(phiMaster.isDeclaredAsRegister());
version.setDeclaredConst(phiMaster.isDeclaredConst());
@ -185,27 +205,39 @@ public class Variable implements Symbol {
return version;
}
/**
* Creates a new PHI-version from a PHI-master
*
* @return The new version of the PHI master
*/
public Variable createVersion() {
Variable version = Variable.createPhiVersion(this, nextPhiVersionNumber++);
getScope().add(version);
return version;
}
/**
* Create a compile-time constant variable
*
* @param name The name
* @param type The type
* @param scope The scope
* @param value The constant value
* @param arraySpec The array specification (if an array)
* @param constantValue The constant value
* @param dataSegment The data segment (in main memory)
*/
public static Variable createConstant(String name, SymbolType type, Scope scope, ArraySpec arraySpec, ConstantValue value, String dataSegment) {
return new Variable(name, Kind.CONSTANT, type, scope, MemoryArea.MAIN_MEMORY, dataSegment, arraySpec, value);
public static Variable createConstant(String name, SymbolType type, Scope scope, ArraySpec arraySpec, ConstantValue constantValue, String dataSegment) {
return new Variable(name, Kind.CONSTANT, type, scope, MemoryArea.MAIN_MEMORY, dataSegment, arraySpec, null, constantValue);
}
/**
* Create a constant version of a variable. Used when a variable is determined to be constant during the compile.
*
* @param variable The variable to create a constant version of
* @param constVal The constant value
* @param constantValue The constant value
*/
public static Variable createConstant(Variable variable, ConstantValue constVal) {
Variable constVar = createConstant(variable.getName(), variable.getType(), variable.getScope(), variable.getArraySpec(), constVal, variable.getDataSegment());
public static Variable createConstant(Variable variable, ConstantValue constantValue) {
Variable constVar = createConstant(variable.getName(), variable.getType(), variable.getScope(), variable.getArraySpec(), constantValue, variable.getDataSegment());
constVar.setDeclaredAlignment(variable.getDeclaredAlignment());
constVar.setDeclaredAsRegister(variable.isDeclaredAsRegister());
constVar.setDeclaredConst(variable.isDeclaredConst());
@ -225,7 +257,7 @@ public class Variable implements Symbol {
* @param original The original variable
*/
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.getConstantValue());
Variable copy = new Variable(name, original.getKind(), original.getType(), scope, original.getMemoryArea(), original.getDataSegment(), original.getArraySpec(), original.getStructStrategy(), original.getConstantValue());
copy.setDeclaredAlignment(original.getDeclaredAlignment());
copy.setDeclaredAsRegister(original.isDeclaredAsRegister());
copy.setDeclaredConst(original.isDeclaredConst());
@ -239,15 +271,26 @@ public class Variable implements Symbol {
/**
* Create a variable representing a single member of a struct variable.
*
* @param structVar The variable that holds a struct value.
* @param memberDefinition The definition of the struct member
* @param isParameter True if the structVar is a parameter to a procedure
* @return The new unwound variable representing the member of the struct
*/
public static Variable createStructMemberUnwound(Variable structVar, Variable memberDefinition) {
public static Variable createStructMemberUnwound(Variable structVar, Variable memberDefinition, boolean isParameter) {
String name = structVar.getLocalName() + "_" + memberDefinition.getLocalName();
Variable.MemoryArea memoryArea = (memberDefinition.getType() instanceof SymbolTypePointer) ? Variable.MemoryArea.ZEROPAGE_MEMORY : structVar.getMemoryArea();
Variable memberVariable = new Variable(name, structVar.getKind(), memberDefinition.getType(), structVar.getScope(), memoryArea, structVar.getDataSegment(), null, null);
memberVariable.setArraySpec(memberDefinition.getArraySpec());
Variable memberVariable;
if(isParameter && memberDefinition.isArray()) {
// Array struct members are converted to pointers when unwound (use same kind as the struct variable)
memberVariable = new Variable(name, structVar.getKind(), memberDefinition.getType(), structVar.getScope(), memoryArea, structVar.getDataSegment(), null, null, null);
} else if(memberDefinition.isKindConstant()) {
// Constant members are unwound as constants
memberVariable = new Variable(name, Kind.CONSTANT, memberDefinition.getType(), structVar.getScope(), memoryArea, structVar.getDataSegment(), memberDefinition.getArraySpec(), memberDefinition.getStructStrategy(), memberDefinition.getConstantValue());
} else {
// 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.getStructStrategy(), memberDefinition.getConstantValue());
}
memberVariable.setDeclaredVolatile(structVar.isDeclaredVolatile());
memberVariable.setInferredVolatile(structVar.isInferredVolatile());
memberVariable.setDeclaredConst(structVar.isDeclaredConst());
@ -255,6 +298,19 @@ public class Variable implements Symbol {
return memberVariable;
}
/**
* If the variable is a PHI-version of a PHI-master variable this returns the PHI-master variable.
*
* @return The PHI-master variable. Null if this is not a PHI-version.
*/
public Variable getPhiMaster() {
if(!isKindPhiVersion())
throw new InternalError("Cannot get PHI-master for non-PHI-version variable " + this.toString());
String name = getName();
String versionOfName = name.substring(0, name.indexOf("#"));
return getScope().getVariable(versionOfName);
}
public Kind getKind() {
return kind;
}
@ -309,33 +365,22 @@ public class Variable implements Symbol {
}
/**
* Creates a new PHI-version from a PHI-master
*
* @return The new version of the PHI master
* Determines if the variable is an array
* @return True if the variable is an array.
*/
public Variable createVersion() {
if(!isKindPhiMaster())
throw new InternalError("Cannot version non-PHI variable " + this.toString());
Variable version = Variable.createPhiVersion(this, nextPhiVersionNumber++);
getScope().add(version);
return version;
public boolean isArray() {
return arraySpec != null;
}
/**
* If the variable is a version of a variable returns the original variable.
*
* @return The original variable. Null if this is not a version.
* If the variable is an array with a declared size this returns the size
* @return The size of the array if declared. Null if not an array or an array without a declared size.
*/
public Variable getVersionOf() {
if(!isKindPhiVersion())
throw new InternalError("Cannot get master for non-PHI version variable " + this.toString());
String name = getName();
String versionOfName = name.substring(0, name.indexOf("#"));
return getScope().getVariable(versionOfName);
}
public boolean isArray() {
return arraySpec != null;
public ConstantValue getArraySize() {
if(arraySpec!=null)
return arraySpec.getArraySize();
else
return null;
}
public ArraySpec getArraySpec() {
@ -346,6 +391,18 @@ public class Variable implements Symbol {
this.arraySpec = arraySpec;
}
public boolean isStruct() {
return type instanceof SymbolTypeStruct;
}
public StructStrategy getStructStrategy() {
return structStrategy;
}
public void setStructStrategy(StructStrategy structStrategy) {
this.structStrategy = structStrategy;
}
public Registers.Register getAllocation() {
return allocation;
}

View File

@ -1,11 +1,11 @@
package dk.camelot64.kickc.model.types;
import dk.camelot64.kickc.model.symbols.ArraySpec;
import dk.camelot64.kickc.model.symbols.ProgramScope;
import dk.camelot64.kickc.model.symbols.StructDefinition;
import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.model.values.ConstantInteger;
import dk.camelot64.kickc.model.values.ConstantLiteral;
import dk.camelot64.kickc.model.values.ConstantValue;
import java.util.Objects;
@ -55,16 +55,16 @@ public class SymbolTypeStruct implements SymbolType {
int sizeBytes = 0;
for(Variable member : structDefinition.getAllVars(false)) {
SymbolType memberType = member.getType();
int memberSize = getMemberSizeBytes(memberType, member.getArraySpec(), programScope);
int memberSize = getMemberSizeBytes(memberType, member.getArraySize(), programScope);
sizeBytes += memberSize;
}
return sizeBytes;
}
public static int getMemberSizeBytes(SymbolType memberType, ArraySpec arraySpec, ProgramScope programScope) {
if(arraySpec!=null && arraySpec.getArraySize() != null) {
public static int getMemberSizeBytes(SymbolType memberType, ConstantValue arraySize, ProgramScope programScope) {
if(arraySize!=null) {
if(programScope != null) {
ConstantLiteral sizeLiteral = arraySpec.getArraySize().calculateLiteral(programScope);
ConstantLiteral sizeLiteral = arraySize.calculateLiteral(programScope);
if(sizeLiteral instanceof ConstantInteger) {
return ((ConstantInteger) sizeLiteral).getInteger().intValue();
}

View File

@ -588,7 +588,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
Variable lValue;
if(kind.equals(Variable.Kind.PHI_MASTER)) {
lValue = Variable.createPhiMaster(varName, declVarType, getCurrentScope(), defaultMemoryArea, currentDataSegment);
} else if (kind.equals(Variable.Kind.LOAD_STORE)) {
} else if (kind.equals(Variable.Kind.LOAD_STORE)) {
lValue = Variable.createLoadStore(varName, declVarType, getCurrentScope(), defaultMemoryArea, currentDataSegment);
} else {
throw new InternalError("Unexpected variable kind! "+kind.name(), statementSource);

View File

@ -134,7 +134,7 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base {
private void updateBlockVersions(VariableRef lValue, Map<Variable, Variable> blockVersions) {
Variable variable = Pass1GenerateSingleStaticAssignmentForm.this.getScope().getVariable(lValue);
if(variable.isKindPhiVersion()) {
blockVersions.put(variable.getVersionOf(), variable);
blockVersions.put(variable.getPhiMaster(), variable);
}
}
@ -201,7 +201,7 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base {
if(phiVariable.isEmpty()) {
VariableRef phiLValVarRef = phiVariable.getVariable();
Variable versioned = getScope().getVariable(phiLValVarRef);
Variable unversioned = versioned.getVersionOf();
Variable unversioned = versioned.getPhiMaster();
List<ControlFlowBlock> predecessors = getPhiPredecessors(block, getProgram());
for(ControlFlowBlock predecessor : predecessors) {
LabelRef predecessorLabel = predecessor.getLabel();
@ -299,7 +299,7 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base {
if(lValueVar.isKindPhiVersion()) {
Variable versioned = lValueVar;
LabelRef label = block.getLabel();
Variable unversioned = versioned.getVersionOf();
Variable unversioned = versioned.getPhiMaster();
Map<Variable, Variable> blockMap = symbolMap.get(label);
if(blockMap == null) {
blockMap = new LinkedHashMap<>();

View File

@ -76,7 +76,7 @@ public class Pass1UnwindStructValues extends Pass1Base {
if(structMemberRef.getStruct() instanceof VariableRef) {
StructUnwinding.StructMemberUnwinding memberVariables = getStructMemberUnwinding(structMemberRef.getStruct(), currentStmt, stmtIt, currentBlock);
if(memberVariables != null && memberVariables != POSTPONE_UNWINDING) {
LValue structMemberVariable = memberVariables.getMemberUnwinding(structMemberRef.getMemberName());
RValue structMemberVariable = memberVariables.getMemberUnwinding(structMemberRef.getMemberName());
getLog().append("Replacing struct member reference " + structMemberRef.toString(getProgram()) + " with member unwinding reference " + structMemberVariable.toString(getProgram()));
programValue.set(structMemberVariable);
modified.set(true);
@ -171,7 +171,7 @@ public class Pass1UnwindStructValues extends Pass1Base {
StructUnwinding structUnwinding = getProgram().getStructUnwinding();
StructUnwinding.VariableUnwinding parameterUnwinding = structUnwinding.getVariableUnwinding(parameter.getRef());
for(String memberName : parameterUnwinding.getMemberNames()) {
VariableRef memberUnwinding = (VariableRef) parameterUnwinding.getMemberUnwinding(memberName);
SymbolVariableRef memberUnwinding = (SymbolVariableRef) parameterUnwinding.getMemberUnwinding(memberName);
unwoundParameterNames.add(memberUnwinding.getLocalName());
procedureUnwound = true;
}
@ -207,7 +207,8 @@ public class Pass1UnwindStructValues extends Pass1Base {
StructDefinition structDefinition = ((SymbolTypeStruct) variable.getType()).getStructDefinition(getProgram().getScope());
StructUnwinding.VariableUnwinding variableUnwinding = structUnwinding.createVariableUnwinding(variable.getRef());
for(Variable member : structDefinition.getAllVars(false)) {
Variable memberVariable = Variable.createStructMemberUnwound(variable, member);
boolean isParameter = scope instanceof Procedure && ((Procedure) scope).getParameters().contains(variable);
Variable memberVariable = Variable.createStructMemberUnwound(variable, member, isParameter);
scope.add(memberVariable);
variableUnwinding.setMemberUnwinding(member.getLocalName(), memberVariable.getRef());
getLog().append("Created struct value member variable " + memberVariable.toString(getProgram()));
@ -243,12 +244,12 @@ public class Pass1UnwindStructValues extends Pass1Base {
List<RValue> membersUnwound = new ArrayList<>();
stmtIt.previous();
for(String memberName : memberUnwinding.getMemberNames()) {
VariableRef memberVarRef = (VariableRef) memberUnwinding.getMemberUnwinding(memberName);
SymbolVariableRef memberVarRef = (SymbolVariableRef) memberUnwinding.getMemberUnwinding(memberName);
membersUnwound.add(memberVarRef);
Variable memberVar = getScope().getVariable(memberVarRef);
StatementSource statementSource = assignment.getSource();
RValue initValue = Pass0GenerateStatementSequence.createZeroValue(memberVar.getType(), statementSource);
Statement initStmt = new StatementAssignment(memberVarRef, initValue, statementSource, Comment.NO_COMMENTS);
Statement initStmt = new StatementAssignment((LValue) memberVarRef, initValue, statementSource, Comment.NO_COMMENTS);
stmtIt.add(initStmt);
getLog().append("Adding struct value member variable default initializer " + initStmt.toString(getProgram(), false));
}
@ -270,7 +271,7 @@ public class Pass1UnwindStructValues extends Pass1Base {
List<RValue> membersUnwound = new ArrayList<>();
int idx = 0;
for(String memberName : memberUnwinding.getMemberNames()) {
LValue memberLvalue = memberUnwinding.getMemberUnwinding(memberName);
LValue memberLvalue = (LValue) memberUnwinding.getMemberUnwinding(memberName);
membersUnwound.add(memberLvalue);
Statement initStmt = new StatementAssignment(memberLvalue, valueList.getList().get(idx++), assignment.getSource(), Comment.NO_COMMENTS);
stmtIt.add(initStmt);
@ -300,8 +301,8 @@ public class Pass1UnwindStructValues extends Pass1Base {
List<RValue> membersUnwound = new ArrayList<>();
stmtIt.previous();
for(String memberName : memberUnwinding.getMemberNames()) {
LValue assignedMemberVarRef = memberUnwinding.getMemberUnwinding(memberName);
LValue sourceMemberVarRef = sourceMemberUnwinding.getMemberUnwinding(memberName);
LValue assignedMemberVarRef = (LValue) memberUnwinding.getMemberUnwinding(memberName);
RValue sourceMemberVarRef = sourceMemberUnwinding.getMemberUnwinding(memberName);
membersUnwound.add(assignedMemberVarRef);
Statement copyStmt = new StatementAssignment(assignedMemberVarRef, sourceMemberVarRef, assignment.getSource(), Comment.NO_COMMENTS);
stmtIt.add(copyStmt);

View File

@ -57,7 +57,7 @@ public class Pass2ArrayInStructInlining extends Pass2SsaOptimization {
if(programValue instanceof ProgramValue.ProgramValueConstantStructMember) {
SymbolVariableRef memberRef = ((ProgramValue.ProgramValueConstantStructMember) programValue).getMemberRef();
Variable structMemberVar = getScope().getVar(memberRef);
if(structMemberVar.isArray() && structMemberVar.getArraySpec().getArraySize() != null) {
if(structMemberVar.isArray() && structMemberVar.getArraySize() != null) {
if(value instanceof ConstantValue) {
ConstantValue constantValue = (ConstantValue) value;
if(constantValue.getType(getProgram().getScope()).equals(SymbolType.STRING)) {

View File

@ -22,8 +22,8 @@ public class Pass3AssertArrayLengths extends Pass2SsaAssertion {
Collection<Variable> allConstants = getScope().getAllConstants(true);
for(Variable constantVar : allConstants) {
SymbolType constantType = constantVar.getType();
if(constantVar.isArray() && constantVar.getArraySpec().getArraySize() != null) {
ConstantValue declaredSize = constantVar.getArraySpec().getArraySize();
if(constantVar.isArray() && constantVar.getArraySize() != null) {
ConstantValue declaredSize = constantVar.getArraySize();
ConstantLiteral declaredSizeVal = declaredSize.calculateLiteral(getScope());
if(!(declaredSizeVal instanceof ConstantInteger)) {
throw new CompileError("Error! Array declared size is not integer " + constantType.toString());

View File

@ -50,7 +50,7 @@ public class Pass3PhiLifting {
Variable newVar;
if(phiVariable.getVariable().isVersion()) {
Variable lValVar = program.getScope().getVariable(phiVariable.getVariable());
newVar = lValVar.getVersionOf().createVersion();
newVar = lValVar.getPhiMaster().createVersion();
} else {
Variable lValVar = program.getScope().getVariable(phiVariable.getVariable());
newVar = lValVar.getScope().addVariableIntermediate();

View File

@ -37,7 +37,7 @@ public class Pass4LiveRangeEquivalenceClassesFinalize extends Pass2Base {
// Found a volatile non-versioned variable
for(Variable otherVariable : variable.getScope().getAllVariables(false)) {
if(otherVariable.isKindPhiVersion()) {
if((otherVariable).getVersionOf().equals((variable).getVersionOf())) {
if((otherVariable).getPhiMaster().equals((variable).getPhiMaster())) {
// They share the same main variable
LiveRangeEquivalenceClass varEC = liveRangeEquivalenceClassSet.getOrCreateEquivalenceClass((VariableRef) variable.getRef());
LiveRangeEquivalenceClass otherEC = liveRangeEquivalenceClassSet.getOrCreateEquivalenceClass((VariableRef) otherVariable.getRef());

View File

@ -72,8 +72,8 @@ public class PassNSizeOfSimplification extends Pass2SsaOptimization {
SymbolType symbolType = constant.getType();
if(constant.isArray() && symbolType instanceof SymbolTypePointer) {
SymbolTypePointer arrayType = (SymbolTypePointer) symbolType;
ConstantValue arraySize = constant.getArraySpec().getArraySize();
if(arraySize instanceof ConstantValue) {
ConstantValue arraySize = constant.getArraySize();
if(arraySize!=null) {
getLog().append("Resolving array sizeof() " + unary.toString(getProgram()));
ConstantRef sizeOfConstantVar = OperatorSizeOf.getSizeOfConstantVar(getScope(), arrayType.getElementType());
programValue.set(new ConstantBinary((ConstantValue) arraySize, Operators.MULTIPLY, sizeOfConstantVar));

View File

@ -40,7 +40,7 @@ public class PassNStructPointerRewriting extends Pass2SsaOptimization {
SymbolType memberType = SymbolTypeInference.inferType(getScope(), structMemberRef);
Variable memberVar = structDefinition.getMember(structMemberRef.getMemberName());
getLog().append("Rewriting struct pointer member access " + programValue.get().toString(getProgram()));
if(memberVar.isArray() && memberVar.getArraySpec().getArraySize()!=null) {
if(memberVar.isArray() && memberVar.getArraySize()!=null) {
// Cast struct pointer to the type of the member
CastValue structTypedPointer = new CastValue(memberType, structPointer);
// Create temporary variable to hold pointer to member ($1)
@ -80,7 +80,7 @@ public class PassNStructPointerRewriting extends Pass2SsaOptimization {
SymbolType memberType = SymbolTypeInference.inferType(getScope(), structMemberRef);
Variable memberVar = structDefinition.getMember(structMemberRef.getMemberName());
getLog().append("Rewriting struct pointer member access " + programValue.get().toString(getProgram()));
if(memberVar.isArray() && memberVar.getArraySpec().getArraySize()!=null) {
if(memberVar.isArray() && memberVar.getArraySize()!=null) {
// Cast struct pointer to the type of the member
CastValue structTypedPointer = new CastValue(memberType, structPointer);
// Create temporary variable to hold pointer to member ($1)

View File

@ -176,7 +176,7 @@ public class Unroller {
if(origVarRef.isIntermediate()) {
newVarRef = scope.addVariableIntermediate().getRef();
} else {
newVarRef = (origVar).getVersionOf().createVersion().getRef();
newVarRef = (origVar).getPhiMaster().createVersion().getRef();
}
return newVarRef;
}
@ -234,7 +234,7 @@ public class Unroller {
newVar = Variable.createCopy(name, scope, definedVar);
scope.add(newVar);
} else if(definedVarRef.isVersion()) {
newVar = (definedVar).getVersionOf().createVersion();
newVar = (definedVar).getPhiMaster().createVersion();
} else {
throw new RuntimeException("Error! Variable is not versioned or intermediate " + definedVar.toString(program));
}

View File

@ -1029,12 +1029,17 @@ public class TestPrograms {
@Test
public void testStruct12() throws IOException, URISyntaxException {
compileAndCompare("struct-12");
compileAndCompare("struct-12", log());
}
@Test
public void testStruct11b() throws IOException, URISyntaxException {
compileAndCompare("struct-11b", log());
}
@Test
public void testStruct11() throws IOException, URISyntaxException {
compileAndCompare("struct-11");
compileAndCompare("struct-11", log());
}
@Test
@ -1089,7 +1094,7 @@ public class TestPrograms {
@Test
public void testStruct0() throws IOException, URISyntaxException {
compileAndCompare("struct-0");
compileAndCompare("struct-0", log());
}
@Test

View File

@ -1,24 +1,30 @@
// Example of a struct containing an array
import "stdlib"
import "print"
// Works because the struct is only handled as a value
struct Person {
unsigned long id;
char[3] initials;
char id;
char[64] name;
};
struct Person jesper = { 111172, "jg" };
struct Person henry = { 280173, "hg" };
struct Person jesper = { 4, "jesper" };
struct Person henriette = { 7, "henriette" };
void main() {
print_person(jesper);
print_person(henry);
print_person(henriette);
}
const char* SCREEN = 0x0400;
char idx = 0;
char[] DIGIT = "0123456789";
void print_person(struct Person person) {
print_dword_decimal(person.id);
print_char(' ');
print_str(person.initials);
print_ln();
}
SCREEN[idx++] = DIGIT[person.id];
SCREEN[idx++] = ' ';
for(byte i=0; person.name[i]; i++)
SCREEN[idx++] = person.name[i];
SCREEN[idx++] = ' ';
}

View File

@ -1,24 +1,21 @@
// Example of a struct containing an array
import "stdlib"
import "print"
unsigned long jesper_id = 111172;
char[64] jesper_initials = "jg";
struct Person {
unsigned long id;
char[3] initials;
};
struct Person jesper = { 111172, "jg" };
struct Person henry = { 280173, "hg" };
unsigned long henry_id = 280173;
char[64] henry_initials = "hg";
void main() {
print_person(jesper);
print_person(henry);
print_person(jesper_id, jesper_initials);
print_person(henry_id, henry_initials);
}
void print_person(struct Person person) {
print_dword_decimal(person.id);
print_char(' ');
print_str(person.initials);
print_ln();
const char* SCREEN = 0x0400;
char idx = 0;
void print_person(unsigned long person_id, char* person_initials) {
for(byte i=0; person_initials[i]; i++)
SCREEN[idx++] = person_initials[i];
SCREEN[idx++] = ' ';
}

View File

@ -7,14 +7,10 @@ struct Person {
};
void main() {
struct Person jesper;
jesper.id = 4;
jesper.name = "jesper";
struct Person jesper = { 4, "jesper" };
print_person(jesper);
struct Person henriette;
henriette.id = 7;
henriette.name = "henriette";
struct Person henriette = { 7, "henriette" };
print_person(henriette);
}

View File

@ -1,7 +1,7 @@
@begin: scope:[] from
[0] (byte) bar_thing1 ← (byte) 'a'
[1] (byte) bar_thing2 ← (byte) 'b'
[2] (byte*) bar_thing3 ← (const string) $0
[2] (const byte*) bar_thing3 ← (const string) $0
to:@1
@1: scope:[] from @begin
[3] phi()

View File

@ -3,11 +3,11 @@ Fixing struct type size struct foo to 14
Setting inferred volatile on symbol affected by address-of (struct foo*) main::barp ← &(struct foo) bar
Created struct value member variable (byte) bar_thing1
Created struct value member variable (byte) bar_thing2
Created struct value member variable (byte*) bar_thing3
Created struct value member variable (const byte*) bar_thing3
Converted struct value to member variables (struct foo) bar
Adding struct value list initializer (byte) bar_thing1 ← (byte) 'a'
Adding struct value list initializer (byte) bar_thing2 ← (byte) 'b'
Adding struct value list initializer (byte*) bar_thing3 ← (string) "qwe"
Adding struct value list initializer (const byte*) bar_thing3 ← (string) "qwe"
Rewriting struct pointer member access *((struct foo*) main::barp).thing1
Rewriting struct pointer member access *((struct foo*) main::barp).thing2
Rewriting struct pointer member access *((struct foo*) main::barp).thing3
@ -18,8 +18,8 @@ CONTROL FLOW GRAPH SSA
@begin: scope:[] from
(byte) bar_thing1 ← (byte) 'a'
(byte) bar_thing2 ← (byte) 'b'
(byte*) bar_thing3 ← (const string) $0
(struct foo) bar ← struct-unwound {(byte) bar_thing1, (byte) bar_thing2, (byte*) bar_thing3}
(const byte*) bar_thing3 ← (const string) $0
(struct foo) bar ← struct-unwound {(byte) bar_thing1, (byte) bar_thing2, (const byte*) bar_thing3}
to:@1
(void()) main()
@ -65,7 +65,7 @@ SYMBOL TABLE SSA
(struct foo) bar loadstore
(byte) bar_thing1 loadstore
(byte) bar_thing2 loadstore
(byte*) bar_thing3 loadstore
(const byte*) bar_thing3 loadstore
(byte) foo::thing1
(byte) foo::thing2
(const byte*) foo::thing3 = { fill( $c, 0) }
@ -117,7 +117,7 @@ Resolved ranged comparison value [18] if(main::j#1!=rangelast(0,$b)) goto main::
Simplifying expression containing zero (byte*)main::barp in
Simplifying expression containing zero main::SCREEN in [6] *((const byte*) main::SCREEN + (const byte) main::i#0) ← *((const byte*) main::$1)
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused variable (struct foo) bar and assignment [3] (struct foo) bar ← struct-unwound {(byte) bar_thing1, (byte) bar_thing2, (byte*) bar_thing3}
Eliminating unused variable (struct foo) bar and assignment [3] (struct foo) bar ← struct-unwound {(byte) bar_thing1, (byte) bar_thing2, (const byte*) bar_thing3}
Eliminating unused constant (const byte) OFFSET_STRUCT_FOO_THING1
Successful SSA optimization PassNEliminateUnusedVars
Adding number conversion cast (unumber) $c in if((byte) main::j#1!=(number) $c) goto main::@1
@ -173,7 +173,7 @@ FINAL CONTROL FLOW GRAPH
@begin: scope:[] from
[0] (byte) bar_thing1 ← (byte) 'a'
[1] (byte) bar_thing2 ← (byte) 'b'
[2] (byte*) bar_thing3 ← (const string) $0
[2] (const byte*) bar_thing3 ← (const string) $0
to:@1
@1: scope:[] from @begin
[3] phi()
@ -203,7 +203,7 @@ main::@return: scope:[main] from main::@1
VARIABLE REGISTER WEIGHTS
(byte) bar_thing1 loadstore 20.0
(byte) bar_thing2 loadstore 20.0
(byte*) bar_thing3 loadstore 20.0
(const byte*) bar_thing3 loadstore 20.0
(byte) foo::thing1
(byte) foo::thing2
(void()) main()
@ -253,7 +253,7 @@ __bbegin:
// [1] (byte) bar_thing2 ← (byte) 'b' -- vbum1=vbuc1
lda #'b'
sta bar_thing2
// [2] (byte*) bar_thing3 ← (const string) $0 -- pbuz1=pbuc1
// [2] (const byte*) bar_thing3 ← (const string) $0 -- pbuz1=pbuc1
lda #<__0
sta.z bar_thing3
lda #>__0
@ -326,7 +326,7 @@ main: {
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] (byte) bar_thing1 ← (byte) 'a' [ ] ( [ ] ) always clobbers reg byte a
Statement [1] (byte) bar_thing2 ← (byte) 'b' [ ] ( [ ] ) always clobbers reg byte a
Statement [2] (byte*) bar_thing3 ← (const string) $0 [ ] ( [ ] ) always clobbers reg byte a
Statement [2] (const byte*) bar_thing3 ← (const string) $0 [ ] ( [ ] ) always clobbers reg byte a
Statement [6] *((const byte*) main::SCREEN) ← *((byte*)(const struct foo*) main::barp) [ ] ( main:4 [ ] ) always clobbers reg byte a
Statement [7] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING2) [ ] ( main:4 [ ] ) always clobbers reg byte a
Statement [9] *((const byte*) main::SCREEN + (byte) main::i#4) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING3 + (byte) main::j#2) [ main::j#2 main::i#4 ] ( main:4 [ main::j#2 main::i#4 ] ) always clobbers reg byte a
@ -334,7 +334,7 @@ Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::j
Removing always clobbered register reg byte a as potential for zp[1]:3 [ main::i#4 main::i#3 ]
Statement [0] (byte) bar_thing1 ← (byte) 'a' [ ] ( [ ] ) always clobbers reg byte a
Statement [1] (byte) bar_thing2 ← (byte) 'b' [ ] ( [ ] ) always clobbers reg byte a
Statement [2] (byte*) bar_thing3 ← (const string) $0 [ ] ( [ ] ) always clobbers reg byte a
Statement [2] (const byte*) bar_thing3 ← (const string) $0 [ ] ( [ ] ) always clobbers reg byte a
Statement [6] *((const byte*) main::SCREEN) ← *((byte*)(const struct foo*) main::barp) [ ] ( main:4 [ ] ) always clobbers reg byte a
Statement [7] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING2) [ ] ( main:4 [ ] ) always clobbers reg byte a
Statement [9] *((const byte*) main::SCREEN + (byte) main::i#4) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING3 + (byte) main::j#2) [ main::j#2 main::i#4 ] ( main:4 [ main::j#2 main::i#4 ] ) always clobbers reg byte a
@ -378,7 +378,7 @@ __bbegin:
// [1] (byte) bar_thing2 ← (byte) 'b' -- vbum1=vbuc1
lda #'b'
sta bar_thing2
// [2] (byte*) bar_thing3 ← (const string) $0 -- pbuz1=pbuc1
// [2] (const byte*) bar_thing3 ← (const string) $0 -- pbuz1=pbuc1
lda #<__0
sta.z bar_thing3
lda #>__0
@ -471,7 +471,7 @@ FINAL SYMBOL TABLE
(const byte) OFFSET_STRUCT_FOO_THING3 = (byte) 2
(byte) bar_thing1 loadstore mem[1] 20.0
(byte) bar_thing2 loadstore mem[1] 20.0
(byte*) bar_thing3 loadstore zp[2]:2 20.0
(const byte*) bar_thing3 loadstore zp[2]:2 20.0
(byte) foo::thing1
(byte) foo::thing2
(const byte*) foo::thing3 = { fill( $c, 0) }
@ -517,7 +517,7 @@ __bbegin:
// [1] (byte) bar_thing2 ← (byte) 'b' -- vbum1=vbuc1
lda #'b'
sta bar_thing2
// [2] (byte*) bar_thing3 ← (const string) $0 -- pbuz1=pbuc1
// [2] (const byte*) bar_thing3 ← (const string) $0 -- pbuz1=pbuc1
lda #<__0
sta.z bar_thing3
lda #>__0

View File

@ -6,7 +6,7 @@
(const byte) OFFSET_STRUCT_FOO_THING3 = (byte) 2
(byte) bar_thing1 loadstore mem[1] 20.0
(byte) bar_thing2 loadstore mem[1] 20.0
(byte*) bar_thing3 loadstore zp[2]:2 20.0
(const byte*) bar_thing3 loadstore zp[2]:2 20.0
(byte) foo::thing1
(byte) foo::thing2
(const byte*) foo::thing3 = { fill( $c, 0) }

View File

@ -21,7 +21,7 @@ main::@return: scope:[main] from main::@1
[8] return
to:@return
(void()) print_person((dword) print_person::person_id , (byte*) print_person::person_initials)
(void()) print_person((dword) print_person::person_id , (const byte*) print_person::person_initials)
print_person: scope:[print_person] from main main::@1
[9] (byte*) print_line_cursor#20 ← phi( main/(byte*) 1024 main::@1/(byte*) print_line_cursor#1 )
[9] (byte*) print_person::person_initials#2 ← phi( main/(const byte*) jesper_initials main::@1/(const byte*) henry_initials )

View File

@ -7,23 +7,23 @@ Fixing pointer addition (word*~) bsearch16u::$1 ← (word*) bsearch16u::items -
Fixing pointer array-indexing *((word*) utoa::digit_values + (byte) utoa::digit)
Fixing pointer array-indexing *((dword*) ultoa::digit_values + (byte) ultoa::digit)
Created struct value member variable (dword) jesper_id
Created struct value member variable (byte*) jesper_initials
Created struct value member variable (const byte*) jesper_initials
Converted struct value to member variables (struct Person) jesper
Created struct value member variable (dword) henry_id
Created struct value member variable (byte*) henry_initials
Created struct value member variable (const byte*) henry_initials
Converted struct value to member variables (struct Person) henry
Created struct value member variable (dword) print_person::person_id
Created struct value member variable (byte*) print_person::person_initials
Created struct value member variable (const byte*) print_person::person_initials
Converted struct value to member variables (struct Person) print_person::person
Converted procedure struct value parameter to member unwinding (void()) print_person((dword) print_person::person_id , (byte*) print_person::person_initials)
Converted procedure struct value parameter to member unwinding (void()) print_person((dword) print_person::person_id , (const byte*) print_person::person_initials)
Adding struct value list initializer (dword) jesper_id ← (number) $1b244
Adding struct value list initializer (byte*) jesper_initials ← (string) "jg"
Adding struct value list initializer (const byte*) jesper_initials ← (string) "jg"
Adding struct value list initializer (dword) henry_id ← (number) $4466d
Adding struct value list initializer (byte*) henry_initials ← (string) "hg"
Converted procedure struct value parameter to member unwinding in call (void~) main::$0 ← call print_person (dword) jesper_id (byte*) jesper_initials
Converted procedure struct value parameter to member unwinding in call (void~) main::$1 ← call print_person (dword) henry_id (byte*) henry_initials
Adding struct value list initializer (const byte*) henry_initials ← (string) "hg"
Converted procedure struct value parameter to member unwinding in call (void~) main::$0 ← call print_person (dword) jesper_id (const byte*) jesper_initials
Converted procedure struct value parameter to member unwinding in call (void~) main::$1 ← call print_person (dword) henry_id (const byte*) henry_initials
Replacing struct member reference (struct Person) print_person::person.id with member unwinding reference (dword) print_person::person_id
Replacing struct member reference (struct Person) print_person::person.initials with member unwinding reference (byte*) print_person::person_initials
Replacing struct member reference (struct Person) print_person::person.initials with member unwinding reference (const byte*) print_person::person_initials
Warning! Adding boolean cast to non-boolean condition *((byte*) strcpy::src)
Warning! Adding boolean cast to non-boolean condition *((byte*) print_str_lines::str)
Warning! Adding boolean cast to non-boolean condition (byte) print_str_lines::ch
@ -32,9 +32,9 @@ Warning! Adding boolean cast to non-boolean condition *((byte*) print_str_at::st
Warning! Adding boolean cast to non-boolean sub-expression (byte) print_str_lines::ch
Identified constant variable (byte*) HEAP_TOP
Identified constant variable (dword) jesper_id
Identified constant variable (byte*) jesper_initials
Identified constant variable (const byte*) jesper_initials
Identified constant variable (dword) henry_id
Identified constant variable (byte*) henry_initials
Identified constant variable (const byte*) henry_initials
Culled Empty Block (label) @1
Culled Empty Block (label) @2
Culled Empty Block (label) @3
@ -396,7 +396,7 @@ main::@return: scope:[main] from main::@2
return
to:@return
(void()) print_person((dword) print_person::person_id , (byte*) print_person::person_initials)
(void()) print_person((dword) print_person::person_id , (const byte*) print_person::person_initials)
print_person: scope:[print_person] from main main::@1
(byte*) print_line_cursor#24 ← phi( main/(byte*) print_line_cursor#19 main::@1/(byte*) print_line_cursor#3 )
(byte*) print_person::person_initials#4 ← phi( main/(byte*) print_person::person_initials#0 main::@1/(byte*) print_person::person_initials#1 )
@ -572,7 +572,7 @@ SYMBOL TABLE SSA
(label) print_ln::@1
(label) print_ln::@2
(label) print_ln::@return
(void()) print_person((dword) print_person::person_id , (byte*) print_person::person_initials)
(void()) print_person((dword) print_person::person_id , (const byte*) print_person::person_initials)
(label) print_person::@1
(label) print_person::@2
(label) print_person::@3
@ -583,7 +583,7 @@ SYMBOL TABLE SSA
(dword) print_person::person_id#0
(dword) print_person::person_id#1
(dword) print_person::person_id#2
(byte*) print_person::person_initials
(const byte*) print_person::person_initials
(byte*) print_person::person_initials#0
(byte*) print_person::person_initials#1
(byte*) print_person::person_initials#2
@ -1172,7 +1172,7 @@ main::@return: scope:[main] from main::@1
[8] return
to:@return
(void()) print_person((dword) print_person::person_id , (byte*) print_person::person_initials)
(void()) print_person((dword) print_person::person_id , (const byte*) print_person::person_initials)
print_person: scope:[print_person] from main main::@1
[9] (byte*) print_line_cursor#20 ← phi( main/(byte*) 1024 main::@1/(byte*) print_line_cursor#1 )
[9] (byte*) print_person::person_initials#2 ← phi( main/(const byte*) jesper_initials main::@1/(const byte*) henry_initials )
@ -1338,11 +1338,11 @@ VARIABLE REGISTER WEIGHTS
(byte*) print_line_cursor#20 0.4444444444444444
(byte*) print_line_cursor#9 24.0
(void()) print_ln()
(void()) print_person((dword) print_person::person_id , (byte*) print_person::person_initials)
(void()) print_person((dword) print_person::person_id , (const byte*) print_person::person_initials)
(struct Person) print_person::person
(dword) print_person::person_id
(dword) print_person::person_id#2 2.0
(byte*) print_person::person_initials
(const byte*) print_person::person_initials
(byte*) print_person::person_initials#2 0.4
(byte*) print_screen
(void()) print_str((byte*) print_str::str)
@ -2735,7 +2735,7 @@ FINAL SYMBOL TABLE
(void()) print_ln()
(label) print_ln::@1
(label) print_ln::@return
(void()) print_person((dword) print_person::person_id , (byte*) print_person::person_initials)
(void()) print_person((dword) print_person::person_id , (const byte*) print_person::person_initials)
(label) print_person::@1
(label) print_person::@2
(label) print_person::@3
@ -2743,7 +2743,7 @@ FINAL SYMBOL TABLE
(struct Person) print_person::person
(dword) print_person::person_id
(dword) print_person::person_id#2 person_id zp[4]:2 2.0
(byte*) print_person::person_initials
(const byte*) print_person::person_initials
(byte*) print_person::person_initials#2 person_initials zp[2]:6 0.4
(byte*) print_screen
(void()) print_str((byte*) print_str::str)

View File

@ -40,7 +40,7 @@
(void()) print_ln()
(label) print_ln::@1
(label) print_ln::@return
(void()) print_person((dword) print_person::person_id , (byte*) print_person::person_initials)
(void()) print_person((dword) print_person::person_id , (const byte*) print_person::person_initials)
(label) print_person::@1
(label) print_person::@2
(label) print_person::@3
@ -48,7 +48,7 @@
(struct Person) print_person::person
(dword) print_person::person_id
(dword) print_person::person_id#2 person_id zp[4]:2 2.0
(byte*) print_person::person_initials
(const byte*) print_person::person_initials
(byte*) print_person::person_initials#2 person_initials zp[2]:6 0.4
(byte*) print_screen
(void()) print_str((byte*) print_str::str)

View File

@ -23,10 +23,8 @@ main: {
rts
jesper_name: .text "jesper"
.byte 0
.fill $39, 0
henriette_name: .text "henriette"
.byte 0
.fill $36, 0
}
// print_person(byte register(X) person_id, byte* zeropage(2) person_name)
print_person: {

View File

@ -21,7 +21,7 @@ main::@return: scope:[main] from main::@1
[8] return
to:@return
(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name)
(void()) print_person((byte) print_person::person_id , (const byte*) print_person::person_name)
print_person: scope:[print_person] from main main::@1
[9] (byte*) print_person::person_name#4 ← phi( main/(const byte*) main::jesper_name#1 main::@1/(const byte*) main::henriette_name#1 )
[9] (byte) idx#13 ← phi( main/(byte) 0 main::@1/(byte) idx#16 )

View File

@ -2,29 +2,29 @@ Fixing struct type size struct Person to 65
Fixing struct type size struct Person to 65
Fixing struct type size struct Person to 65
Created struct value member variable (byte) main::jesper_id
Created struct value member variable (byte*) main::jesper_name
Created struct value member variable (const byte*) main::jesper_name
Converted struct value to member variables (struct Person) main::jesper
Created struct value member variable (byte) main::henriette_id
Created struct value member variable (byte*) main::henriette_name
Created struct value member variable (const byte*) main::henriette_name
Converted struct value to member variables (struct Person) main::henriette
Created struct value member variable (byte) print_person::person_id
Created struct value member variable (byte*) print_person::person_name
Created struct value member variable (const byte*) print_person::person_name
Converted struct value to member variables (struct Person) print_person::person
Converted procedure struct value parameter to member unwinding (void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name)
Converted procedure struct value parameter to member unwinding (void()) print_person((byte) print_person::person_id , (const byte*) print_person::person_name)
Adding struct value member variable default initializer (byte) main::jesper_id ← (byte) 0
Adding struct value member variable default initializer (byte*) main::jesper_name ← (byte*) 0
Converted procedure struct value parameter to member unwinding in call (void~) main::$0 ← call print_person (byte) main::jesper_id (byte*) main::jesper_name
Adding struct value member variable default initializer (const byte*) main::jesper_name ← (byte*) 0
Converted procedure struct value parameter to member unwinding in call (void~) main::$0 ← call print_person (byte) main::jesper_id (const byte*) main::jesper_name
Adding struct value member variable default initializer (byte) main::henriette_id ← (byte) 0
Adding struct value member variable default initializer (byte*) main::henriette_name ← (byte*) 0
Converted procedure struct value parameter to member unwinding in call (void~) main::$1 ← call print_person (byte) main::henriette_id (byte*) main::henriette_name
Adding struct value member variable default initializer (const byte*) main::henriette_name ← (byte*) 0
Converted procedure struct value parameter to member unwinding in call (void~) main::$1 ← call print_person (byte) main::henriette_id (const byte*) main::henriette_name
Replacing struct member reference (struct Person) main::jesper.id with member unwinding reference (byte) main::jesper_id
Replacing struct member reference (struct Person) main::jesper.name with member unwinding reference (byte*) main::jesper_name
Replacing struct member reference (struct Person) main::jesper.name with member unwinding reference (const byte*) main::jesper_name
Replacing struct member reference (struct Person) main::henriette.id with member unwinding reference (byte) main::henriette_id
Replacing struct member reference (struct Person) main::henriette.name with member unwinding reference (byte*) main::henriette_name
Replacing struct member reference (struct Person) main::henriette.name with member unwinding reference (const byte*) main::henriette_name
Replacing struct member reference (struct Person) print_person::person.id with member unwinding reference (byte) print_person::person_id
Replacing struct member reference (struct Person) print_person::person.name with member unwinding reference (byte*) print_person::person_name
Replacing struct member reference (struct Person) print_person::person.name with member unwinding reference (byte*) print_person::person_name
Warning! Adding boolean cast to non-boolean condition *((byte*) print_person::person_name + (byte) print_person::i)
Replacing struct member reference (struct Person) print_person::person.name with member unwinding reference (const byte*) print_person::person_name
Replacing struct member reference (struct Person) print_person::person.name with member unwinding reference (const byte*) print_person::person_name
Warning! Adding boolean cast to non-boolean condition *((const byte*) print_person::person_name + (byte) print_person::i)
Culled Empty Block (label) print_person::@4
Culled Empty Block (label) print_person::@5
Culled Empty Block (label) print_person::@6
@ -68,7 +68,7 @@ main::@return: scope:[main] from main::@2
(byte) idx#3 ← (number) 0
to:@2
(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name)
(void()) print_person((byte) print_person::person_id , (const byte*) print_person::person_name)
print_person: scope:[print_person] from main main::@1
(byte*) print_person::person_name#4 ← phi( main/(byte*) print_person::person_name#0 main::@1/(byte*) print_person::person_name#1 )
(byte) idx#13 ← phi( main/(byte) idx#18 main::@1/(byte) idx#0 )
@ -155,16 +155,16 @@ SYMBOL TABLE SSA
(byte) main::henriette_id
(byte) main::henriette_id#0
(byte) main::henriette_id#1
(byte*) main::henriette_name
(const byte*) main::henriette_name
(byte*) main::henriette_name#0
(byte*) main::henriette_name#1
(byte) main::jesper_id
(byte) main::jesper_id#0
(byte) main::jesper_id#1
(byte*) main::jesper_name
(const byte*) main::jesper_name
(byte*) main::jesper_name#0
(byte*) main::jesper_name#1
(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name)
(void()) print_person((byte) print_person::person_id , (const byte*) print_person::person_name)
(bool~) print_person::$0
(label) print_person::@1
(label) print_person::@2
@ -180,7 +180,7 @@ SYMBOL TABLE SSA
(byte) print_person::person_id#0
(byte) print_person::person_id#1
(byte) print_person::person_id#2
(byte*) print_person::person_name
(const byte*) print_person::person_name
(byte*) print_person::person_name#0
(byte*) print_person::person_name#1
(byte*) print_person::person_name#2
@ -315,7 +315,7 @@ main::@return: scope:[main] from main::@1
[8] return
to:@return
(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name)
(void()) print_person((byte) print_person::person_id , (const byte*) print_person::person_name)
print_person: scope:[print_person] from main main::@1
[9] (byte*) print_person::person_name#4 ← phi( main/(const byte*) main::jesper_name#1 main::@1/(const byte*) main::henriette_name#1 )
[9] (byte) idx#13 ← phi( main/(byte) 0 main::@1/(byte) idx#16 )
@ -355,17 +355,17 @@ VARIABLE REGISTER WEIGHTS
(byte) idx#6 11.0
(void()) main()
(byte) main::henriette_id
(byte*) main::henriette_name
(const byte*) main::henriette_name
(byte) main::jesper_id
(byte*) main::jesper_name
(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name)
(const byte*) main::jesper_name
(void()) print_person((byte) print_person::person_id , (const byte*) print_person::person_name)
(byte) print_person::i
(byte) print_person::i#1 22.0
(byte) print_person::i#2 11.0
(struct Person) print_person::person
(byte) print_person::person_id
(byte) print_person::person_id#2 2.0
(byte*) print_person::person_name
(const byte*) print_person::person_name
(byte*) print_person::person_name#4 2.2
Initial phi equivalence classes
@ -463,10 +463,8 @@ main: {
rts
jesper_name: .text "jesper"
.byte 0
.fill $39, 0
henriette_name: .text "henriette"
.byte 0
.fill $36, 0
}
// print_person
// print_person(byte zeropage(2) person_id, byte* zeropage(4) person_name)
@ -643,10 +641,8 @@ main: {
rts
jesper_name: .text "jesper"
.byte 0
.fill $39, 0
henriette_name: .text "henriette"
.byte 0
.fill $36, 0
}
// print_person
// print_person(byte register(X) person_id, byte* zeropage(2) person_name)
@ -762,13 +758,13 @@ FINAL SYMBOL TABLE
(label) main::@return
(byte) main::henriette_id
(const byte) main::henriette_id#1 henriette_id = (byte) 7
(byte*) main::henriette_name
(const byte*) main::henriette_name
(const byte*) main::henriette_name#1 henriette_name = (string) "henriette"
(byte) main::jesper_id
(const byte) main::jesper_id#1 jesper_id = (byte) 4
(byte*) main::jesper_name
(const byte*) main::jesper_name
(const byte*) main::jesper_name#1 jesper_name = (string) "jesper"
(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name)
(void()) print_person((byte) print_person::person_id , (const byte*) print_person::person_name)
(label) print_person::@1
(label) print_person::@2
(label) print_person::@3
@ -779,7 +775,7 @@ FINAL SYMBOL TABLE
(struct Person) print_person::person
(byte) print_person::person_id
(byte) print_person::person_id#2 reg byte x 2.0
(byte*) print_person::person_name
(const byte*) print_person::person_name
(byte*) print_person::person_name#4 person_name zp[2]:2 2.2
reg byte x [ print_person::person_id#2 ]
@ -846,10 +842,8 @@ main: {
rts
jesper_name: .text "jesper"
.byte 0
.fill $39, 0
henriette_name: .text "henriette"
.byte 0
.fill $36, 0
}
// print_person
// print_person(byte register(X) person_id, byte* zeropage(2) person_name)

View File

@ -17,13 +17,13 @@
(label) main::@return
(byte) main::henriette_id
(const byte) main::henriette_id#1 henriette_id = (byte) 7
(byte*) main::henriette_name
(const byte*) main::henriette_name
(const byte*) main::henriette_name#1 henriette_name = (string) "henriette"
(byte) main::jesper_id
(const byte) main::jesper_id#1 jesper_id = (byte) 4
(byte*) main::jesper_name
(const byte*) main::jesper_name
(const byte*) main::jesper_name#1 jesper_name = (string) "jesper"
(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name)
(void()) print_person((byte) print_person::person_id , (const byte*) print_person::person_name)
(label) print_person::@1
(label) print_person::@2
(label) print_person::@3
@ -34,7 +34,7 @@
(struct Person) print_person::person
(byte) print_person::person_id
(byte) print_person::person_id#2 reg byte x 2.0
(byte*) print_person::person_name
(const byte*) print_person::person_name
(byte*) print_person::person_name#4 person_name zp[2]:2 2.2
reg byte x [ print_person::person_id#2 ]

View File

@ -21,7 +21,7 @@ main::@return: scope:[main] from main::@1
[8] return
to:@return
(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name)
(void()) print_person((byte) print_person::person_id , (const byte*) print_person::person_name)
print_person: scope:[print_person] from main main::@1
[9] (byte*) print_person::person_name#4 ← phi( main/(const byte*) main::jesper_name main::@1/(const byte*) main::henriette_name )
[9] (byte) idx#13 ← phi( main/(byte) 0 main::@1/(byte) idx#16 )

View File

@ -2,29 +2,29 @@ Fixing struct type size struct Person to 17
Fixing struct type size struct Person to 17
Fixing struct type size struct Person to 17
Created struct value member variable (byte) main::jesper_id
Created struct value member variable (byte*) main::jesper_name
Created struct value member variable (const byte*) main::jesper_name
Converted struct value to member variables (struct Person) main::jesper
Created struct value member variable (byte) main::henriette_id
Created struct value member variable (byte*) main::henriette_name
Created struct value member variable (const byte*) main::henriette_name
Converted struct value to member variables (struct Person) main::henriette
Created struct value member variable (byte) print_person::person_id
Created struct value member variable (byte*) print_person::person_name
Created struct value member variable (const byte*) print_person::person_name
Converted struct value to member variables (struct Person) print_person::person
Converted procedure struct value parameter to member unwinding (void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name)
Converted procedure struct value parameter to member unwinding (void()) print_person((byte) print_person::person_id , (const byte*) print_person::person_name)
Adding struct value list initializer (byte) main::jesper_id ← (number) 4
Adding struct value list initializer (byte*) main::jesper_name ← (string) "jesper"
Converted procedure struct value parameter to member unwinding in call (void~) main::$0 ← call print_person (byte) main::jesper_id (byte*) main::jesper_name
Adding struct value list initializer (const byte*) main::jesper_name ← (string) "jesper"
Converted procedure struct value parameter to member unwinding in call (void~) main::$0 ← call print_person (byte) main::jesper_id (const byte*) main::jesper_name
Adding struct value list initializer (byte) main::henriette_id ← (number) 7
Adding struct value list initializer (byte*) main::henriette_name ← (string) "henriette"
Converted procedure struct value parameter to member unwinding in call (void~) main::$1 ← call print_person (byte) main::henriette_id (byte*) main::henriette_name
Adding struct value list initializer (const byte*) main::henriette_name ← (string) "henriette"
Converted procedure struct value parameter to member unwinding in call (void~) main::$1 ← call print_person (byte) main::henriette_id (const byte*) main::henriette_name
Replacing struct member reference (struct Person) print_person::person.id with member unwinding reference (byte) print_person::person_id
Replacing struct member reference (struct Person) print_person::person.name with member unwinding reference (byte*) print_person::person_name
Replacing struct member reference (struct Person) print_person::person.name with member unwinding reference (byte*) print_person::person_name
Warning! Adding boolean cast to non-boolean condition *((byte*) print_person::person_name + (byte) print_person::i)
Replacing struct member reference (struct Person) print_person::person.name with member unwinding reference (const byte*) print_person::person_name
Replacing struct member reference (struct Person) print_person::person.name with member unwinding reference (const byte*) print_person::person_name
Warning! Adding boolean cast to non-boolean condition *((const byte*) print_person::person_name + (byte) print_person::i)
Identified constant variable (byte) main::jesper_id
Identified constant variable (byte*) main::jesper_name
Identified constant variable (const byte*) main::jesper_name
Identified constant variable (byte) main::henriette_id
Identified constant variable (byte*) main::henriette_name
Identified constant variable (const byte*) main::henriette_name
Culled Empty Block (label) print_person::@4
Culled Empty Block (label) print_person::@5
Culled Empty Block (label) print_person::@6
@ -60,7 +60,7 @@ main::@return: scope:[main] from main::@2
(byte) idx#3 ← (number) 0
to:@2
(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name)
(void()) print_person((byte) print_person::person_id , (const byte*) print_person::person_name)
print_person: scope:[print_person] from main main::@1
(byte*) print_person::person_name#4 ← phi( main/(byte*) print_person::person_name#0 main::@1/(byte*) print_person::person_name#1 )
(byte) idx#13 ← phi( main/(byte) idx#18 main::@1/(byte) idx#0 )
@ -146,7 +146,7 @@ SYMBOL TABLE SSA
(const byte*) main::henriette_name = (string) "henriette"
(const byte) main::jesper_id = (byte) 4
(const byte*) main::jesper_name = (string) "jesper"
(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name)
(void()) print_person((byte) print_person::person_id , (const byte*) print_person::person_name)
(bool~) print_person::$0
(label) print_person::@1
(label) print_person::@2
@ -162,7 +162,7 @@ SYMBOL TABLE SSA
(byte) print_person::person_id#0
(byte) print_person::person_id#1
(byte) print_person::person_id#2
(byte*) print_person::person_name
(const byte*) print_person::person_name
(byte*) print_person::person_name#0
(byte*) print_person::person_name#1
(byte*) print_person::person_name#2
@ -273,7 +273,7 @@ main::@return: scope:[main] from main::@1
[8] return
to:@return
(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name)
(void()) print_person((byte) print_person::person_id , (const byte*) print_person::person_name)
print_person: scope:[print_person] from main main::@1
[9] (byte*) print_person::person_name#4 ← phi( main/(const byte*) main::jesper_name main::@1/(const byte*) main::henriette_name )
[9] (byte) idx#13 ← phi( main/(byte) 0 main::@1/(byte) idx#16 )
@ -312,14 +312,14 @@ VARIABLE REGISTER WEIGHTS
(byte) idx#5 4.0
(byte) idx#6 11.0
(void()) main()
(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name)
(void()) print_person((byte) print_person::person_id , (const byte*) print_person::person_name)
(byte) print_person::i
(byte) print_person::i#1 22.0
(byte) print_person::i#2 11.0
(struct Person) print_person::person
(byte) print_person::person_id
(byte) print_person::person_id#2 2.0
(byte*) print_person::person_name
(const byte*) print_person::person_name
(byte*) print_person::person_name#4 2.2
Initial phi equivalence classes
@ -716,7 +716,7 @@ FINAL SYMBOL TABLE
(const byte*) main::henriette_name = (string) "henriette"
(const byte) main::jesper_id = (byte) 4
(const byte*) main::jesper_name = (string) "jesper"
(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name)
(void()) print_person((byte) print_person::person_id , (const byte*) print_person::person_name)
(label) print_person::@1
(label) print_person::@2
(label) print_person::@3
@ -727,7 +727,7 @@ FINAL SYMBOL TABLE
(struct Person) print_person::person
(byte) print_person::person_id
(byte) print_person::person_id#2 reg byte x 2.0
(byte*) print_person::person_name
(const byte*) print_person::person_name
(byte*) print_person::person_name#4 person_name zp[2]:2 2.2
reg byte x [ print_person::person_id#2 ]

View File

@ -19,7 +19,7 @@
(const byte*) main::henriette_name = (string) "henriette"
(const byte) main::jesper_id = (byte) 4
(const byte*) main::jesper_name = (string) "jesper"
(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name)
(void()) print_person((byte) print_person::person_id , (const byte*) print_person::person_name)
(label) print_person::@1
(label) print_person::@2
(label) print_person::@3
@ -30,7 +30,7 @@
(struct Person) print_person::person
(byte) print_person::person_id
(byte) print_person::person_id#2 reg byte x 2.0
(byte*) print_person::person_name
(const byte*) print_person::person_name
(byte*) print_person::person_name#4 person_name zp[2]:2 2.2
reg byte x [ print_person::person_id#2 ]