1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-11-20 02:32:36 +00:00

Struct values can now be bulk initialized / copied in assignments. Still needs work for global variables and more.

This commit is contained in:
jespergravgaard 2020-01-09 00:30:16 +01:00
parent 26be14f7ee
commit 030a379845
115 changed files with 2604 additions and 2231 deletions

View File

@ -0,0 +1,5 @@
!:
lda {c2}-1,x
sta {c1}-1,x
dex
bne !-

View File

@ -0,0 +1,5 @@
!:
lda {c2}-1,y
sta {c1}-1,y
dey
bne !-

View File

@ -0,0 +1,5 @@
lda #0
!:
dey
sta {c1},y
bne !-

View File

@ -0,0 +1,5 @@
!:
lda {c2}-1,x
sta {c1}-1,x
dex
bne !-

View File

@ -0,0 +1,5 @@
!:
lda {c2}-1,y
sta {c1}-1,y
dey
bne !-

View File

@ -0,0 +1,5 @@
lda #0
!:
dex
sta {c1},x
bne !-

View File

@ -0,0 +1,5 @@
lda #0
!:
dey
sta {c1},y
bne !-

View File

@ -20,7 +20,7 @@ public class Initializers {
* @param statementSource The source line
* @return The new statement
*/
public static RValue createZeroValue(ValueTypeSpec typeSpec, StatementSource statementSource) {
public static ConstantValue createZeroValue(ValueTypeSpec typeSpec, StatementSource statementSource) {
if(typeSpec.getType() instanceof SymbolTypeIntegerFixed) {
// Add an zero value initializer
return new ConstantInteger(0L, typeSpec.getType());

View File

@ -118,9 +118,9 @@ public class SymbolTypeInference {
} else if(rValue instanceof StackIdxValue) {
return SymbolType.BYTE;
} else if(rValue instanceof MemsetValue) {
return SymbolType.BYTE;
return ((MemsetValue) rValue).getType();
} else if(rValue instanceof MemcpyValue) {
return SymbolType.BYTE;
return ((MemcpyValue) rValue).getType();
} else if(rValue instanceof StructUnwoundPlaceholder) {
return ((StructUnwoundPlaceholder) rValue).getTypeStruct();
} else if(rValue instanceof ConstantStructValue) {

View File

@ -1,6 +1,7 @@
package dk.camelot64.kickc.model.values;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.types.SymbolType;
/** Value representing intrinsic call to memcpy(dest, src, size). */
public class MemcpyValue implements RValue {
@ -11,9 +12,13 @@ public class MemcpyValue implements RValue {
/** The constant holding the size to set to zero. */
private ConstantValue size;
public MemcpyValue(RValue source, ConstantValue size) {
/** The type of the value, */
private SymbolType type;
public MemcpyValue(RValue source, ConstantValue size, SymbolType type) {
this.source = source;
this.size = size;
this.type = type;
}
public ConstantValue getSize() {
@ -32,9 +37,13 @@ public class MemcpyValue implements RValue {
this.source = source;
}
public SymbolType getType() {
return type;
}
@Override
public String toString(Program program) {
return "memcpy("+source.toString(program)+", "+size.toString(program)+")";
return "memcpy("+source.toString(program)+", "+type.getTypeName()+", "+size.toString(program)+")";
}

View File

@ -9,8 +9,12 @@ public class MemsetValue implements RValue {
/** The constant holding the size to set to zero. */
private ConstantValue size;
public MemsetValue(ConstantValue size) {
/** The type of the value. */
private SymbolType type;
public MemsetValue(ConstantValue size, SymbolType type) {
this.size = size;
this.type = type;
}
public ConstantValue getSize() {
@ -21,9 +25,13 @@ public class MemsetValue implements RValue {
this.size = size;
}
public SymbolType getType() {
return type;
}
@Override
public String toString(Program program) {
return "memset("+size.toString(program)+")";
return "memset("+type.getTypeName()+", "+size.toString(program)+")";
}

View File

@ -1,39 +0,0 @@
package dk.camelot64.kickc.model.values;
import dk.camelot64.kickc.model.InternalError;
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.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypeIntegerFixed;
import dk.camelot64.kickc.model.types.SymbolTypePointer;
import dk.camelot64.kickc.model.types.SymbolTypeStruct;
import java.util.LinkedHashMap;
/**
* Factory usable for creating the default "zero" values for all types.
*/
public class ZeroConstantValues {
public static ConstantValue zeroValue(SymbolType type, ProgramScope programScope) {
if(type instanceof SymbolTypeStruct) {
SymbolTypeStruct typeStruct = (SymbolTypeStruct) type;
LinkedHashMap<SymbolVariableRef, ConstantValue> zeroValues = new LinkedHashMap<>();
StructDefinition structDefinition = typeStruct.getStructDefinition(programScope);
for(Variable memberVar : structDefinition.getAllVariables(false)) {
zeroValues.put(memberVar.getRef(), zeroValue(memberVar.getType(), programScope));
}
return new ConstantStructValue(typeStruct, zeroValues);
} else if(type.equals(SymbolType.BOOLEAN)) {
return new ConstantBool(false);
} else if(type instanceof SymbolTypeIntegerFixed) {
return new ConstantInteger(0L, type);
} else if(type instanceof SymbolTypePointer) {
return new ConstantPointer(0L, ((SymbolTypePointer) type).getElementType());
} else {
throw new InternalError("Unhandled type " + type);
}
}
}

View File

@ -205,11 +205,17 @@ public class Pass1UnwindStructValues extends Pass1Base {
boolean initialAssignment = assignment.isInitialAssignment();
StatementSource source = assignment.getSource();
// Check if this is already a bulk assignment
if(assignment.getrValue2() instanceof MemcpyValue || assignment.getrValue2() instanceof MemsetValue)
return false;
// Check for bulk assignable values
if(isBulkAssignable(lValue) && isBulkAssignable(rValue)) {
RValueUnwinding lValueUnwinding = getValueUnwinding(lValue, assignment, stmtIt, currentBlock);
RValueUnwinding rValueUnwinding = getValueUnwinding(rValue, assignment, stmtIt, currentBlock);
unwindAssignment(lValueUnwinding, rValueUnwinding, null, stmtIt, initialAssignment, source);
stmtIt.remove();
return true;
}
// Check for struct unwinding
@ -294,7 +300,6 @@ public class Pass1UnwindStructValues extends Pass1Base {
* @return true if the value is bulk assignable
*/
private boolean isBulkAssignable(RValue value) {
/*
if(value instanceof SymbolVariableRef) {
Variable var = getScope().getVar((SymbolVariableRef) value);
if(var.isStructClassic())
@ -309,8 +314,6 @@ public class Pass1UnwindStructValues extends Pass1Base {
return true;
// TODO: Add support for arrays
// Not bulk assignable
*/
return false;
}

View File

@ -5,10 +5,7 @@ import dk.camelot64.kickc.model.iterator.ProgramValue;
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
import dk.camelot64.kickc.model.symbols.*;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.values.ConstantArray;
import dk.camelot64.kickc.model.values.ConstantRef;
import dk.camelot64.kickc.model.values.ConstantString;
import dk.camelot64.kickc.model.values.ConstantValue;
import dk.camelot64.kickc.model.values.*;
import java.util.*;
@ -92,7 +89,7 @@ public class Pass2ConstantInlining extends Pass2SsaOptimization {
Collection<Variable> allConstants = getProgram().getScope().getAllConstants(true);
for(Variable constant : allConstants) {
if(constant.getRef().isIntermediate()) {
if(!(constant.getType().equals(SymbolType.STRING)) && !(constant.getInitValue() instanceof ConstantArray)) {
if(!(constant.getType().equals(SymbolType.STRING)) && !(constant.getInitValue() instanceof ConstantArray) && !(constant.getInitValue() instanceof ConstantStructValue)) {
unnamed.put(constant.getConstantRef(), constant.getInitValue());
}
}

View File

@ -7,6 +7,7 @@ import dk.camelot64.kickc.model.*;
import dk.camelot64.kickc.model.iterator.ProgramValue;
import dk.camelot64.kickc.model.iterator.ProgramValueHandler;
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
import dk.camelot64.kickc.model.operators.OperatorSizeOf;
import dk.camelot64.kickc.model.operators.Operators;
import dk.camelot64.kickc.model.statements.*;
import dk.camelot64.kickc.model.symbols.*;
@ -312,6 +313,8 @@ public class Pass4CodeGeneration {
ConstantValue constantValue = constantVar.getInitValue();
if(constantValue instanceof ConstantArray) {
return true;
} else if(constantValue instanceof ConstantStructValue) {
return true;
} else {
try {
ConstantLiteral literal = constantValue.calculateLiteral(getScope());
@ -492,7 +495,7 @@ public class Pass4CodeGeneration {
asm.addDataAlignment(alignment);
}
ConstantValue constantValue = constantVar.getInitValue();
if(constantValue instanceof ConstantArray || constantValue instanceof ConstantString) {
if(constantValue instanceof ConstantArray || constantValue instanceof ConstantString || constantValue instanceof ConstantStructValue) {
AsmDataChunk asmDataChunk = new AsmDataChunk();
addChunkData(asmDataChunk, constantValue, constantVar.getType(), constantVar.getArraySpec(), scopeRef);
asmDataChunk.addToAsm(AsmFormat.asmFix(asmName), asm);
@ -537,7 +540,8 @@ public class Pass4CodeGeneration {
asm.addDataAlignment(alignment);
}
AsmDataChunk asmDataChunk = new AsmDataChunk();
addChunkData(asmDataChunk, ZeroConstantValues.zeroValue(variable.getType(), getScope()), variable.getType(), variable.getArraySpec(), scopeRef);
ConstantValue zeroValue = Initializers.createZeroValue(new Initializers.ValueTypeSpec(variable.getType(), variable.getArraySpec()), null);
addChunkData(asmDataChunk, zeroValue, variable.getType(), variable.getArraySpec(), scopeRef);
asmDataChunk.addToAsm(AsmFormat.asmFix(variable.getAsmName()), asm);
added.add(variable.getAsmName());
}
@ -577,12 +581,20 @@ public class Pass4CodeGeneration {
*/
private void addChunkData(AsmDataChunk dataChunk, ConstantValue value, SymbolType valueType, ArraySpec valueArraySpec, ScopeRef scopeRef) {
if(valueType instanceof SymbolTypeStruct) {
// Add each struct member recursively
ConstantStructValue structValue = (ConstantStructValue) value;
for(SymbolVariableRef memberRef : structValue.getMembers()) {
ConstantValue memberValue = structValue.getValue(memberRef);
Variable memberVariable = getScope().getVar(memberRef);
addChunkData(dataChunk, memberValue, memberVariable.getType(), memberVariable.getArraySpec(), scopeRef);
if(value instanceof ConstantStructValue) {
// Add each struct member recursively
ConstantStructValue structValue = (ConstantStructValue) value;
for(SymbolVariableRef memberRef : structValue.getMembers()) {
ConstantValue memberValue = structValue.getValue(memberRef);
Variable memberVariable = getScope().getVar(memberRef);
addChunkData(dataChunk, memberValue, memberVariable.getType(), memberVariable.getArraySpec(), scopeRef);
}
} else if(value instanceof StructZero) {
final SymbolTypeStruct typeStruct = ((StructZero) value).getTypeStruct();
final ConstantRef structSize = OperatorSizeOf.getSizeOfConstantVar(getScope(), typeStruct);
String totalSizeBytesAsm = AsmFormat.getAsmConstant(program, structSize, 99, scopeRef);
int totalSizeBytes = typeStruct.getSizeBytes();
dataChunk.addDataFilled(AsmDataNumeric.Type.BYTE, totalSizeBytesAsm, totalSizeBytes, "0", null);
}
} else if(valueType instanceof SymbolTypePointer && valueArraySpec != null) {
SymbolTypePointer constTypeArray = (SymbolTypePointer) valueType;
@ -652,7 +664,7 @@ public class Pass4CodeGeneration {
Integer declaredSize = getArrayDeclaredSize(valueArraySpec.getArraySize());
if(declaredSize != null && declaredSize > dataNumElements) {
int padding = declaredSize - dataNumElements;
ConstantValue zeroValue = ZeroConstantValues.zeroValue(elementType, program.getScope());
ConstantValue zeroValue = Initializers.createZeroValue(new Initializers.ValueTypeSpec(elementType, valueArraySpec), null);
if(zeroValue instanceof ConstantInteger) {
dataChunk.addDataFilled(getNumericType(elementType), AsmFormat.getAsmNumber(padding), padding, AsmFormat.getAsmConstant(program, zeroValue, 99, scopeRef), getEncoding(zeroValue));
} else {

View File

@ -38,7 +38,7 @@ public class PassNStructAddressOfRewriting extends Pass2SsaOptimization {
SymbolRef toSymbolRef = constantSymbolPointer.getToSymbol();
Symbol toSymbol = getScope().getSymbol(toSymbolRef);
if(toSymbol.getType() instanceof SymbolTypeStruct) {
RValue rewrite = rewriteStructAddressOf((VariableRef) toSymbol.getRef());
RValue rewrite = rewriteStructAddressOf((SymbolVariableRef) toSymbol.getRef());
if(rewrite != null) {
programValue.set(rewrite);
getLog().append("Rewriting struct address-of to first member " + value.toString(getProgram()));
@ -58,7 +58,7 @@ public class PassNStructAddressOfRewriting extends Pass2SsaOptimization {
if(rValue instanceof SymbolVariableRef) {
Symbol toSymbol = getScope().getSymbol((SymbolVariableRef) rValue);
if(toSymbol.getType() instanceof SymbolTypeStruct) {
RValue rewrite = rewriteStructAddressOf((VariableRef) toSymbol.getRef());
RValue rewrite = rewriteStructAddressOf((SymbolVariableRef) toSymbol.getRef());
if(rewrite != null) {
assignment.setOperator(null);
assignment.setrValue2(rewrite);
@ -90,8 +90,13 @@ public class PassNStructAddressOfRewriting extends Pass2SsaOptimization {
return modified.get();
}
private RValue rewriteStructAddressOf(VariableRef toSymbol) {
Variable variable = getScope().getVariable(toSymbol);
private RValue rewriteStructAddressOf(SymbolVariableRef toSymbol) {
Variable variable = getScope().getVar(toSymbol);
// Constant struct values do not need rewriting
if(variable.isKindConstant())
return null;
// Hacky way to handle PHI-masters
if(variable.isKindPhiMaster()) {
Collection<Variable> versions = variable.getScope().getVersions(variable);

View File

@ -1,10 +1,12 @@
package dk.camelot64.kickc.passes.unwinding;
import dk.camelot64.kickc.model.operators.OperatorSizeOf;
import dk.camelot64.kickc.model.symbols.ArraySpec;
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.SymbolTypePointer;
import dk.camelot64.kickc.model.values.*;
/** Unwinding a constant value. */
@ -36,7 +38,7 @@ public class ConstantValueUnwinding implements RValueUnwinding {
@Override
public boolean isBulkCopyable() {
return getArraySpec()!=null;
return getArraySpec()!=null || value instanceof ConstantStructValue;
}
@Override
@ -44,12 +46,21 @@ public class ConstantValueUnwinding implements RValueUnwinding {
throw new InternalError("Not a valid LValue!");
}
private ConstantValue getByteSize(ProgramScope scope) {
return getArraySpec()!=null?getArraySpec().getArraySize(): OperatorSizeOf.getSizeOfConstantVar(scope, getSymbolType());
}
@Override
public RValue getBulkRValue(ProgramScope scope) {
String constName = scope.allocateIntermediateVariableName();
Variable constVar = Variable.createConstant(constName, symbolType, scope, getArraySpec(), value, Scope.SEGMENT_DATA_DEFAULT);
scope.add(constVar);
return new MemcpyValue(new PointerDereferenceSimple(constVar.getRef()), getArraySpec().getArraySize());
if(getArraySpec()!=null) {
final SymbolType elementType = ((SymbolTypePointer) getSymbolType()).getElementType();
return new MemcpyValue(new PointerDereferenceSimple(new ConstantSymbolPointer(constVar.getRef())), getByteSize(scope), elementType);
} else {
return new MemcpyValue(new PointerDereferenceSimple(new ConstantSymbolPointer(constVar.getRef())), getByteSize(scope), getSymbolType());
}
}
}

View File

@ -129,7 +129,7 @@ public class StructVariableMemberUnwinding implements StructMemberUnwinding {
@Override
public RValue getBulkRValue(ProgramScope scope) {
RValue memberArrayPointer = getUnwinding(scope);
return new MemcpyValue(new PointerDereferenceSimple(memberArrayPointer), getArraySpec().getArraySize());
return new MemcpyValue(new PointerDereferenceSimple(memberArrayPointer), getArraySpec().getArraySize(), getSymbolType());
}
};

View File

@ -1,9 +1,11 @@
package dk.camelot64.kickc.passes.unwinding;
import dk.camelot64.kickc.model.operators.OperatorSizeOf;
import dk.camelot64.kickc.model.symbols.ArraySpec;
import dk.camelot64.kickc.model.symbols.ProgramScope;
import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypeStruct;
import dk.camelot64.kickc.model.values.*;
/** Value unwinding for a variable. */
@ -33,7 +35,7 @@ public class StructVariableValueUnwinding implements RValueUnwinding {
@Override
public boolean isBulkCopyable() {
return getArraySpec()!=null;
return getArraySpec()!=null || variable.isStructClassic() ;
}
@Override
@ -43,11 +45,16 @@ public class StructVariableValueUnwinding implements RValueUnwinding {
return pointerDeref;
}
private ConstantValue getByteSize(ProgramScope scope) {
return getArraySpec()!=null?getArraySpec().getArraySize(): OperatorSizeOf.getSizeOfConstantVar(scope, getSymbolType());
}
@Override
public RValue getBulkRValue(ProgramScope scope) {
ConstantSymbolPointer pointer = new ConstantSymbolPointer(variable.getRef());
LValue pointerDeref = new PointerDereferenceSimple(pointer);
return new MemcpyValue(pointerDeref, getArraySpec().getArraySize());
return new MemcpyValue(pointerDeref, getByteSize(scope), getSymbolType());
}
}

View File

@ -1,5 +1,6 @@
package dk.camelot64.kickc.passes.unwinding;
import dk.camelot64.kickc.model.Initializers;
import dk.camelot64.kickc.model.InternalError;
import dk.camelot64.kickc.model.operators.OperatorSizeOf;
import dk.camelot64.kickc.model.symbols.ArraySpec;
@ -30,12 +31,12 @@ public class ZeroValueUnwinding implements RValueUnwinding {
@Override
public RValue getUnwinding(ProgramScope programScope) {
return ZeroConstantValues.zeroValue(getSymbolType(), programScope);
return Initializers.createZeroValue(new Initializers.ValueTypeSpec(getSymbolType(), getArraySpec()), null);
}
@Override
public boolean isBulkCopyable() {
return arraySpec!=null;
return arraySpec!=null || symbolType instanceof SymbolTypeStruct;
}
@Override
@ -53,7 +54,7 @@ public class ZeroValueUnwinding implements RValueUnwinding {
} else {
throw new InternalError("Bulk unwinding of zero value not handled "+symbolType.getTypeName());
}
return new MemsetValue(byteSize);
return new MemsetValue(byteSize, getSymbolType());
}
}

View File

@ -1127,6 +1127,11 @@ public class TestPrograms {
assertError("struct-err-0", "Unknown struct type");
}
@Test
public void testStruct32() throws IOException, URISyntaxException {
compileAndCompare("struct-32", log());
}
@Test
public void testStruct31() throws IOException, URISyntaxException {
compileAndCompare("struct-31");
@ -1134,7 +1139,7 @@ public class TestPrograms {
@Test
public void testStruct30() throws IOException, URISyntaxException {
compileAndCompare("struct-30");
compileAndCompare("struct-30", log());
}
@Test

17
src/test/kc/struct-32.kc Normal file
View File

@ -0,0 +1,17 @@
// Minimal struct with C-Standard behavior - member is array, copy assignment
struct Point {
char x;
char y;
};
const char* SCREEN = 0x0400;
void main() {
__ma struct Point point1;
point1.x = 2;
point1.y = 3;
__ma struct Point point2 = point1;
SCREEN[0] = point2.x;
SCREEN[1] = point2.y;
}

View File

@ -3,12 +3,15 @@
.pc = $801 "Basic"
:BasicUpstart(__bbegin)
.pc = $80d "Program"
.const SIZEOF_STRUCT_FOO = 2
.const OFFSET_STRUCT_FOO_THING2 = 1
__bbegin:
lda #'a'
sta bar
lda #'b'
sta bar+OFFSET_STRUCT_FOO_THING2
ldy #SIZEOF_STRUCT_FOO
!:
lda __0-1,y
sta bar-1,y
dey
bne !-
jsr main
rts
main: {
@ -20,4 +23,5 @@ main: {
sta SCREEN+1
rts
}
bar: .byte 0, 0
__0: .byte 'a', 'b'
bar: .fill SIZEOF_STRUCT_FOO, 0

View File

@ -1,19 +1,18 @@
@begin: scope:[] from
[0] *((byte*)&(struct foo) bar) ← (byte) 'a'
[1] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b'
[0] *(&(struct foo) bar) ← memcpy(*(&(const struct foo) $0), struct foo, (const byte) SIZEOF_STRUCT_FOO)
to:@1
@1: scope:[] from @begin
[2] phi()
[3] call main
[1] phi()
[2] call main
to:@end
@end: scope:[] from @1
[4] phi()
[3] phi()
(void()) main()
main: scope:[main] from @1
[5] *((const byte*) main::SCREEN) ← *((byte*)(const struct foo*) main::barp)
[6] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING2)
[4] *((const byte*) main::SCREEN) ← *((byte*)(const struct foo*) main::barp)
[5] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING2)
to:main::@return
main::@return: scope:[main] from main
[7] return
[6] return
to:@return

View File

@ -1,15 +1,12 @@
Setting inferred volatile on symbol affected by address-of (struct foo*) main::barp ← &(struct foo) bar
Adding struct value member variable copy *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING1) ← (byte) 'a'
Adding struct value member variable copy *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b'
Adding struct value member variable copy *(&(struct foo) bar) ← memcpy(*(&(const struct foo) $0), struct foo, (const byte) SIZEOF_STRUCT_FOO)
Rewriting struct pointer member access *((struct foo*) main::barp).thing1
Rewriting struct pointer member access *((struct foo*) main::barp).thing2
Identified constant variable (struct foo*) main::barp
CONTROL FLOW GRAPH SSA
@begin: scope:[] from
*((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING1) ← (byte) 'a'
*((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b'
(struct foo) bar ← struct-unwound {*((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING1), *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2)}
*(&(struct foo) bar) ← memcpy(*(&(const struct foo) $0), struct foo, (const byte) SIZEOF_STRUCT_FOO)
to:@1
(void()) main()
@ -33,12 +30,14 @@ main::@return: scope:[main] from main
@end: scope:[] from @2
SYMBOL TABLE SSA
(const struct foo) $0 = { thing1: (byte) 'a', thing2: (byte) 'b' }
(label) @1
(label) @2
(label) @begin
(label) @end
(const byte) OFFSET_STRUCT_FOO_THING1 = (byte) 0
(const byte) OFFSET_STRUCT_FOO_THING2 = (byte) 1
(const byte) SIZEOF_STRUCT_FOO = (byte) 2
(struct foo) bar loadstore
(byte) foo::thing1
(byte) foo::thing2
@ -55,22 +54,20 @@ SYMBOL TABLE SSA
Simplifying constant pointer cast (byte*) 1024
Successful SSA optimization PassNCastSimplification
Removing C-classic struct-unwound assignment [2] (struct foo) bar ← struct-unwound {*((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING1), *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2)}
Constant right-side identified [4] (byte*~) main::$0 ← (byte*)(const struct foo*) main::barp + (const byte) OFFSET_STRUCT_FOO_THING1
Constant right-side identified [7] (byte*~) main::$1 ← (byte*)(const struct foo*) main::barp + (const byte) OFFSET_STRUCT_FOO_THING2
Constant right-side identified [2] (byte*~) main::$0 ← (byte*)(const struct foo*) main::barp + (const byte) OFFSET_STRUCT_FOO_THING1
Constant right-side identified [5] (byte*~) main::$1 ← (byte*)(const struct foo*) main::barp + (const byte) OFFSET_STRUCT_FOO_THING2
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant (const byte) main::i#0 = 0
Constant (const byte*) main::$0 = (byte*)main::barp+OFFSET_STRUCT_FOO_THING1
Constant (const byte*) main::$1 = (byte*)main::barp+OFFSET_STRUCT_FOO_THING2
Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero (byte*)main::barp in
Simplifying expression containing zero (byte*)&bar in [0] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING1) ← (byte) 'a'
Simplifying expression containing zero main::SCREEN in [5] *((const byte*) main::SCREEN + (const byte) main::i#0) ← *((const byte*) main::$0)
Simplifying expression containing zero main::SCREEN in [3] *((const byte*) main::SCREEN + (const byte) main::i#0) ← *((const byte*) main::$0)
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused variable (byte) main::i#2 and assignment [5] (byte) main::i#2 ← ++ (byte) main::i#1
Eliminating unused variable (byte) main::i#2 and assignment [4] (byte) main::i#2 ← ++ (byte) main::i#1
Eliminating unused constant (const byte) OFFSET_STRUCT_FOO_THING1
Successful SSA optimization PassNEliminateUnusedVars
Constant right-side identified [3] (byte) main::i#1 ← ++ (const byte) main::i#0
Constant right-side identified [2] (byte) main::i#1 ← ++ (const byte) main::i#0
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant (const byte) main::i#1 = ++main::i#0
Successful SSA optimization Pass2ConstantIdentification
@ -89,7 +86,7 @@ Adding NOP phi() at start of @1
Adding NOP phi() at start of @2
Adding NOP phi() at start of @end
CALL GRAPH
Calls in [] to main:3
Calls in [] to main:2
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
@ -99,23 +96,22 @@ Adding NOP phi() at start of @end
FINAL CONTROL FLOW GRAPH
@begin: scope:[] from
[0] *((byte*)&(struct foo) bar) ← (byte) 'a'
[1] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b'
[0] *(&(struct foo) bar) ← memcpy(*(&(const struct foo) $0), struct foo, (const byte) SIZEOF_STRUCT_FOO)
to:@1
@1: scope:[] from @begin
[2] phi()
[3] call main
[1] phi()
[2] call main
to:@end
@end: scope:[] from @1
[4] phi()
[3] phi()
(void()) main()
main: scope:[main] from @1
[5] *((const byte*) main::SCREEN) ← *((byte*)(const struct foo*) main::barp)
[6] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING2)
[4] *((const byte*) main::SCREEN) ← *((byte*)(const struct foo*) main::barp)
[5] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING2)
to:main::@return
main::@return: scope:[main] from main
[7] return
[6] return
to:@return
@ -142,23 +138,25 @@ Target platform is c64basic / MOS6502X
:BasicUpstart(__bbegin)
.pc = $80d "Program"
// Global Constants & labels
.const SIZEOF_STRUCT_FOO = 2
.const OFFSET_STRUCT_FOO_THING2 = 1
// @begin
__bbegin:
// [0] *((byte*)&(struct foo) bar) ← (byte) 'a' -- _deref_pbuc1=vbuc2
lda #'a'
sta bar
// [1] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b' -- _deref_pbuc1=vbuc2
lda #'b'
sta bar+OFFSET_STRUCT_FOO_THING2
// [2] phi from @begin to @1 [phi:@begin->@1]
// [0] *(&(struct foo) bar) ← memcpy(*(&(const struct foo) $0), struct foo, (const byte) SIZEOF_STRUCT_FOO) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_FOO
!:
lda __0-1,y
sta bar-1,y
dey
bne !-
// [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin:
jmp __b1
// @1
__b1:
// [3] call main
// [2] call main
jsr main
// [4] phi from @1 to @end [phi:@1->@end]
// [3] phi from @1 to @end [phi:@1->@end]
__bend_from___b1:
jmp __bend
// @end
@ -167,26 +165,26 @@ __bend:
main: {
.label SCREEN = $400
.label barp = bar
// [5] *((const byte*) main::SCREEN) ← *((byte*)(const struct foo*) main::barp) -- _deref_pbuc1=_deref_pbuc2
// [4] *((const byte*) main::SCREEN) ← *((byte*)(const struct foo*) main::barp) -- _deref_pbuc1=_deref_pbuc2
lda barp
sta SCREEN
// [6] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING2) -- _deref_pbuc1=_deref_pbuc2
// [5] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING2) -- _deref_pbuc1=_deref_pbuc2
lda barp+OFFSET_STRUCT_FOO_THING2
sta SCREEN+1
jmp __breturn
// main::@return
__breturn:
// [7] return
// [6] return
rts
}
// File Data
bar: .byte 0, 0
__0: .byte 'a', 'b'
bar: .fill SIZEOF_STRUCT_FOO, 0
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] *((byte*)&(struct foo) bar) ← (byte) 'a' [ bar ] ( [ bar ] ) always clobbers reg byte a
Statement [1] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b' [ ] ( [ ] ) always clobbers reg byte a
Statement [5] *((const byte*) main::SCREEN) ← *((byte*)(const struct foo*) main::barp) [ ] ( main:3 [ ] ) always clobbers reg byte a
Statement [6] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING2) [ ] ( main:3 [ ] ) always clobbers reg byte a
Statement [0] *(&(struct foo) bar) ← memcpy(*(&(const struct foo) $0), struct foo, (const byte) SIZEOF_STRUCT_FOO) [ ] ( [ ] ) always clobbers reg byte a reg byte y
Statement [4] *((const byte*) main::SCREEN) ← *((byte*)(const struct foo*) main::barp) [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [5] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING2) [ ] ( main:2 [ ] ) always clobbers reg byte a
Potential registers mem[2] [ bar ] : mem[2] ,
REGISTER UPLIFT SCOPES
@ -194,9 +192,9 @@ Uplift Scope [foo]
Uplift Scope [main]
Uplift Scope [] 0: mem[2] [ bar ]
Uplifting [foo] best 49 combination
Uplifting [main] best 49 combination
Uplifting [] best 49 combination mem[2] [ bar ]
Uplifting [foo] best 53 combination
Uplifting [main] best 53 combination
Uplifting [] best 53 combination mem[2] [ bar ]
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
@ -207,23 +205,25 @@ ASSEMBLER BEFORE OPTIMIZATION
:BasicUpstart(__bbegin)
.pc = $80d "Program"
// Global Constants & labels
.const SIZEOF_STRUCT_FOO = 2
.const OFFSET_STRUCT_FOO_THING2 = 1
// @begin
__bbegin:
// [0] *((byte*)&(struct foo) bar) ← (byte) 'a' -- _deref_pbuc1=vbuc2
lda #'a'
sta bar
// [1] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b' -- _deref_pbuc1=vbuc2
lda #'b'
sta bar+OFFSET_STRUCT_FOO_THING2
// [2] phi from @begin to @1 [phi:@begin->@1]
// [0] *(&(struct foo) bar) ← memcpy(*(&(const struct foo) $0), struct foo, (const byte) SIZEOF_STRUCT_FOO) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_FOO
!:
lda __0-1,y
sta bar-1,y
dey
bne !-
// [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin:
jmp __b1
// @1
__b1:
// [3] call main
// [2] call main
jsr main
// [4] phi from @1 to @end [phi:@1->@end]
// [3] phi from @1 to @end [phi:@1->@end]
__bend_from___b1:
jmp __bend
// @end
@ -232,20 +232,21 @@ __bend:
main: {
.label SCREEN = $400
.label barp = bar
// [5] *((const byte*) main::SCREEN) ← *((byte*)(const struct foo*) main::barp) -- _deref_pbuc1=_deref_pbuc2
// [4] *((const byte*) main::SCREEN) ← *((byte*)(const struct foo*) main::barp) -- _deref_pbuc1=_deref_pbuc2
lda barp
sta SCREEN
// [6] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING2) -- _deref_pbuc1=_deref_pbuc2
// [5] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING2) -- _deref_pbuc1=_deref_pbuc2
lda barp+OFFSET_STRUCT_FOO_THING2
sta SCREEN+1
jmp __breturn
// main::@return
__breturn:
// [7] return
// [6] return
rts
}
// File Data
bar: .byte 0, 0
__0: .byte 'a', 'b'
bar: .fill SIZEOF_STRUCT_FOO, 0
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
@ -263,10 +264,12 @@ Adding RTS to root block
Succesful ASM optimization Pass5AddMainRts
FINAL SYMBOL TABLE
(const struct foo) $0 = { thing1: (byte) 'a', thing2: (byte) 'b' }
(label) @1
(label) @begin
(label) @end
(const byte) OFFSET_STRUCT_FOO_THING2 = (byte) 1
(const byte) SIZEOF_STRUCT_FOO = (byte) 2
(struct foo) bar loadstore mem[2]
(byte) foo::thing1
(byte) foo::thing2
@ -280,7 +283,7 @@ mem[2] [ bar ]
FINAL ASSEMBLER
Score: 46
Score: 50
// File Comments
// Test declaring a variable as "memory", meaning it will be stored in memory and accessed through an implicit pointer (using load/store)
@ -290,40 +293,43 @@ Score: 46
:BasicUpstart(__bbegin)
.pc = $80d "Program"
// Global Constants & labels
.const SIZEOF_STRUCT_FOO = 2
.const OFFSET_STRUCT_FOO_THING2 = 1
// @begin
__bbegin:
// bar = { 'a', 'b' }
// [0] *((byte*)&(struct foo) bar) ← (byte) 'a' -- _deref_pbuc1=vbuc2
lda #'a'
sta bar
// [1] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b' -- _deref_pbuc1=vbuc2
lda #'b'
sta bar+OFFSET_STRUCT_FOO_THING2
// [2] phi from @begin to @1 [phi:@begin->@1]
// [0] *(&(struct foo) bar) ← memcpy(*(&(const struct foo) $0), struct foo, (const byte) SIZEOF_STRUCT_FOO) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_FOO
!:
lda __0-1,y
sta bar-1,y
dey
bne !-
// [1] phi from @begin to @1 [phi:@begin->@1]
// @1
// [3] call main
// [2] call main
jsr main
rts
// [4] phi from @1 to @end [phi:@1->@end]
// [3] phi from @1 to @end [phi:@1->@end]
// @end
// main
main: {
.label SCREEN = $400
.label barp = bar
// SCREEN[i++] = barp->thing1
// [5] *((const byte*) main::SCREEN) ← *((byte*)(const struct foo*) main::barp) -- _deref_pbuc1=_deref_pbuc2
// [4] *((const byte*) main::SCREEN) ← *((byte*)(const struct foo*) main::barp) -- _deref_pbuc1=_deref_pbuc2
lda barp
sta SCREEN
// SCREEN[i++] = barp->thing2
// [6] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING2) -- _deref_pbuc1=_deref_pbuc2
// [5] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING2) -- _deref_pbuc1=_deref_pbuc2
lda barp+OFFSET_STRUCT_FOO_THING2
sta SCREEN+1
// main::@return
// }
// [7] return
// [6] return
rts
}
// File Data
bar: .byte 0, 0
__0: .byte 'a', 'b'
bar: .fill SIZEOF_STRUCT_FOO, 0

View File

@ -1,7 +1,9 @@
(const struct foo) $0 = { thing1: (byte) 'a', thing2: (byte) 'b' }
(label) @1
(label) @begin
(label) @end
(const byte) OFFSET_STRUCT_FOO_THING2 = (byte) 1
(const byte) SIZEOF_STRUCT_FOO = (byte) 2
(struct foo) bar loadstore mem[2]
(byte) foo::thing1
(byte) foo::thing2

View File

@ -3,17 +3,14 @@
.pc = $801 "Basic"
:BasicUpstart(__bbegin)
.pc = $80d "Program"
.const SIZEOF_STRUCT_FOO = $e
.const OFFSET_STRUCT_FOO_THING2 = 1
.const OFFSET_STRUCT_FOO_THING3 = 2
__bbegin:
lda #'a'
sta bar
lda #'b'
sta bar+OFFSET_STRUCT_FOO_THING2
ldy #$c
ldy #SIZEOF_STRUCT_FOO
!:
lda __0-1,y
sta bar+OFFSET_STRUCT_FOO_THING3-1,y
sta bar-1,y
dey
bne !-
jsr main
@ -36,7 +33,8 @@ main: {
bne __b1
rts
}
__0: .text "qwe"
__0: .byte 'a', 'b'
.text "qwe"
.byte 0
.fill 8, 0
bar: .byte 0, 0
bar: .fill SIZEOF_STRUCT_FOO, 0

View File

@ -1,28 +1,26 @@
@begin: scope:[] from
[0] *((byte*)&(struct foo) bar) ← (byte) 'a'
[1] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b'
[2] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING3) ← memcpy(*((const byte*) $0), (number) $c)
[0] *(&(struct foo) bar) ← memcpy(*(&(const struct foo) $0), struct foo, (const byte) SIZEOF_STRUCT_FOO)
to:@1
@1: scope:[] from @begin
[3] phi()
[4] call main
[1] phi()
[2] call main
to:@end
@end: scope:[] from @1
[5] phi()
[3] phi()
(void()) main()
main: scope:[main] from @1
[6] *((const byte*) main::SCREEN) ← *((byte*)(const struct foo*) main::barp)
[7] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING2)
[4] *((const byte*) main::SCREEN) ← *((byte*)(const struct foo*) main::barp)
[5] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING2)
to:main::@1
main::@1: scope:[main] from main main::@1
[8] (byte) main::i#4 ← phi( main/(byte) 2 main::@1/(byte) main::i#3 )
[8] (byte) main::j#2 ← phi( main/(byte) 0 main::@1/(byte) main::j#1 )
[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)
[10] (byte) main::i#3 ← ++ (byte) main::i#4
[11] (byte) main::j#1 ← ++ (byte) main::j#2
[12] if((byte) main::j#1!=(byte) $c) goto main::@1
[6] (byte) main::i#4 ← phi( main/(byte) 2 main::@1/(byte) main::i#3 )
[6] (byte) main::j#2 ← phi( main/(byte) 0 main::@1/(byte) main::j#1 )
[7] *((const byte*) main::SCREEN + (byte) main::i#4) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING3 + (byte) main::j#2)
[8] (byte) main::i#3 ← ++ (byte) main::i#4
[9] (byte) main::j#1 ← ++ (byte) main::j#2
[10] if((byte) main::j#1!=(byte) $c) goto main::@1
to:main::@return
main::@return: scope:[main] from main::@1
[13] return
[11] return
to:@return

View File

@ -3,9 +3,7 @@ Fixing struct type size struct foo to 14
Fixing struct type SIZE_OF struct foo to 14
Fixing struct type SIZE_OF struct foo to 14
Setting inferred volatile on symbol affected by address-of (struct foo*) main::barp ← &(struct foo) bar
Adding struct value member variable copy *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING1) ← (byte) 'a'
Adding struct value member variable copy *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b'
Adding struct value member variable copy *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING3) ← memcpy(*((const byte*) $0), (number) $c)
Adding struct value member variable copy *(&(struct foo) bar) ← memcpy(*(&(const struct foo) $0), struct foo, (const byte) SIZEOF_STRUCT_FOO)
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
@ -14,10 +12,7 @@ Culled Empty Block (label) main::@2
CONTROL FLOW GRAPH SSA
@begin: scope:[] from
*((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING1) ← (byte) 'a'
*((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b'
*((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING3) ← memcpy(*((const byte*) $0), (number) $c)
(struct foo) bar ← struct-unwound {*((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING1), *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2), *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING3)}
*(&(struct foo) bar) ← memcpy(*(&(const struct foo) $0), struct foo, (const byte) SIZEOF_STRUCT_FOO)
to:@1
(void()) main()
@ -52,7 +47,7 @@ main::@return: scope:[main] from main::@1
@end: scope:[] from @2
SYMBOL TABLE SSA
(const byte*) $0[(number) $c] = (string) "qwe"
(const struct foo) $0 = { thing1: (byte) 'a', thing2: (byte) 'b', thing3: (string) "qwe" }
(label) @1
(label) @2
(label) @begin
@ -60,6 +55,7 @@ SYMBOL TABLE SSA
(const byte) OFFSET_STRUCT_FOO_THING1 = (byte) 0
(const byte) OFFSET_STRUCT_FOO_THING2 = (byte) 1
(const byte) OFFSET_STRUCT_FOO_THING3 = (byte) 2
(const byte) SIZEOF_STRUCT_FOO = (byte) $e
(struct foo) bar loadstore
(byte) foo::thing1
(byte) foo::thing2
@ -86,12 +82,11 @@ SYMBOL TABLE SSA
Simplifying constant pointer cast (byte*) 1024
Successful SSA optimization PassNCastSimplification
Simple Condition (bool~) main::$0 [18] if((byte) main::j#1!=rangelast(0,$b)) goto main::@1
Simple Condition (bool~) main::$0 [15] if((byte) main::j#1!=rangelast(0,$b)) goto main::@1
Successful SSA optimization Pass2ConditionalJumpSimplification
Removing C-classic struct-unwound assignment [3] (struct foo) bar ← struct-unwound {*((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING1), *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2), *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING3)}
Constant right-side identified [5] (byte*~) main::$1 ← (byte*)(const struct foo*) main::barp + (const byte) OFFSET_STRUCT_FOO_THING1
Constant right-side identified [8] (byte*~) main::$2 ← (byte*)(const struct foo*) main::barp + (const byte) OFFSET_STRUCT_FOO_THING2
Constant right-side identified [13] (byte*~) main::$3 ← (byte*)(const struct foo*) main::barp + (const byte) OFFSET_STRUCT_FOO_THING3
Constant right-side identified [2] (byte*~) main::$1 ← (byte*)(const struct foo*) main::barp + (const byte) OFFSET_STRUCT_FOO_THING1
Constant right-side identified [5] (byte*~) main::$2 ← (byte*)(const struct foo*) main::barp + (const byte) OFFSET_STRUCT_FOO_THING2
Constant right-side identified [10] (byte*~) main::$3 ← (byte*)(const struct foo*) main::barp + (const byte) OFFSET_STRUCT_FOO_THING3
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant (const byte) main::i#0 = 0
Constant (const byte*) main::$1 = (byte*)main::barp+OFFSET_STRUCT_FOO_THING1
@ -99,11 +94,10 @@ Constant (const byte*) main::$2 = (byte*)main::barp+OFFSET_STRUCT_FOO_THING2
Constant (const byte) main::j#0 = 0
Constant (const byte*) main::$3 = (byte*)main::barp+OFFSET_STRUCT_FOO_THING3
Successful SSA optimization Pass2ConstantIdentification
Resolved ranged next value [16] main::j#1 ← ++ main::j#2 to ++
Resolved ranged comparison value [18] if(main::j#1!=rangelast(0,$b)) goto main::@1 to (number) $c
Resolved ranged next value [13] main::j#1 ← ++ main::j#2 to ++
Resolved ranged comparison value [15] if(main::j#1!=rangelast(0,$b)) goto main::@1 to (number) $c
Simplifying expression containing zero (byte*)main::barp in
Simplifying expression containing zero (byte*)&bar in [0] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING1) ← (byte) 'a'
Simplifying expression containing zero main::SCREEN in [6] *((const byte*) main::SCREEN + (const byte) main::i#0) ← *((const byte*) main::$1)
Simplifying expression containing zero main::SCREEN in [3] *((const byte*) main::SCREEN + (const byte) main::i#0) ← *((const byte*) main::$1)
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant (const byte) OFFSET_STRUCT_FOO_THING1
Successful SSA optimization PassNEliminateUnusedVars
@ -113,11 +107,11 @@ Simplifying constant integer cast $c
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) $c
Successful SSA optimization PassNFinalizeNumberTypeConversions
Constant right-side identified [4] (byte) main::i#1 ← ++ (const byte) main::i#0
Constant right-side identified [2] (byte) main::i#1 ← ++ (const byte) main::i#0
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant (const byte) main::i#1 = ++main::i#0
Successful SSA optimization Pass2ConstantIdentification
Constant right-side identified [5] (byte) main::i#2 ← ++ (const byte) main::i#1
Constant right-side identified [3] (byte) main::i#2 ← ++ (const byte) main::i#1
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant (const byte) main::i#2 = ++main::i#1
Successful SSA optimization Pass2ConstantIdentification
@ -145,11 +139,11 @@ Adding NOP phi() at start of @1
Adding NOP phi() at start of @2
Adding NOP phi() at start of @end
CALL GRAPH
Calls in [] to main:4
Calls in [] to main:2
Created 2 initial phi equivalence classes
Coalesced [15] main::j#3 ← main::j#1
Coalesced [16] main::i#5 ← main::i#3
Coalesced [13] main::j#3 ← main::j#1
Coalesced [14] main::i#5 ← main::i#3
Coalesced down to 2 phi equivalence classes
Culled Empty Block (label) @2
Culled Empty Block (label) main::@3
@ -158,32 +152,30 @@ Adding NOP phi() at start of @end
FINAL CONTROL FLOW GRAPH
@begin: scope:[] from
[0] *((byte*)&(struct foo) bar) ← (byte) 'a'
[1] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b'
[2] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING3) ← memcpy(*((const byte*) $0), (number) $c)
[0] *(&(struct foo) bar) ← memcpy(*(&(const struct foo) $0), struct foo, (const byte) SIZEOF_STRUCT_FOO)
to:@1
@1: scope:[] from @begin
[3] phi()
[4] call main
[1] phi()
[2] call main
to:@end
@end: scope:[] from @1
[5] phi()
[3] phi()
(void()) main()
main: scope:[main] from @1
[6] *((const byte*) main::SCREEN) ← *((byte*)(const struct foo*) main::barp)
[7] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING2)
[4] *((const byte*) main::SCREEN) ← *((byte*)(const struct foo*) main::barp)
[5] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING2)
to:main::@1
main::@1: scope:[main] from main main::@1
[8] (byte) main::i#4 ← phi( main/(byte) 2 main::@1/(byte) main::i#3 )
[8] (byte) main::j#2 ← phi( main/(byte) 0 main::@1/(byte) main::j#1 )
[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)
[10] (byte) main::i#3 ← ++ (byte) main::i#4
[11] (byte) main::j#1 ← ++ (byte) main::j#2
[12] if((byte) main::j#1!=(byte) $c) goto main::@1
[6] (byte) main::i#4 ← phi( main/(byte) 2 main::@1/(byte) main::i#3 )
[6] (byte) main::j#2 ← phi( main/(byte) 0 main::@1/(byte) main::j#1 )
[7] *((const byte*) main::SCREEN + (byte) main::i#4) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING3 + (byte) main::j#2)
[8] (byte) main::i#3 ← ++ (byte) main::i#4
[9] (byte) main::j#1 ← ++ (byte) main::j#2
[10] if((byte) main::j#1!=(byte) $c) goto main::@1
to:main::@return
main::@return: scope:[main] from main::@1
[13] return
[11] return
to:@return
@ -221,31 +213,26 @@ Target platform is c64basic / MOS6502X
:BasicUpstart(__bbegin)
.pc = $80d "Program"
// Global Constants & labels
.const SIZEOF_STRUCT_FOO = $e
.const OFFSET_STRUCT_FOO_THING2 = 1
.const OFFSET_STRUCT_FOO_THING3 = 2
// @begin
__bbegin:
// [0] *((byte*)&(struct foo) bar) ← (byte) 'a' -- _deref_pbuc1=vbuc2
lda #'a'
sta bar
// [1] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b' -- _deref_pbuc1=vbuc2
lda #'b'
sta bar+OFFSET_STRUCT_FOO_THING2
// [2] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING3) ← memcpy(*((const byte*) $0), (number) $c) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3
ldy #$c
// [0] *(&(struct foo) bar) ← memcpy(*(&(const struct foo) $0), struct foo, (const byte) SIZEOF_STRUCT_FOO) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_FOO
!:
lda __0-1,y
sta bar+OFFSET_STRUCT_FOO_THING3-1,y
sta bar-1,y
dey
bne !-
// [3] phi from @begin to @1 [phi:@begin->@1]
// [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin:
jmp __b1
// @1
__b1:
// [4] call main
// [2] call main
jsr main
// [5] phi from @1 to @end [phi:@1->@end]
// [3] phi from @1 to @end [phi:@1->@end]
__bend_from___b1:
jmp __bend
// @end
@ -256,68 +243,65 @@ main: {
.label barp = bar
.label i = 3
.label j = 2
// [6] *((const byte*) main::SCREEN) ← *((byte*)(const struct foo*) main::barp) -- _deref_pbuc1=_deref_pbuc2
// [4] *((const byte*) main::SCREEN) ← *((byte*)(const struct foo*) main::barp) -- _deref_pbuc1=_deref_pbuc2
lda barp
sta SCREEN
// [7] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING2) -- _deref_pbuc1=_deref_pbuc2
// [5] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING2) -- _deref_pbuc1=_deref_pbuc2
lda barp+OFFSET_STRUCT_FOO_THING2
sta SCREEN+1
// [8] phi from main to main::@1 [phi:main->main::@1]
// [6] phi from main to main::@1 [phi:main->main::@1]
__b1_from_main:
// [8] phi (byte) main::i#4 = (byte) 2 [phi:main->main::@1#0] -- vbuz1=vbuc1
// [6] phi (byte) main::i#4 = (byte) 2 [phi:main->main::@1#0] -- vbuz1=vbuc1
lda #2
sta.z i
// [8] phi (byte) main::j#2 = (byte) 0 [phi:main->main::@1#1] -- vbuz1=vbuc1
// [6] phi (byte) main::j#2 = (byte) 0 [phi:main->main::@1#1] -- vbuz1=vbuc1
lda #0
sta.z j
jmp __b1
// [8] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
// [6] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
__b1_from___b1:
// [8] phi (byte) main::i#4 = (byte) main::i#3 [phi:main::@1->main::@1#0] -- register_copy
// [8] phi (byte) main::j#2 = (byte) main::j#1 [phi:main::@1->main::@1#1] -- register_copy
// [6] phi (byte) main::i#4 = (byte) main::i#3 [phi:main::@1->main::@1#0] -- register_copy
// [6] phi (byte) main::j#2 = (byte) main::j#1 [phi:main::@1->main::@1#1] -- register_copy
jmp __b1
// main::@1
__b1:
// [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) -- pbuc1_derefidx_vbuz1=pbuc2_derefidx_vbuz2
// [7] *((const byte*) main::SCREEN + (byte) main::i#4) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING3 + (byte) main::j#2) -- pbuc1_derefidx_vbuz1=pbuc2_derefidx_vbuz2
ldy.z j
lda barp+OFFSET_STRUCT_FOO_THING3,y
ldy.z i
sta SCREEN,y
// [10] (byte) main::i#3 ← ++ (byte) main::i#4 -- vbuz1=_inc_vbuz1
// [8] (byte) main::i#3 ← ++ (byte) main::i#4 -- vbuz1=_inc_vbuz1
inc.z i
// [11] (byte) main::j#1 ← ++ (byte) main::j#2 -- vbuz1=_inc_vbuz1
// [9] (byte) main::j#1 ← ++ (byte) main::j#2 -- vbuz1=_inc_vbuz1
inc.z j
// [12] if((byte) main::j#1!=(byte) $c) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
// [10] if((byte) main::j#1!=(byte) $c) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
lda #$c
cmp.z j
bne __b1_from___b1
jmp __breturn
// main::@return
__breturn:
// [13] return
// [11] return
rts
}
// File Data
__0: .text "qwe"
__0: .byte 'a', 'b'
.text "qwe"
.byte 0
.fill 8, 0
bar: .byte 0, 0
bar: .fill SIZEOF_STRUCT_FOO, 0
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] *((byte*)&(struct foo) bar) ← (byte) 'a' [ bar ] ( [ bar ] ) always clobbers reg byte a
Statement [1] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b' [ bar ] ( [ bar ] ) always clobbers reg byte a
Statement [2] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING3) ← memcpy(*((const byte*) $0), (number) $c) [ ] ( [ ] ) always clobbers reg byte a reg byte y
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
Statement [0] *(&(struct foo) bar) ← memcpy(*(&(const struct foo) $0), struct foo, (const byte) SIZEOF_STRUCT_FOO) [ ] ( [ ] ) always clobbers reg byte a reg byte y
Statement [4] *((const byte*) main::SCREEN) ← *((byte*)(const struct foo*) main::barp) [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [5] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING2) [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [7] *((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:2 [ main::j#2 main::i#4 ] ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::j#2 main::j#1 ]
Removing always clobbered register reg byte a as potential for zp[1]:3 [ main::i#4 main::i#3 ]
Statement [0] *((byte*)&(struct foo) bar) ← (byte) 'a' [ bar ] ( [ bar ] ) always clobbers reg byte a
Statement [1] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b' [ bar ] ( [ bar ] ) always clobbers reg byte a
Statement [2] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING3) ← memcpy(*((const byte*) $0), (number) $c) [ ] ( [ ] ) always clobbers reg byte a reg byte y
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
Statement [0] *(&(struct foo) bar) ← memcpy(*(&(const struct foo) $0), struct foo, (const byte) SIZEOF_STRUCT_FOO) [ ] ( [ ] ) always clobbers reg byte a reg byte y
Statement [4] *((const byte*) main::SCREEN) ← *((byte*)(const struct foo*) main::barp) [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [5] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING2) [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [7] *((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:2 [ main::j#2 main::i#4 ] ) always clobbers reg byte a
Potential registers zp[1]:2 [ main::j#2 main::j#1 ] : zp[1]:2 , reg byte x , reg byte y ,
Potential registers zp[1]:3 [ main::i#4 main::i#3 ] : zp[1]:3 , reg byte x , reg byte y ,
Potential registers mem[14] [ bar ] : mem[14] ,
@ -327,9 +311,9 @@ Uplift Scope [main] 27.5: zp[1]:2 [ main::j#2 main::j#1 ] 23.83: zp[1]:3 [ main:
Uplift Scope [foo]
Uplift Scope [] 0: mem[14] [ bar ]
Uplifting [main] best 372 combination reg byte y [ main::j#2 main::j#1 ] reg byte x [ main::i#4 main::i#3 ]
Uplifting [foo] best 372 combination
Uplifting [] best 372 combination mem[14] [ bar ]
Uplifting [main] best 360 combination reg byte y [ main::j#2 main::j#1 ] reg byte x [ main::i#4 main::i#3 ]
Uplifting [foo] best 360 combination
Uplifting [] best 360 combination mem[14] [ bar ]
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
@ -340,31 +324,26 @@ ASSEMBLER BEFORE OPTIMIZATION
:BasicUpstart(__bbegin)
.pc = $80d "Program"
// Global Constants & labels
.const SIZEOF_STRUCT_FOO = $e
.const OFFSET_STRUCT_FOO_THING2 = 1
.const OFFSET_STRUCT_FOO_THING3 = 2
// @begin
__bbegin:
// [0] *((byte*)&(struct foo) bar) ← (byte) 'a' -- _deref_pbuc1=vbuc2
lda #'a'
sta bar
// [1] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b' -- _deref_pbuc1=vbuc2
lda #'b'
sta bar+OFFSET_STRUCT_FOO_THING2
// [2] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING3) ← memcpy(*((const byte*) $0), (number) $c) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3
ldy #$c
// [0] *(&(struct foo) bar) ← memcpy(*(&(const struct foo) $0), struct foo, (const byte) SIZEOF_STRUCT_FOO) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_FOO
!:
lda __0-1,y
sta bar+OFFSET_STRUCT_FOO_THING3-1,y
sta bar-1,y
dey
bne !-
// [3] phi from @begin to @1 [phi:@begin->@1]
// [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin:
jmp __b1
// @1
__b1:
// [4] call main
// [2] call main
jsr main
// [5] phi from @1 to @end [phi:@1->@end]
// [3] phi from @1 to @end [phi:@1->@end]
__bend_from___b1:
jmp __bend
// @end
@ -373,47 +352,48 @@ __bend:
main: {
.label SCREEN = $400
.label barp = bar
// [6] *((const byte*) main::SCREEN) ← *((byte*)(const struct foo*) main::barp) -- _deref_pbuc1=_deref_pbuc2
// [4] *((const byte*) main::SCREEN) ← *((byte*)(const struct foo*) main::barp) -- _deref_pbuc1=_deref_pbuc2
lda barp
sta SCREEN
// [7] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING2) -- _deref_pbuc1=_deref_pbuc2
// [5] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING2) -- _deref_pbuc1=_deref_pbuc2
lda barp+OFFSET_STRUCT_FOO_THING2
sta SCREEN+1
// [8] phi from main to main::@1 [phi:main->main::@1]
// [6] phi from main to main::@1 [phi:main->main::@1]
__b1_from_main:
// [8] phi (byte) main::i#4 = (byte) 2 [phi:main->main::@1#0] -- vbuxx=vbuc1
// [6] phi (byte) main::i#4 = (byte) 2 [phi:main->main::@1#0] -- vbuxx=vbuc1
ldx #2
// [8] phi (byte) main::j#2 = (byte) 0 [phi:main->main::@1#1] -- vbuyy=vbuc1
// [6] phi (byte) main::j#2 = (byte) 0 [phi:main->main::@1#1] -- vbuyy=vbuc1
ldy #0
jmp __b1
// [8] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
// [6] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
__b1_from___b1:
// [8] phi (byte) main::i#4 = (byte) main::i#3 [phi:main::@1->main::@1#0] -- register_copy
// [8] phi (byte) main::j#2 = (byte) main::j#1 [phi:main::@1->main::@1#1] -- register_copy
// [6] phi (byte) main::i#4 = (byte) main::i#3 [phi:main::@1->main::@1#0] -- register_copy
// [6] phi (byte) main::j#2 = (byte) main::j#1 [phi:main::@1->main::@1#1] -- register_copy
jmp __b1
// main::@1
__b1:
// [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) -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuyy
// [7] *((const byte*) main::SCREEN + (byte) main::i#4) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING3 + (byte) main::j#2) -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuyy
lda barp+OFFSET_STRUCT_FOO_THING3,y
sta SCREEN,x
// [10] (byte) main::i#3 ← ++ (byte) main::i#4 -- vbuxx=_inc_vbuxx
// [8] (byte) main::i#3 ← ++ (byte) main::i#4 -- vbuxx=_inc_vbuxx
inx
// [11] (byte) main::j#1 ← ++ (byte) main::j#2 -- vbuyy=_inc_vbuyy
// [9] (byte) main::j#1 ← ++ (byte) main::j#2 -- vbuyy=_inc_vbuyy
iny
// [12] if((byte) main::j#1!=(byte) $c) goto main::@1 -- vbuyy_neq_vbuc1_then_la1
// [10] if((byte) main::j#1!=(byte) $c) goto main::@1 -- vbuyy_neq_vbuc1_then_la1
cpy #$c
bne __b1_from___b1
jmp __breturn
// main::@return
__breturn:
// [13] return
// [11] return
rts
}
// File Data
__0: .text "qwe"
__0: .byte 'a', 'b'
.text "qwe"
.byte 0
.fill 8, 0
bar: .byte 0, 0
bar: .fill SIZEOF_STRUCT_FOO, 0
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
@ -437,12 +417,13 @@ Removing instruction jmp __b1
Succesful ASM optimization Pass5NextJumpElimination
FINAL SYMBOL TABLE
(const byte*) $0[(number) $c] = (string) "qwe"
(const struct foo) $0 = { thing1: (byte) 'a', thing2: (byte) 'b', thing3: (string) "qwe" }
(label) @1
(label) @begin
(label) @end
(const byte) OFFSET_STRUCT_FOO_THING2 = (byte) 1
(const byte) OFFSET_STRUCT_FOO_THING3 = (byte) 2
(const byte) SIZEOF_STRUCT_FOO = (byte) $e
(struct foo) bar loadstore mem[14]
(byte) foo::thing1
(byte) foo::thing2
@ -465,7 +446,7 @@ mem[14] [ bar ]
FINAL ASSEMBLER
Score: 282
Score: 270
// File Comments
// Test declaring a variable as "memory", meaning it will be stored in memory and accessed through an implicit pointer (using load/store)
@ -475,74 +456,70 @@ Score: 282
:BasicUpstart(__bbegin)
.pc = $80d "Program"
// Global Constants & labels
.const SIZEOF_STRUCT_FOO = $e
.const OFFSET_STRUCT_FOO_THING2 = 1
.const OFFSET_STRUCT_FOO_THING3 = 2
// @begin
__bbegin:
// bar = { 'a', 'b', "qwe" }
// [0] *((byte*)&(struct foo) bar) ← (byte) 'a' -- _deref_pbuc1=vbuc2
lda #'a'
sta bar
// [1] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b' -- _deref_pbuc1=vbuc2
lda #'b'
sta bar+OFFSET_STRUCT_FOO_THING2
// [2] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING3) ← memcpy(*((const byte*) $0), (number) $c) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3
ldy #$c
// [0] *(&(struct foo) bar) ← memcpy(*(&(const struct foo) $0), struct foo, (const byte) SIZEOF_STRUCT_FOO) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_FOO
!:
lda __0-1,y
sta bar+OFFSET_STRUCT_FOO_THING3-1,y
sta bar-1,y
dey
bne !-
// [3] phi from @begin to @1 [phi:@begin->@1]
// [1] phi from @begin to @1 [phi:@begin->@1]
// @1
// [4] call main
// [2] call main
jsr main
rts
// [5] phi from @1 to @end [phi:@1->@end]
// [3] phi from @1 to @end [phi:@1->@end]
// @end
// main
main: {
.label SCREEN = $400
.label barp = bar
// SCREEN[i++] = barp->thing1
// [6] *((const byte*) main::SCREEN) ← *((byte*)(const struct foo*) main::barp) -- _deref_pbuc1=_deref_pbuc2
// [4] *((const byte*) main::SCREEN) ← *((byte*)(const struct foo*) main::barp) -- _deref_pbuc1=_deref_pbuc2
lda barp
sta SCREEN
// SCREEN[i++] = barp->thing2
// [7] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING2) -- _deref_pbuc1=_deref_pbuc2
// [5] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING2) -- _deref_pbuc1=_deref_pbuc2
lda barp+OFFSET_STRUCT_FOO_THING2
sta SCREEN+1
// [8] phi from main to main::@1 [phi:main->main::@1]
// [8] phi (byte) main::i#4 = (byte) 2 [phi:main->main::@1#0] -- vbuxx=vbuc1
// [6] phi from main to main::@1 [phi:main->main::@1]
// [6] phi (byte) main::i#4 = (byte) 2 [phi:main->main::@1#0] -- vbuxx=vbuc1
ldx #2
// [8] phi (byte) main::j#2 = (byte) 0 [phi:main->main::@1#1] -- vbuyy=vbuc1
// [6] phi (byte) main::j#2 = (byte) 0 [phi:main->main::@1#1] -- vbuyy=vbuc1
ldy #0
// [8] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
// [8] phi (byte) main::i#4 = (byte) main::i#3 [phi:main::@1->main::@1#0] -- register_copy
// [8] phi (byte) main::j#2 = (byte) main::j#1 [phi:main::@1->main::@1#1] -- register_copy
// [6] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
// [6] phi (byte) main::i#4 = (byte) main::i#3 [phi:main::@1->main::@1#0] -- register_copy
// [6] phi (byte) main::j#2 = (byte) main::j#1 [phi:main::@1->main::@1#1] -- register_copy
// main::@1
__b1:
// SCREEN[i++] = barp->thing3[j]
// [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) -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuyy
// [7] *((const byte*) main::SCREEN + (byte) main::i#4) ← *((byte*)(const struct foo*) main::barp+(const byte) OFFSET_STRUCT_FOO_THING3 + (byte) main::j#2) -- pbuc1_derefidx_vbuxx=pbuc2_derefidx_vbuyy
lda barp+OFFSET_STRUCT_FOO_THING3,y
sta SCREEN,x
// SCREEN[i++] = barp->thing3[j];
// [10] (byte) main::i#3 ← ++ (byte) main::i#4 -- vbuxx=_inc_vbuxx
// [8] (byte) main::i#3 ← ++ (byte) main::i#4 -- vbuxx=_inc_vbuxx
inx
// for( char j: 0..11)
// [11] (byte) main::j#1 ← ++ (byte) main::j#2 -- vbuyy=_inc_vbuyy
// [9] (byte) main::j#1 ← ++ (byte) main::j#2 -- vbuyy=_inc_vbuyy
iny
// [12] if((byte) main::j#1!=(byte) $c) goto main::@1 -- vbuyy_neq_vbuc1_then_la1
// [10] if((byte) main::j#1!=(byte) $c) goto main::@1 -- vbuyy_neq_vbuc1_then_la1
cpy #$c
bne __b1
// main::@return
// }
// [13] return
// [11] return
rts
}
// File Data
__0: .text "qwe"
__0: .byte 'a', 'b'
.text "qwe"
.byte 0
.fill 8, 0
bar: .byte 0, 0
bar: .fill SIZEOF_STRUCT_FOO, 0

View File

@ -1,9 +1,10 @@
(const byte*) $0[(number) $c] = (string) "qwe"
(const struct foo) $0 = { thing1: (byte) 'a', thing2: (byte) 'b', thing3: (string) "qwe" }
(label) @1
(label) @begin
(label) @end
(const byte) OFFSET_STRUCT_FOO_THING2 = (byte) 1
(const byte) OFFSET_STRUCT_FOO_THING3 = (byte) 2
(const byte) SIZEOF_STRUCT_FOO = (byte) $e
(struct foo) bar loadstore mem[14]
(byte) foo::thing1
(byte) foo::thing2

View File

@ -3,12 +3,15 @@
.pc = $801 "Basic"
:BasicUpstart(__bbegin)
.pc = $80d "Program"
.const SIZEOF_STRUCT_FOO = 2
.const OFFSET_STRUCT_FOO_THING2 = 1
__bbegin:
lda #'a'
sta bar
lda #'b'
sta bar+OFFSET_STRUCT_FOO_THING2
ldy #SIZEOF_STRUCT_FOO
!:
lda __0-1,y
sta bar-1,y
dey
bne !-
jsr main
rts
main: {
@ -19,4 +22,5 @@ main: {
sta SCREEN+1
rts
}
bar: .byte 0, 0
__0: .byte 'a', 'b'
bar: .fill SIZEOF_STRUCT_FOO, 0

View File

@ -1,19 +1,18 @@
@begin: scope:[] from
[0] *((byte*)&(struct foo) bar) ← (byte) 'a'
[1] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b'
[0] *(&(struct foo) bar) ← memcpy(*(&(const struct foo) $0), struct foo, (const byte) SIZEOF_STRUCT_FOO)
to:@1
@1: scope:[] from @begin
[2] phi()
[3] call main
[1] phi()
[2] call main
to:@end
@end: scope:[] from @1
[4] phi()
[3] phi()
(void()) main()
main: scope:[main] from @1
[5] *((const byte*) main::SCREEN) ← *((byte*)&(struct foo) bar)
[6] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2)
[4] *((const byte*) main::SCREEN) ← *((byte*)&(struct foo) bar)
[5] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2)
to:main::@return
main::@return: scope:[main] from main
[7] return
[6] return
to:@return

View File

@ -1,13 +1,10 @@
Adding struct value member variable copy *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING1) ← (byte) 'a'
Adding struct value member variable copy *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b'
Adding struct value member variable copy *(&(struct foo) bar) ← memcpy(*(&(const struct foo) $0), struct foo, (const byte) SIZEOF_STRUCT_FOO)
Replacing struct member reference (struct foo) bar.thing1 with member unwinding reference *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING1)
Replacing struct member reference (struct foo) bar.thing2 with member unwinding reference *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2)
CONTROL FLOW GRAPH SSA
@begin: scope:[] from
*((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING1) ← (byte) 'a'
*((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b'
(struct foo) bar ← struct-unwound {*((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING1), *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2)}
*(&(struct foo) bar) ← memcpy(*(&(const struct foo) $0), struct foo, (const byte) SIZEOF_STRUCT_FOO)
to:@1
(void()) main()
@ -29,12 +26,14 @@ main::@return: scope:[main] from main
@end: scope:[] from @2
SYMBOL TABLE SSA
(const struct foo) $0 = { thing1: (byte) 'a', thing2: (byte) 'b' }
(label) @1
(label) @2
(label) @begin
(label) @end
(const byte) OFFSET_STRUCT_FOO_THING1 = (byte) 0
(const byte) OFFSET_STRUCT_FOO_THING2 = (byte) 1
(const byte) SIZEOF_STRUCT_FOO = (byte) 2
(struct foo) bar loadstore
(byte) foo::thing1
(byte) foo::thing2
@ -48,17 +47,15 @@ SYMBOL TABLE SSA
Simplifying constant pointer cast (byte*) 1024
Successful SSA optimization PassNCastSimplification
Removing C-classic struct-unwound assignment [2] (struct foo) bar ← struct-unwound {*((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING1), *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2)}
Constant (const byte) main::i#0 = 0
Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero (byte*)&bar in [0] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING1) ← (byte) 'a'
Simplifying expression containing zero (byte*)&bar in [4] *((const byte*) main::SCREEN + (const byte) main::i#0) ← *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING1)
Simplifying expression containing zero main::SCREEN in [4] *((const byte*) main::SCREEN + (const byte) main::i#0) ← *((byte*)&(struct foo) bar)
Simplifying expression containing zero (byte*)&bar in [2] *((const byte*) main::SCREEN + (const byte) main::i#0) ← *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING1)
Simplifying expression containing zero main::SCREEN in [2] *((const byte*) main::SCREEN + (const byte) main::i#0) ← *((byte*)&(struct foo) bar)
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused variable (byte) main::i#2 and assignment [5] (byte) main::i#2 ← ++ (byte) main::i#1
Eliminating unused variable (byte) main::i#2 and assignment [4] (byte) main::i#2 ← ++ (byte) main::i#1
Eliminating unused constant (const byte) OFFSET_STRUCT_FOO_THING1
Successful SSA optimization PassNEliminateUnusedVars
Constant right-side identified [3] (byte) main::i#1 ← ++ (const byte) main::i#0
Constant right-side identified [2] (byte) main::i#1 ← ++ (const byte) main::i#0
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant (const byte) main::i#1 = ++main::i#0
Successful SSA optimization Pass2ConstantIdentification
@ -75,7 +72,7 @@ Adding NOP phi() at start of @1
Adding NOP phi() at start of @2
Adding NOP phi() at start of @end
CALL GRAPH
Calls in [] to main:3
Calls in [] to main:2
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
@ -85,23 +82,22 @@ Adding NOP phi() at start of @end
FINAL CONTROL FLOW GRAPH
@begin: scope:[] from
[0] *((byte*)&(struct foo) bar) ← (byte) 'a'
[1] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b'
[0] *(&(struct foo) bar) ← memcpy(*(&(const struct foo) $0), struct foo, (const byte) SIZEOF_STRUCT_FOO)
to:@1
@1: scope:[] from @begin
[2] phi()
[3] call main
[1] phi()
[2] call main
to:@end
@end: scope:[] from @1
[4] phi()
[3] phi()
(void()) main()
main: scope:[main] from @1
[5] *((const byte*) main::SCREEN) ← *((byte*)&(struct foo) bar)
[6] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2)
[4] *((const byte*) main::SCREEN) ← *((byte*)&(struct foo) bar)
[5] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2)
to:main::@return
main::@return: scope:[main] from main
[7] return
[6] return
to:@return
@ -128,23 +124,25 @@ Target platform is c64basic / MOS6502X
:BasicUpstart(__bbegin)
.pc = $80d "Program"
// Global Constants & labels
.const SIZEOF_STRUCT_FOO = 2
.const OFFSET_STRUCT_FOO_THING2 = 1
// @begin
__bbegin:
// [0] *((byte*)&(struct foo) bar) ← (byte) 'a' -- _deref_pbuc1=vbuc2
lda #'a'
sta bar
// [1] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b' -- _deref_pbuc1=vbuc2
lda #'b'
sta bar+OFFSET_STRUCT_FOO_THING2
// [2] phi from @begin to @1 [phi:@begin->@1]
// [0] *(&(struct foo) bar) ← memcpy(*(&(const struct foo) $0), struct foo, (const byte) SIZEOF_STRUCT_FOO) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_FOO
!:
lda __0-1,y
sta bar-1,y
dey
bne !-
// [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin:
jmp __b1
// @1
__b1:
// [3] call main
// [2] call main
jsr main
// [4] phi from @1 to @end [phi:@1->@end]
// [3] phi from @1 to @end [phi:@1->@end]
__bend_from___b1:
jmp __bend
// @end
@ -152,26 +150,26 @@ __bend:
// main
main: {
.label SCREEN = $400
// [5] *((const byte*) main::SCREEN) ← *((byte*)&(struct foo) bar) -- _deref_pbuc1=_deref_pbuc2
// [4] *((const byte*) main::SCREEN) ← *((byte*)&(struct foo) bar) -- _deref_pbuc1=_deref_pbuc2
lda bar
sta SCREEN
// [6] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) -- _deref_pbuc1=_deref_pbuc2
// [5] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) -- _deref_pbuc1=_deref_pbuc2
lda bar+OFFSET_STRUCT_FOO_THING2
sta SCREEN+1
jmp __breturn
// main::@return
__breturn:
// [7] return
// [6] return
rts
}
// File Data
bar: .byte 0, 0
__0: .byte 'a', 'b'
bar: .fill SIZEOF_STRUCT_FOO, 0
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] *((byte*)&(struct foo) bar) ← (byte) 'a' [ bar ] ( [ bar ] ) always clobbers reg byte a
Statement [1] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b' [ bar ] ( [ bar ] ) always clobbers reg byte a
Statement [5] *((const byte*) main::SCREEN) ← *((byte*)&(struct foo) bar) [ bar ] ( main:3 [ bar ] ) always clobbers reg byte a
Statement [6] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) [ ] ( main:3 [ ] ) always clobbers reg byte a
Statement [0] *(&(struct foo) bar) ← memcpy(*(&(const struct foo) $0), struct foo, (const byte) SIZEOF_STRUCT_FOO) [ bar ] ( [ bar ] ) always clobbers reg byte a reg byte y
Statement [4] *((const byte*) main::SCREEN) ← *((byte*)&(struct foo) bar) [ bar ] ( main:2 [ bar ] ) always clobbers reg byte a
Statement [5] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) [ ] ( main:2 [ ] ) always clobbers reg byte a
Potential registers mem[2] [ bar ] : mem[2] ,
REGISTER UPLIFT SCOPES
@ -179,9 +177,9 @@ Uplift Scope [foo]
Uplift Scope [main]
Uplift Scope [] 0: mem[2] [ bar ]
Uplifting [foo] best 49 combination
Uplifting [main] best 49 combination
Uplifting [] best 49 combination mem[2] [ bar ]
Uplifting [foo] best 53 combination
Uplifting [main] best 53 combination
Uplifting [] best 53 combination mem[2] [ bar ]
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
@ -192,23 +190,25 @@ ASSEMBLER BEFORE OPTIMIZATION
:BasicUpstart(__bbegin)
.pc = $80d "Program"
// Global Constants & labels
.const SIZEOF_STRUCT_FOO = 2
.const OFFSET_STRUCT_FOO_THING2 = 1
// @begin
__bbegin:
// [0] *((byte*)&(struct foo) bar) ← (byte) 'a' -- _deref_pbuc1=vbuc2
lda #'a'
sta bar
// [1] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b' -- _deref_pbuc1=vbuc2
lda #'b'
sta bar+OFFSET_STRUCT_FOO_THING2
// [2] phi from @begin to @1 [phi:@begin->@1]
// [0] *(&(struct foo) bar) ← memcpy(*(&(const struct foo) $0), struct foo, (const byte) SIZEOF_STRUCT_FOO) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_FOO
!:
lda __0-1,y
sta bar-1,y
dey
bne !-
// [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin:
jmp __b1
// @1
__b1:
// [3] call main
// [2] call main
jsr main
// [4] phi from @1 to @end [phi:@1->@end]
// [3] phi from @1 to @end [phi:@1->@end]
__bend_from___b1:
jmp __bend
// @end
@ -216,20 +216,21 @@ __bend:
// main
main: {
.label SCREEN = $400
// [5] *((const byte*) main::SCREEN) ← *((byte*)&(struct foo) bar) -- _deref_pbuc1=_deref_pbuc2
// [4] *((const byte*) main::SCREEN) ← *((byte*)&(struct foo) bar) -- _deref_pbuc1=_deref_pbuc2
lda bar
sta SCREEN
// [6] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) -- _deref_pbuc1=_deref_pbuc2
// [5] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) -- _deref_pbuc1=_deref_pbuc2
lda bar+OFFSET_STRUCT_FOO_THING2
sta SCREEN+1
jmp __breturn
// main::@return
__breturn:
// [7] return
// [6] return
rts
}
// File Data
bar: .byte 0, 0
__0: .byte 'a', 'b'
bar: .fill SIZEOF_STRUCT_FOO, 0
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
@ -247,10 +248,12 @@ Adding RTS to root block
Succesful ASM optimization Pass5AddMainRts
FINAL SYMBOL TABLE
(const struct foo) $0 = { thing1: (byte) 'a', thing2: (byte) 'b' }
(label) @1
(label) @begin
(label) @end
(const byte) OFFSET_STRUCT_FOO_THING2 = (byte) 1
(const byte) SIZEOF_STRUCT_FOO = (byte) 2
(struct foo) bar loadstore mem[2]
(byte) foo::thing1
(byte) foo::thing2
@ -263,7 +266,7 @@ mem[2] [ bar ]
FINAL ASSEMBLER
Score: 46
Score: 50
// File Comments
// Test declaring a variable as "memory", meaning it will be stored in memory and accessed through an implicit pointer (using load/store)
@ -273,39 +276,42 @@ Score: 46
:BasicUpstart(__bbegin)
.pc = $80d "Program"
// Global Constants & labels
.const SIZEOF_STRUCT_FOO = 2
.const OFFSET_STRUCT_FOO_THING2 = 1
// @begin
__bbegin:
// bar = { 'a', 'b' }
// [0] *((byte*)&(struct foo) bar) ← (byte) 'a' -- _deref_pbuc1=vbuc2
lda #'a'
sta bar
// [1] *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) ← (byte) 'b' -- _deref_pbuc1=vbuc2
lda #'b'
sta bar+OFFSET_STRUCT_FOO_THING2
// [2] phi from @begin to @1 [phi:@begin->@1]
// [0] *(&(struct foo) bar) ← memcpy(*(&(const struct foo) $0), struct foo, (const byte) SIZEOF_STRUCT_FOO) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_FOO
!:
lda __0-1,y
sta bar-1,y
dey
bne !-
// [1] phi from @begin to @1 [phi:@begin->@1]
// @1
// [3] call main
// [2] call main
jsr main
rts
// [4] phi from @1 to @end [phi:@1->@end]
// [3] phi from @1 to @end [phi:@1->@end]
// @end
// main
main: {
.label SCREEN = $400
// SCREEN[i++] = bar.thing1
// [5] *((const byte*) main::SCREEN) ← *((byte*)&(struct foo) bar) -- _deref_pbuc1=_deref_pbuc2
// [4] *((const byte*) main::SCREEN) ← *((byte*)&(struct foo) bar) -- _deref_pbuc1=_deref_pbuc2
lda bar
sta SCREEN
// SCREEN[i++] = bar.thing2
// [6] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) -- _deref_pbuc1=_deref_pbuc2
// [5] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)&(struct foo) bar+(const byte) OFFSET_STRUCT_FOO_THING2) -- _deref_pbuc1=_deref_pbuc2
lda bar+OFFSET_STRUCT_FOO_THING2
sta SCREEN+1
// main::@return
// }
// [7] return
// [6] return
rts
}
// File Data
bar: .byte 0, 0
__0: .byte 'a', 'b'
bar: .fill SIZEOF_STRUCT_FOO, 0

View File

@ -1,7 +1,9 @@
(const struct foo) $0 = { thing1: (byte) 'a', thing2: (byte) 'b' }
(label) @1
(label) @begin
(label) @end
(const byte) OFFSET_STRUCT_FOO_THING2 = (byte) 1
(const byte) SIZEOF_STRUCT_FOO = (byte) 2
(struct foo) bar loadstore mem[2]
(byte) foo::thing1
(byte) foo::thing2

View File

@ -11,7 +11,7 @@ Created struct value member variable (byte) main::c_center_y
Converted struct value to member variables (struct Point) main::c_center
Adding struct value member variable copy (byte) main::p_x ← (byte) 0
Adding struct value member variable copy (byte) main::p_y ← (byte) 0
Adding struct value member variable copy (struct Point) main::c_center ← { x: (byte) 0, y: (byte) 0 }
Adding struct value member variable copy (struct Point) main::c_center ← {}
Adding struct value member variable copy (byte) main::c_radius ← (byte) 0
Adding struct value member variable copy (byte) main::c_center_x ← (byte) 0
Adding struct value member variable copy (byte) main::c_center_y ← (byte) 0

View File

@ -1,6 +1,6 @@
@begin: scope:[] from
[0] *((const byte*) jesper_name) ← memcpy(*((const byte*) $0), (number) $40)
[1] *((const byte*) henriette_name) ← memcpy(*((const byte*) $1), (number) $40)
[0] *((const byte*) jesper_name) ← memcpy(*(&(const byte*) $0), byte, (number) $40)
[1] *((const byte*) henriette_name) ← memcpy(*(&(const byte*) $1), byte, (number) $40)
to:@1
@1: scope:[] from @begin
[2] phi()

View File

@ -14,9 +14,9 @@ Created struct value member variable (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)
Adding struct value member variable copy (byte) jesper_id ← (byte) 4
Adding struct value member variable copy *((const byte*) jesper_name) ← memcpy(*((const byte*) $0), (number) $40)
Adding struct value member variable copy *((const byte*) jesper_name) ← memcpy(*(&(const byte*) $0), byte, (number) $40)
Adding struct value member variable copy (byte) henriette_id ← (byte) 7
Adding struct value member variable copy *((const byte*) henriette_name) ← memcpy(*((const byte*) $1), (number) $40)
Adding struct value member variable copy *((const byte*) henriette_name) ← memcpy(*(&(const byte*) $1), byte, (number) $40)
Converted procedure struct value parameter to member unwinding in call (void~) main::$0 ← call print_person (byte) jesper_id (const byte*) jesper_name
Converted procedure struct value parameter to member unwinding in call (void~) main::$1 ← call print_person (byte) henriette_id (const byte*) henriette_name
Replacing struct member reference (struct Person) print_person::person.id with member unwinding reference (byte) print_person::person_id
@ -31,8 +31,8 @@ Culled Empty Block (label) print_person::@6
CONTROL FLOW GRAPH SSA
@begin: scope:[] from
*((const byte*) jesper_name) ← memcpy(*((const byte*) $0), (number) $40)
*((const byte*) henriette_name) ← memcpy(*((const byte*) $1), (number) $40)
*((const byte*) jesper_name) ← memcpy(*(&(const byte*) $0), byte, (number) $40)
*((const byte*) henriette_name) ← memcpy(*(&(const byte*) $1), byte, (number) $40)
to:@1
(void()) main()
@ -244,8 +244,8 @@ Adding NOP phi() at start of main::@1
FINAL CONTROL FLOW GRAPH
@begin: scope:[] from
[0] *((const byte*) jesper_name) ← memcpy(*((const byte*) $0), (number) $40)
[1] *((const byte*) henriette_name) ← memcpy(*((const byte*) $1), (number) $40)
[0] *((const byte*) jesper_name) ← memcpy(*(&(const byte*) $0), byte, (number) $40)
[1] *((const byte*) henriette_name) ← memcpy(*(&(const byte*) $1), byte, (number) $40)
to:@1
@1: scope:[] from @begin
[2] phi()
@ -355,14 +355,14 @@ Target platform is c64basic / MOS6502X
.label idx_2 = 3
// @begin
__bbegin:
// [0] *((const byte*) jesper_name) ← memcpy(*((const byte*) $0), (number) $40) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3
// [0] *((const byte*) jesper_name) ← memcpy(*(&(const byte*) $0), byte, (number) $40) -- _deref_pbuc1=_deref_pptc2_memcpy_vbuc3
ldy #$40
!:
lda __0-1,y
sta jesper_name-1,y
dey
bne !-
// [1] *((const byte*) henriette_name) ← memcpy(*((const byte*) $1), (number) $40) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3
// [1] *((const byte*) henriette_name) ← memcpy(*(&(const byte*) $1), byte, (number) $40) -- _deref_pbuc1=_deref_pptc2_memcpy_vbuc3
ldy #$40
!:
lda __1-1,y
@ -507,8 +507,8 @@ print_person: {
.fill $36, 0
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] *((const byte*) jesper_name) ← memcpy(*((const byte*) $0), (number) $40) [ ] ( [ ] ) always clobbers reg byte a reg byte y
Statement [1] *((const byte*) henriette_name) ← memcpy(*((const byte*) $1), (number) $40) [ ] ( [ ] ) always clobbers reg byte a reg byte y
Statement [0] *((const byte*) jesper_name) ← memcpy(*(&(const byte*) $0), byte, (number) $40) [ ] ( [ ] ) always clobbers reg byte a reg byte y
Statement [1] *((const byte*) henriette_name) ← memcpy(*(&(const byte*) $1), byte, (number) $40) [ ] ( [ ] ) always clobbers reg byte a reg byte y
Statement [11] *((const byte*) SCREEN + (byte) idx#13) ← *((const byte*) DIGIT + (byte) print_person::person_id#2) [ idx#13 print_person::person_name#4 ] ( main:3::print_person:6 [ idx#13 print_person::person_name#4 ] main:3::print_person:8 [ idx#13 print_person::person_name#4 ] ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp[1]:3 [ idx#13 idx#16 ]
Statement [13] *((const byte*) SCREEN + (byte) idx#4) ← (byte) ' ' [ print_person::person_name#4 idx#4 ] ( main:3::print_person:6 [ print_person::person_name#4 idx#4 ] main:3::print_person:8 [ print_person::person_name#4 idx#4 ] ) always clobbers reg byte a
@ -518,8 +518,8 @@ Removing always clobbered register reg byte a as potential for zp[1]:6 [ print_p
Removing always clobbered register reg byte a as potential for zp[1]:7 [ idx#14 idx#5 idx#6 ]
Statement [17] *((const byte*) SCREEN + (byte) idx#14) ← (byte) ' ' [ idx#14 ] ( main:3::print_person:6 [ idx#14 ] main:3::print_person:8 [ idx#14 ] ) always clobbers reg byte a
Statement [20] *((const byte*) SCREEN + (byte) idx#14) ← *((byte*) print_person::person_name#4 + (byte) print_person::i#2) [ print_person::person_name#4 print_person::i#2 idx#14 ] ( main:3::print_person:6 [ print_person::person_name#4 print_person::i#2 idx#14 ] main:3::print_person:8 [ print_person::person_name#4 print_person::i#2 idx#14 ] ) always clobbers reg byte a
Statement [0] *((const byte*) jesper_name) ← memcpy(*((const byte*) $0), (number) $40) [ ] ( [ ] ) always clobbers reg byte a reg byte y
Statement [1] *((const byte*) henriette_name) ← memcpy(*((const byte*) $1), (number) $40) [ ] ( [ ] ) always clobbers reg byte a reg byte y
Statement [0] *((const byte*) jesper_name) ← memcpy(*(&(const byte*) $0), byte, (number) $40) [ ] ( [ ] ) always clobbers reg byte a reg byte y
Statement [1] *((const byte*) henriette_name) ← memcpy(*(&(const byte*) $1), byte, (number) $40) [ ] ( [ ] ) always clobbers reg byte a reg byte y
Statement [11] *((const byte*) SCREEN + (byte) idx#13) ← *((const byte*) DIGIT + (byte) print_person::person_id#2) [ idx#13 print_person::person_name#4 ] ( main:3::print_person:6 [ idx#13 print_person::person_name#4 ] main:3::print_person:8 [ idx#13 print_person::person_name#4 ] ) always clobbers reg byte a
Statement [13] *((const byte*) SCREEN + (byte) idx#4) ← (byte) ' ' [ print_person::person_name#4 idx#4 ] ( main:3::print_person:6 [ print_person::person_name#4 idx#4 ] main:3::print_person:8 [ print_person::person_name#4 idx#4 ] ) always clobbers reg byte a
Statement [16] if((byte) 0!=*((byte*) print_person::person_name#4 + (byte) print_person::i#2)) goto print_person::@2 [ print_person::person_name#4 print_person::i#2 idx#14 ] ( main:3::print_person:6 [ print_person::person_name#4 print_person::i#2 idx#14 ] main:3::print_person:8 [ print_person::person_name#4 print_person::i#2 idx#14 ] ) always clobbers reg byte a
@ -558,14 +558,14 @@ ASSEMBLER BEFORE OPTIMIZATION
.const henriette_id = 7
// @begin
__bbegin:
// [0] *((const byte*) jesper_name) ← memcpy(*((const byte*) $0), (number) $40) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3
// [0] *((const byte*) jesper_name) ← memcpy(*(&(const byte*) $0), byte, (number) $40) -- _deref_pbuc1=_deref_pptc2_memcpy_vbuc3
ldy #$40
!:
lda __0-1,y
sta jesper_name-1,y
dey
bne !-
// [1] *((const byte*) henriette_name) ← memcpy(*((const byte*) $1), (number) $40) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3
// [1] *((const byte*) henriette_name) ← memcpy(*(&(const byte*) $1), byte, (number) $40) -- _deref_pbuc1=_deref_pptc2_memcpy_vbuc3
ldy #$40
!:
lda __1-1,y
@ -785,7 +785,7 @@ Score: 426
// @begin
__bbegin:
// jesper = { 4, "jesper" }
// [0] *((const byte*) jesper_name) ← memcpy(*((const byte*) $0), (number) $40) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3
// [0] *((const byte*) jesper_name) ← memcpy(*(&(const byte*) $0), byte, (number) $40) -- _deref_pbuc1=_deref_pptc2_memcpy_vbuc3
ldy #$40
!:
lda __0-1,y
@ -793,7 +793,7 @@ __bbegin:
dey
bne !-
// henriette = { 7, "henriette" }
// [1] *((const byte*) henriette_name) ← memcpy(*((const byte*) $1), (number) $40) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3
// [1] *((const byte*) henriette_name) ← memcpy(*(&(const byte*) $1), byte, (number) $40) -- _deref_pbuc1=_deref_pptc2_memcpy_vbuc3
ldy #$40
!:
lda __1-1,y

View File

@ -10,11 +10,11 @@
(void()) main()
main: scope:[main] from @1
[4] *((const byte*) main::jesper_name) ← memcpy(*((const byte*) $0), (number) $40)
[4] *((const byte*) main::jesper_name) ← memcpy(*(&(const byte*) $0), byte, (number) $40)
[5] call print_person
to:main::@1
main::@1: scope:[main] from main
[6] *((const byte*) main::henriette_name) ← memcpy(*((const byte*) $1), (number) $40)
[6] *((const byte*) main::henriette_name) ← memcpy(*(&(const byte*) $1), byte, (number) $40)
[7] call print_person
to:main::@return
main::@return: scope:[main] from main::@1

View File

@ -14,10 +14,10 @@ Created struct value member variable (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)
Adding struct value member variable copy (byte) main::jesper_id ← (byte) 4
Adding struct value member variable copy *((const byte*) main::jesper_name) ← memcpy(*((const byte*) $0), (number) $40)
Adding struct value member variable copy *((const byte*) main::jesper_name) ← memcpy(*(&(const byte*) $0), byte, (number) $40)
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 copy (byte) main::henriette_id ← (byte) 7
Adding struct value member variable copy *((const byte*) main::henriette_name) ← memcpy(*((const byte*) $1), (number) $40)
Adding struct value member variable copy *((const byte*) main::henriette_name) ← memcpy(*(&(const byte*) $1), byte, (number) $40)
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
@ -36,7 +36,7 @@ CONTROL FLOW GRAPH SSA
(void()) main()
main: scope:[main] from @2
(byte) idx#18 ← phi( @2/(byte) idx#20 )
*((const byte*) main::jesper_name) ← memcpy(*((const byte*) $0), (number) $40)
*((const byte*) main::jesper_name) ← memcpy(*(&(const byte*) $0), byte, (number) $40)
(byte) print_person::person_id#0 ← (const byte) main::jesper_id
(byte*) print_person::person_name#0 ← (const byte*) main::jesper_name
call print_person
@ -44,7 +44,7 @@ main: scope:[main] from @2
main::@1: scope:[main] from main
(byte) idx#10 ← phi( main/(byte) idx#8 )
(byte) idx#0 ← (byte) idx#10
*((const byte*) main::henriette_name) ← memcpy(*((const byte*) $1), (number) $40)
*((const byte*) main::henriette_name) ← memcpy(*(&(const byte*) $1), byte, (number) $40)
(byte) print_person::person_id#1 ← (const byte) main::henriette_id
(byte*) print_person::person_name#1 ← (const byte*) main::henriette_name
call print_person
@ -254,11 +254,11 @@ FINAL CONTROL FLOW GRAPH
(void()) main()
main: scope:[main] from @1
[4] *((const byte*) main::jesper_name) ← memcpy(*((const byte*) $0), (number) $40)
[4] *((const byte*) main::jesper_name) ← memcpy(*(&(const byte*) $0), byte, (number) $40)
[5] call print_person
to:main::@1
main::@1: scope:[main] from main
[6] *((const byte*) main::henriette_name) ← memcpy(*((const byte*) $1), (number) $40)
[6] *((const byte*) main::henriette_name) ← memcpy(*(&(const byte*) $1), byte, (number) $40)
[7] call print_person
to:main::@return
main::@return: scope:[main] from main::@1
@ -367,7 +367,7 @@ __bend:
main: {
.const jesper_id = 4
.const henriette_id = 7
// [4] *((const byte*) main::jesper_name) ← memcpy(*((const byte*) $0), (number) $40) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3
// [4] *((const byte*) main::jesper_name) ← memcpy(*(&(const byte*) $0), byte, (number) $40) -- _deref_pbuc1=_deref_pptc2_memcpy_vbuc3
ldy #$40
!:
lda __0-1,y
@ -392,7 +392,7 @@ main: {
jmp __b1
// main::@1
__b1:
// [6] *((const byte*) main::henriette_name) ← memcpy(*((const byte*) $1), (number) $40) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3
// [6] *((const byte*) main::henriette_name) ← memcpy(*(&(const byte*) $1), byte, (number) $40) -- _deref_pbuc1=_deref_pptc2_memcpy_vbuc3
ldy #$40
!:
lda __1-1,y
@ -501,8 +501,8 @@ print_person: {
.fill $36, 0
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] *((const byte*) main::jesper_name) ← memcpy(*((const byte*) $0), (number) $40) [ ] ( main:2 [ ] ) always clobbers reg byte a reg byte y
Statement [6] *((const byte*) main::henriette_name) ← memcpy(*((const byte*) $1), (number) $40) [ idx#16 ] ( main:2 [ idx#16 ] ) always clobbers reg byte a reg byte y
Statement [4] *((const byte*) main::jesper_name) ← memcpy(*(&(const byte*) $0), byte, (number) $40) [ ] ( main:2 [ ] ) always clobbers reg byte a reg byte y
Statement [6] *((const byte*) main::henriette_name) ← memcpy(*(&(const byte*) $1), byte, (number) $40) [ idx#16 ] ( main:2 [ idx#16 ] ) always clobbers reg byte a reg byte y
Removing always clobbered register reg byte a as potential for zp[1]:3 [ idx#13 idx#16 ]
Removing always clobbered register reg byte y as potential for zp[1]:3 [ idx#13 idx#16 ]
Statement [10] *((const byte*) SCREEN + (byte) idx#13) ← *((const byte*) DIGIT + (byte) print_person::person_id#2) [ idx#13 print_person::person_name#4 ] ( main:2::print_person:5 [ idx#13 print_person::person_name#4 ] main:2::print_person:7 [ idx#13 print_person::person_name#4 ] ) always clobbers reg byte a
@ -513,8 +513,8 @@ Removing always clobbered register reg byte a as potential for zp[1]:6 [ print_p
Removing always clobbered register reg byte a as potential for zp[1]:7 [ idx#14 idx#5 idx#6 ]
Statement [16] *((const byte*) SCREEN + (byte) idx#14) ← (byte) ' ' [ idx#14 ] ( main:2::print_person:5 [ idx#14 ] main:2::print_person:7 [ idx#14 ] ) always clobbers reg byte a
Statement [19] *((const byte*) SCREEN + (byte) idx#14) ← *((byte*) print_person::person_name#4 + (byte) print_person::i#2) [ print_person::person_name#4 print_person::i#2 idx#14 ] ( main:2::print_person:5 [ print_person::person_name#4 print_person::i#2 idx#14 ] main:2::print_person:7 [ print_person::person_name#4 print_person::i#2 idx#14 ] ) always clobbers reg byte a
Statement [4] *((const byte*) main::jesper_name) ← memcpy(*((const byte*) $0), (number) $40) [ ] ( main:2 [ ] ) always clobbers reg byte a reg byte y
Statement [6] *((const byte*) main::henriette_name) ← memcpy(*((const byte*) $1), (number) $40) [ idx#16 ] ( main:2 [ idx#16 ] ) always clobbers reg byte a reg byte y
Statement [4] *((const byte*) main::jesper_name) ← memcpy(*(&(const byte*) $0), byte, (number) $40) [ ] ( main:2 [ ] ) always clobbers reg byte a reg byte y
Statement [6] *((const byte*) main::henriette_name) ← memcpy(*(&(const byte*) $1), byte, (number) $40) [ idx#16 ] ( main:2 [ idx#16 ] ) always clobbers reg byte a reg byte y
Statement [10] *((const byte*) SCREEN + (byte) idx#13) ← *((const byte*) DIGIT + (byte) print_person::person_id#2) [ idx#13 print_person::person_name#4 ] ( main:2::print_person:5 [ idx#13 print_person::person_name#4 ] main:2::print_person:7 [ idx#13 print_person::person_name#4 ] ) always clobbers reg byte a
Statement [12] *((const byte*) SCREEN + (byte) idx#4) ← (byte) ' ' [ print_person::person_name#4 idx#4 ] ( main:2::print_person:5 [ print_person::person_name#4 idx#4 ] main:2::print_person:7 [ print_person::person_name#4 idx#4 ] ) always clobbers reg byte a
Statement [15] if((byte) 0!=*((byte*) print_person::person_name#4 + (byte) print_person::i#2)) goto print_person::@2 [ print_person::person_name#4 print_person::i#2 idx#14 ] ( main:2::print_person:5 [ print_person::person_name#4 print_person::i#2 idx#14 ] main:2::print_person:7 [ print_person::person_name#4 print_person::i#2 idx#14 ] ) always clobbers reg byte a
@ -571,7 +571,7 @@ __bend:
main: {
.const jesper_id = 4
.const henriette_id = 7
// [4] *((const byte*) main::jesper_name) ← memcpy(*((const byte*) $0), (number) $40) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3
// [4] *((const byte*) main::jesper_name) ← memcpy(*(&(const byte*) $0), byte, (number) $40) -- _deref_pbuc1=_deref_pptc2_memcpy_vbuc3
ldy #$40
!:
lda __0-1,y
@ -595,7 +595,7 @@ main: {
jmp __b1
// main::@1
__b1:
// [6] *((const byte*) main::henriette_name) ← memcpy(*((const byte*) $1), (number) $40) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3
// [6] *((const byte*) main::henriette_name) ← memcpy(*(&(const byte*) $1), byte, (number) $40) -- _deref_pbuc1=_deref_pptc2_memcpy_vbuc3
ldy #$40
!:
lda __1-1,y
@ -789,7 +789,7 @@ main: {
.const jesper_id = 4
.const henriette_id = 7
// jesper = { 4, "jesper" }
// [4] *((const byte*) main::jesper_name) ← memcpy(*((const byte*) $0), (number) $40) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3
// [4] *((const byte*) main::jesper_name) ← memcpy(*(&(const byte*) $0), byte, (number) $40) -- _deref_pbuc1=_deref_pptc2_memcpy_vbuc3
ldy #$40
!:
lda __0-1,y
@ -812,7 +812,7 @@ main: {
jsr print_person
// main::@1
// henriette = { 7, "henriette" }
// [6] *((const byte*) main::henriette_name) ← memcpy(*((const byte*) $1), (number) $40) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3
// [6] *((const byte*) main::henriette_name) ← memcpy(*(&(const byte*) $1), byte, (number) $40) -- _deref_pbuc1=_deref_pptc2_memcpy_vbuc3
ldy #$40
!:
lda __1-1,y

View File

@ -3,12 +3,16 @@
:BasicUpstart(__bbegin)
.pc = $80d "Program"
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1
.label point = 2
__bbegin:
ldy #SIZEOF_STRUCT_POINT
lda #0
sta.z point
sta point+OFFSET_STRUCT_POINT_Y
!:
dey
sta point,y
bne !-
jsr main
rts
main: {

View File

@ -1,21 +1,20 @@
@begin: scope:[] from
[0] *((byte*)&(struct Point) point) ← (byte) 0
[1] *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0
[0] *(&(struct Point) point) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT)
to:@1
@1: scope:[] from @begin
[2] phi()
[3] call main
[1] phi()
[2] call main
to:@end
@end: scope:[] from @1
[4] phi()
[3] phi()
(void()) main()
main: scope:[main] from @1
[5] *((byte*)&(struct Point) point) ← (byte) 2
[6] *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
[7] *((const byte*) SCREEN) ← *((byte*)&(struct Point) point)
[8] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y)
[4] *((byte*)&(struct Point) point) ← (byte) 2
[5] *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
[6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) point)
[7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y)
to:main::@return
main::@return: scope:[main] from main
[9] return
[8] return
to:@return

View File

@ -1,5 +1,4 @@
Adding struct value member variable copy *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 0
Adding struct value member variable copy *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0
Adding struct value member variable copy *(&(struct Point) point) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT)
Replacing struct member reference (struct Point) point.x with member unwinding reference *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_X)
Replacing struct member reference (struct Point) point.y with member unwinding reference *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y)
Replacing struct member reference (struct Point) point.x with member unwinding reference *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_X)
@ -7,9 +6,7 @@ Replacing struct member reference (struct Point) point.y with member unwinding r
CONTROL FLOW GRAPH SSA
@begin: scope:[] from
*((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 0
*((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0
(struct Point) point ← struct-unwound {*((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y)}
*(&(struct Point) point) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT)
to:@1
(void()) main()
@ -39,6 +36,7 @@ SYMBOL TABLE SSA
(byte) Point::x
(byte) Point::y
(const byte*) SCREEN = (byte*)(number) $400
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(void()) main()
(label) main::@return
(struct Point) point loadstore
@ -62,11 +60,9 @@ Finalized unsigned number type (byte) 3
Finalized unsigned number type (byte) 0
Finalized unsigned number type (byte) 1
Successful SSA optimization PassNFinalizeNumberTypeConversions
Removing C-classic struct-unwound assignment [2] (struct Point) point ← struct-unwound {*((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y)}
Simplifying expression containing zero (byte*)&point in [0] *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 0
Simplifying expression containing zero (byte*)&point in [3] *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
Simplifying expression containing zero (byte*)&point in [5] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero SCREEN in [5] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) point)
Simplifying expression containing zero (byte*)&point in [1] *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
Simplifying expression containing zero (byte*)&point in [3] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero SCREEN in [3] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) point)
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant (const byte) OFFSET_STRUCT_POINT_X
Successful SSA optimization PassNEliminateUnusedVars
@ -76,7 +72,7 @@ Adding NOP phi() at start of @1
Adding NOP phi() at start of @2
Adding NOP phi() at start of @end
CALL GRAPH
Calls in [] to main:3
Calls in [] to main:2
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
@ -86,25 +82,24 @@ Adding NOP phi() at start of @end
FINAL CONTROL FLOW GRAPH
@begin: scope:[] from
[0] *((byte*)&(struct Point) point) ← (byte) 0
[1] *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0
[0] *(&(struct Point) point) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT)
to:@1
@1: scope:[] from @begin
[2] phi()
[3] call main
[1] phi()
[2] call main
to:@end
@end: scope:[] from @1
[4] phi()
[3] phi()
(void()) main()
main: scope:[main] from @1
[5] *((byte*)&(struct Point) point) ← (byte) 2
[6] *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
[7] *((const byte*) SCREEN) ← *((byte*)&(struct Point) point)
[8] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y)
[4] *((byte*)&(struct Point) point) ← (byte) 2
[5] *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
[6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) point)
[7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y)
to:main::@return
main::@return: scope:[main] from main
[9] return
[8] return
to:@return
@ -130,57 +125,58 @@ Target platform is c64basic / MOS6502X
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1
.label point = 2
// @begin
__bbegin:
// [0] *((byte*)&(struct Point) point) ← (byte) 0 -- _deref_pbuc1=vbuc2
// [0] *(&(struct Point) point) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_memset_vbuc2
ldy #SIZEOF_STRUCT_POINT
lda #0
sta.z point
// [1] *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0 -- _deref_pbuc1=vbuc2
lda #0
sta point+OFFSET_STRUCT_POINT_Y
// [2] phi from @begin to @1 [phi:@begin->@1]
!:
dey
sta point,y
bne !-
// [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin:
jmp __b1
// @1
__b1:
// [3] call main
// [2] call main
jsr main
// [4] phi from @1 to @end [phi:@1->@end]
// [3] phi from @1 to @end [phi:@1->@end]
__bend_from___b1:
jmp __bend
// @end
__bend:
// main
main: {
// [5] *((byte*)&(struct Point) point) ← (byte) 2 -- _deref_pbuc1=vbuc2
// [4] *((byte*)&(struct Point) point) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z point
// [6] *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
// [5] *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta point+OFFSET_STRUCT_POINT_Y
// [7] *((const byte*) SCREEN) ← *((byte*)&(struct Point) point) -- _deref_pbuc1=_deref_pbuc2
// [6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) point) -- _deref_pbuc1=_deref_pbuc2
lda.z point
sta SCREEN
// [8] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda point+OFFSET_STRUCT_POINT_Y
sta SCREEN+1
jmp __breturn
// main::@return
__breturn:
// [9] return
// [8] return
rts
}
// File Data
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] *((byte*)&(struct Point) point) ← (byte) 0 [ point ] ( [ point ] ) always clobbers reg byte a
Statement [1] *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0 [ point ] ( [ point ] ) always clobbers reg byte a
Statement [5] *((byte*)&(struct Point) point) ← (byte) 2 [ point ] ( main:3 [ point ] ) always clobbers reg byte a
Statement [6] *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 [ point ] ( main:3 [ point ] ) always clobbers reg byte a
Statement [7] *((const byte*) SCREEN) ← *((byte*)&(struct Point) point) [ point ] ( main:3 [ point ] ) always clobbers reg byte a
Statement [8] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) [ ] ( main:3 [ ] ) always clobbers reg byte a
Statement [0] *(&(struct Point) point) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT) [ point ] ( [ point ] ) always clobbers reg byte a reg byte y
Statement [4] *((byte*)&(struct Point) point) ← (byte) 2 [ point ] ( main:2 [ point ] ) always clobbers reg byte a
Statement [5] *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 [ point ] ( main:2 [ point ] ) always clobbers reg byte a
Statement [6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) point) [ point ] ( main:2 [ point ] ) always clobbers reg byte a
Statement [7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) [ ] ( main:2 [ ] ) always clobbers reg byte a
Potential registers zp[2]:2 [ point ] : zp[2]:2 ,
REGISTER UPLIFT SCOPES
@ -188,9 +184,9 @@ Uplift Scope [Point]
Uplift Scope [main]
Uplift Scope [] 0: zp[2]:2 [ point ]
Uplifting [Point] best 58 combination
Uplifting [main] best 58 combination
Uplifting [] best 58 combination zp[2]:2 [ point ]
Uplifting [Point] best 60 combination
Uplifting [main] best 60 combination
Uplifting [] best 60 combination zp[2]:2 [ point ]
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
@ -201,46 +197,48 @@ ASSEMBLER BEFORE OPTIMIZATION
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1
.label point = 2
// @begin
__bbegin:
// [0] *((byte*)&(struct Point) point) ← (byte) 0 -- _deref_pbuc1=vbuc2
// [0] *(&(struct Point) point) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_memset_vbuc2
ldy #SIZEOF_STRUCT_POINT
lda #0
sta.z point
// [1] *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0 -- _deref_pbuc1=vbuc2
lda #0
sta point+OFFSET_STRUCT_POINT_Y
// [2] phi from @begin to @1 [phi:@begin->@1]
!:
dey
sta point,y
bne !-
// [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin:
jmp __b1
// @1
__b1:
// [3] call main
// [2] call main
jsr main
// [4] phi from @1 to @end [phi:@1->@end]
// [3] phi from @1 to @end [phi:@1->@end]
__bend_from___b1:
jmp __bend
// @end
__bend:
// main
main: {
// [5] *((byte*)&(struct Point) point) ← (byte) 2 -- _deref_pbuc1=vbuc2
// [4] *((byte*)&(struct Point) point) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z point
// [6] *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
// [5] *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta point+OFFSET_STRUCT_POINT_Y
// [7] *((const byte*) SCREEN) ← *((byte*)&(struct Point) point) -- _deref_pbuc1=_deref_pbuc2
// [6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) point) -- _deref_pbuc1=_deref_pbuc2
lda.z point
sta SCREEN
// [8] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda point+OFFSET_STRUCT_POINT_Y
sta SCREEN+1
jmp __breturn
// main::@return
__breturn:
// [9] return
// [8] return
rts
}
// File Data
@ -250,8 +248,6 @@ Removing instruction jmp __b1
Removing instruction jmp __bend
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction lda #0
Succesful ASM optimization Pass5UnnecesaryLoadElimination
Removing instruction __b1_from___bbegin:
Removing instruction __bend_from___b1:
Succesful ASM optimization Pass5RedundantLabelElimination
@ -270,6 +266,7 @@ FINAL SYMBOL TABLE
(byte) Point::x
(byte) Point::y
(const byte*) SCREEN = (byte*) 1024
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(void()) main()
(label) main::@return
(struct Point) point loadstore zp[2]:2
@ -278,7 +275,7 @@ zp[2]:2 [ point ]
FINAL ASSEMBLER
Score: 53
Score: 57
// File Comments
// Minimal struct with C-Standard behavior - declaration, instantiation and usage
@ -288,44 +285,47 @@ Score: 53
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1
.label point = 2
// @begin
__bbegin:
// point
// [0] *((byte*)&(struct Point) point) ← (byte) 0 -- _deref_pbuc1=vbuc2
// [0] *(&(struct Point) point) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_memset_vbuc2
ldy #SIZEOF_STRUCT_POINT
lda #0
sta.z point
// [1] *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0 -- _deref_pbuc1=vbuc2
sta point+OFFSET_STRUCT_POINT_Y
// [2] phi from @begin to @1 [phi:@begin->@1]
!:
dey
sta point,y
bne !-
// [1] phi from @begin to @1 [phi:@begin->@1]
// @1
// [3] call main
// [2] call main
jsr main
rts
// [4] phi from @1 to @end [phi:@1->@end]
// [3] phi from @1 to @end [phi:@1->@end]
// @end
// main
main: {
// point.x = 2
// [5] *((byte*)&(struct Point) point) ← (byte) 2 -- _deref_pbuc1=vbuc2
// [4] *((byte*)&(struct Point) point) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z point
// point.y = 3
// [6] *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
// [5] *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta point+OFFSET_STRUCT_POINT_Y
// SCREEN[0] = point.x
// [7] *((const byte*) SCREEN) ← *((byte*)&(struct Point) point) -- _deref_pbuc1=_deref_pbuc2
// [6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) point) -- _deref_pbuc1=_deref_pbuc2
lda.z point
sta SCREEN
// SCREEN[1] = point.y
// [8] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda point+OFFSET_STRUCT_POINT_Y
sta SCREEN+1
// main::@return
// }
// [9] return
// [8] return
rts
}
// File Data

View File

@ -5,6 +5,7 @@
(byte) Point::x
(byte) Point::y
(const byte*) SCREEN = (byte*) 1024
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(void()) main()
(label) main::@return
(struct Point) point loadstore zp[2]:2

View File

@ -3,21 +3,27 @@
:BasicUpstart(main)
.pc = $80d "Program"
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1
main: {
.label point1 = 2
.label point2 = 4
ldy #SIZEOF_STRUCT_POINT
lda #0
sta.z point1
sta point1+OFFSET_STRUCT_POINT_Y
!:
dey
sta point1,y
bne !-
lda #2
sta.z point1
lda #3
sta point1+OFFSET_STRUCT_POINT_Y
lda.z point1
sta.z point2
lda point1+OFFSET_STRUCT_POINT_Y
sta point2+OFFSET_STRUCT_POINT_Y
ldy #SIZEOF_STRUCT_POINT
!:
lda point1-1,y
sta point2-1,y
dey
bne !-
lda.z point2
sta SCREEN
lda point2+OFFSET_STRUCT_POINT_Y

View File

@ -10,15 +10,13 @@
(void()) main()
main: scope:[main] from @1
[4] *((byte*)&(struct Point) main::point1) ← (byte) 0
[5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0
[6] *((byte*)&(struct Point) main::point1) ← (byte) 2
[7] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
[8] *((byte*)&(struct Point) main::point2) ← *((byte*)&(struct Point) main::point1)
[9] *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y)
[10] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2)
[11] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y)
[4] *(&(struct Point) main::point1) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT)
[5] *((byte*)&(struct Point) main::point1) ← (byte) 2
[6] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
[7] *(&(struct Point) main::point2) ← memcpy(*(&(struct Point) main::point1), struct Point, (const byte) SIZEOF_STRUCT_POINT)
[8] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2)
[9] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y)
to:main::@return
main::@return: scope:[main] from main
[12] return
[10] return
to:@return

View File

@ -1,7 +1,5 @@
Adding struct value member variable copy *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 0
Adding struct value member variable copy *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0
Adding struct value member variable copy *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X)
Adding struct value member variable copy *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y)
Adding struct value member variable copy *(&(struct Point) main::point1) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT)
Adding struct value member variable copy *(&(struct Point) main::point2) ← memcpy(*(&(struct Point) main::point1), struct Point, (const byte) SIZEOF_STRUCT_POINT)
Replacing struct member reference (struct Point) main::point1.x with member unwinding reference *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X)
Replacing struct member reference (struct Point) main::point1.y with member unwinding reference *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y)
Replacing struct member reference (struct Point) main::point2.x with member unwinding reference *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X)
@ -13,14 +11,10 @@ CONTROL FLOW GRAPH SSA
(void()) main()
main: scope:[main] from @1
*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 0
*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0
(struct Point) main::point1 ← struct-unwound {*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y)}
*(&(struct Point) main::point1) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT)
*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (number) 2
*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (number) 3
*((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X)
*((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y)
(struct Point) main::point2 ← struct-unwound {*((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y)}
*(&(struct Point) main::point2) ← memcpy(*(&(struct Point) main::point1), struct Point, (const byte) SIZEOF_STRUCT_POINT)
*((const byte*) SCREEN + (number) 0) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X)
*((const byte*) SCREEN + (number) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y)
to:main::@return
@ -44,6 +38,7 @@ SYMBOL TABLE SSA
(byte) Point::x
(byte) Point::y
(const byte*) SCREEN = (byte*)(number) $400
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(void()) main()
(label) main::@return
(struct Point) main::point1 loadstore
@ -68,14 +63,9 @@ Finalized unsigned number type (byte) 3
Finalized unsigned number type (byte) 0
Finalized unsigned number type (byte) 1
Successful SSA optimization PassNFinalizeNumberTypeConversions
Removing C-classic struct-unwound assignment [2] (struct Point) main::point1 ← struct-unwound {*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y)}
Removing C-classic struct-unwound assignment [7] (struct Point) main::point2 ← struct-unwound {*((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y)}
Simplifying expression containing zero (byte*)&main::point1 in [0] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 0
Simplifying expression containing zero (byte*)&main::point1 in [3] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
Simplifying expression containing zero (byte*)&main::point1 in [5] *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero (byte*)&main::point2 in [5] *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X) ← *((byte*)&(struct Point) main::point1)
Simplifying expression containing zero (byte*)&main::point2 in [8] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero SCREEN in [8] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) main::point2)
Simplifying expression containing zero (byte*)&main::point1 in [1] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
Simplifying expression containing zero (byte*)&main::point2 in [4] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero SCREEN in [4] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) main::point2)
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant (const byte) OFFSET_STRUCT_POINT_X
Successful SSA optimization PassNEliminateUnusedVars
@ -108,17 +98,15 @@ FINAL CONTROL FLOW GRAPH
(void()) main()
main: scope:[main] from @1
[4] *((byte*)&(struct Point) main::point1) ← (byte) 0
[5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0
[6] *((byte*)&(struct Point) main::point1) ← (byte) 2
[7] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
[8] *((byte*)&(struct Point) main::point2) ← *((byte*)&(struct Point) main::point1)
[9] *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y)
[10] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2)
[11] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y)
[4] *(&(struct Point) main::point1) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT)
[5] *((byte*)&(struct Point) main::point1) ← (byte) 2
[6] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
[7] *(&(struct Point) main::point2) ← memcpy(*(&(struct Point) main::point1), struct Point, (const byte) SIZEOF_STRUCT_POINT)
[8] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2)
[9] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y)
to:main::@return
main::@return: scope:[main] from main
[12] return
[10] return
to:@return
@ -148,6 +136,7 @@ Target platform is c64basic / MOS6502X
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1
// @begin
__bbegin:
@ -167,47 +156,47 @@ __bend:
main: {
.label point1 = 2
.label point2 = 4
// [4] *((byte*)&(struct Point) main::point1) ← (byte) 0 -- _deref_pbuc1=vbuc2
// [4] *(&(struct Point) main::point1) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_memset_vbuc2
ldy #SIZEOF_STRUCT_POINT
lda #0
sta.z point1
// [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0 -- _deref_pbuc1=vbuc2
lda #0
sta point1+OFFSET_STRUCT_POINT_Y
// [6] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
!:
dey
sta point1,y
bne !-
// [5] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z point1
// [7] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
// [6] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta point1+OFFSET_STRUCT_POINT_Y
// [8] *((byte*)&(struct Point) main::point2) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2
lda.z point1
sta.z point2
// [9] *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda point1+OFFSET_STRUCT_POINT_Y
sta point2+OFFSET_STRUCT_POINT_Y
// [10] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2) -- _deref_pbuc1=_deref_pbuc2
// [7] *(&(struct Point) main::point2) ← memcpy(*(&(struct Point) main::point1), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda point1-1,y
sta point2-1,y
dey
bne !-
// [8] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2) -- _deref_pbuc1=_deref_pbuc2
lda.z point2
sta SCREEN
// [11] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [9] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda point2+OFFSET_STRUCT_POINT_Y
sta SCREEN+1
jmp __breturn
// main::@return
__breturn:
// [12] return
// [10] return
rts
}
// File Data
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] *((byte*)&(struct Point) main::point1) ← (byte) 0 [ main::point1 main::point2 ] ( main:2 [ main::point1 main::point2 ] ) always clobbers reg byte a
Statement [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0 [ main::point1 main::point2 ] ( main:2 [ main::point1 main::point2 ] ) always clobbers reg byte a
Statement [6] *((byte*)&(struct Point) main::point1) ← (byte) 2 [ main::point1 main::point2 ] ( main:2 [ main::point1 main::point2 ] ) always clobbers reg byte a
Statement [7] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 [ main::point1 main::point2 ] ( main:2 [ main::point1 main::point2 ] ) always clobbers reg byte a
Statement [8] *((byte*)&(struct Point) main::point2) ← *((byte*)&(struct Point) main::point1) [ main::point1 main::point2 ] ( main:2 [ main::point1 main::point2 ] ) always clobbers reg byte a
Statement [9] *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) [ main::point2 ] ( main:2 [ main::point2 ] ) always clobbers reg byte a
Statement [10] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2) [ main::point2 ] ( main:2 [ main::point2 ] ) always clobbers reg byte a
Statement [11] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [4] *(&(struct Point) main::point1) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT) [ main::point1 main::point2 ] ( main:2 [ main::point1 main::point2 ] ) always clobbers reg byte a reg byte y
Statement [5] *((byte*)&(struct Point) main::point1) ← (byte) 2 [ main::point1 main::point2 ] ( main:2 [ main::point1 main::point2 ] ) always clobbers reg byte a
Statement [6] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 [ main::point1 main::point2 ] ( main:2 [ main::point1 main::point2 ] ) always clobbers reg byte a
Statement [7] *(&(struct Point) main::point2) ← memcpy(*(&(struct Point) main::point1), struct Point, (const byte) SIZEOF_STRUCT_POINT) [ main::point2 ] ( main:2 [ main::point2 ] ) always clobbers reg byte a reg byte y
Statement [8] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2) [ main::point2 ] ( main:2 [ main::point2 ] ) always clobbers reg byte a
Statement [9] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) [ ] ( main:2 [ ] ) always clobbers reg byte a
Potential registers zp[2]:2 [ main::point1 ] : zp[2]:2 ,
Potential registers zp[2]:4 [ main::point2 ] : zp[2]:4 ,
@ -216,9 +205,9 @@ Uplift Scope [Point]
Uplift Scope [main] 0: zp[2]:2 [ main::point1 ] 0: zp[2]:4 [ main::point2 ]
Uplift Scope []
Uplifting [Point] best 72 combination
Uplifting [main] best 72 combination zp[2]:2 [ main::point1 ] zp[2]:4 [ main::point2 ]
Uplifting [] best 72 combination
Uplifting [Point] best 76 combination
Uplifting [main] best 76 combination zp[2]:2 [ main::point1 ] zp[2]:4 [ main::point2 ]
Uplifting [] best 76 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
@ -229,6 +218,7 @@ ASSEMBLER BEFORE OPTIMIZATION
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1
// @begin
__bbegin:
@ -248,34 +238,36 @@ __bend:
main: {
.label point1 = 2
.label point2 = 4
// [4] *((byte*)&(struct Point) main::point1) ← (byte) 0 -- _deref_pbuc1=vbuc2
// [4] *(&(struct Point) main::point1) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_memset_vbuc2
ldy #SIZEOF_STRUCT_POINT
lda #0
sta.z point1
// [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0 -- _deref_pbuc1=vbuc2
lda #0
sta point1+OFFSET_STRUCT_POINT_Y
// [6] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
!:
dey
sta point1,y
bne !-
// [5] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z point1
// [7] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
// [6] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta point1+OFFSET_STRUCT_POINT_Y
// [8] *((byte*)&(struct Point) main::point2) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2
lda.z point1
sta.z point2
// [9] *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda point1+OFFSET_STRUCT_POINT_Y
sta point2+OFFSET_STRUCT_POINT_Y
// [10] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2) -- _deref_pbuc1=_deref_pbuc2
// [7] *(&(struct Point) main::point2) ← memcpy(*(&(struct Point) main::point1), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda point1-1,y
sta point2-1,y
dey
bne !-
// [8] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2) -- _deref_pbuc1=_deref_pbuc2
lda.z point2
sta SCREEN
// [11] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [9] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda point2+OFFSET_STRUCT_POINT_Y
sta SCREEN+1
jmp __breturn
// main::@return
__breturn:
// [12] return
// [10] return
rts
}
// File Data
@ -285,8 +277,6 @@ Removing instruction jmp __b1
Removing instruction jmp __bend
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction lda #0
Succesful ASM optimization Pass5UnnecesaryLoadElimination
Replacing label __bbegin with __b1
Removing instruction __bbegin:
Removing instruction __b1_from___bbegin:
@ -309,6 +299,7 @@ FINAL SYMBOL TABLE
(byte) Point::x
(byte) Point::y
(const byte*) SCREEN = (byte*) 1024
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(void()) main()
(label) main::@return
(struct Point) main::point1 loadstore zp[2]:2
@ -319,7 +310,7 @@ zp[2]:4 [ main::point2 ]
FINAL ASSEMBLER
Score: 55
Score: 61
// File Comments
// Minimal struct with C-Standard behavior - copying
@ -329,6 +320,7 @@ Score: 55
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1
// @begin
// [1] phi from @begin to @1 [phi:@begin->@1]
@ -341,37 +333,40 @@ main: {
.label point1 = 2
.label point2 = 4
// point1
// [4] *((byte*)&(struct Point) main::point1) ← (byte) 0 -- _deref_pbuc1=vbuc2
// [4] *(&(struct Point) main::point1) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_memset_vbuc2
ldy #SIZEOF_STRUCT_POINT
lda #0
sta.z point1
// [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0 -- _deref_pbuc1=vbuc2
sta point1+OFFSET_STRUCT_POINT_Y
!:
dey
sta point1,y
bne !-
// point1.x = 2
// [6] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
// [5] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z point1
// point1.y = 3
// [7] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
// [6] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta point1+OFFSET_STRUCT_POINT_Y
// point2 = point1
// [8] *((byte*)&(struct Point) main::point2) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2
lda.z point1
sta.z point2
// [9] *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda point1+OFFSET_STRUCT_POINT_Y
sta point2+OFFSET_STRUCT_POINT_Y
// [7] *(&(struct Point) main::point2) ← memcpy(*(&(struct Point) main::point1), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda point1-1,y
sta point2-1,y
dey
bne !-
// SCREEN[0] = point2.x
// [10] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2) -- _deref_pbuc1=_deref_pbuc2
// [8] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2) -- _deref_pbuc1=_deref_pbuc2
lda.z point2
sta SCREEN
// SCREEN[1] = point2.y
// [11] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [9] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda point2+OFFSET_STRUCT_POINT_Y
sta SCREEN+1
// main::@return
// }
// [12] return
// [10] return
rts
}
// File Data

View File

@ -5,6 +5,7 @@
(byte) Point::x
(byte) Point::y
(const byte*) SCREEN = (byte*) 1024
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(void()) main()
(label) main::@return
(struct Point) main::point1 loadstore zp[2]:2

View File

@ -3,16 +3,20 @@
:BasicUpstart(main)
.pc = $80d "Program"
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1
main: {
.label point1 = 2
lda #2
sta.z point1
lda #3
sta point1+OFFSET_STRUCT_POINT_Y
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta point1-1,y
dey
bne !-
lda.z point1
sta SCREEN
lda point1+OFFSET_STRUCT_POINT_Y
sta SCREEN+1
rts
}
__0: .byte 2, 3

View File

@ -10,11 +10,10 @@
(void()) main()
main: scope:[main] from @1
[4] *((byte*)&(struct Point) main::point1) ← (byte) 2
[5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
[6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1)
[7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y)
[4] *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
[5] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1)
[6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y)
to:main::@return
main::@return: scope:[main] from main
[8] return
[7] return
to:@return

View File

@ -1,5 +1,4 @@
Adding struct value member variable copy *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
Adding struct value member variable copy *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
Adding struct value member variable copy *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
Replacing struct member reference (struct Point) main::point1.x with member unwinding reference *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X)
Replacing struct member reference (struct Point) main::point1.y with member unwinding reference *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y)
@ -9,9 +8,7 @@ CONTROL FLOW GRAPH SSA
(void()) main()
main: scope:[main] from @1
*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
(struct Point) main::point1 ← struct-unwound {*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y)}
*(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
*((const byte*) SCREEN + (number) 0) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X)
*((const byte*) SCREEN + (number) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y)
to:main::@return
@ -26,6 +23,7 @@ main::@return: scope:[main] from main
@end: scope:[] from @2
SYMBOL TABLE SSA
(const struct Point) $0 = { x: (byte) 2, y: (byte) 3 }
(label) @1
(label) @2
(label) @begin
@ -35,6 +33,7 @@ SYMBOL TABLE SSA
(byte) Point::x
(byte) Point::y
(const byte*) SCREEN = (byte*)(number) $400
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(void()) main()
(label) main::@return
(struct Point) main::point1 loadstore
@ -49,10 +48,8 @@ Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) 0
Finalized unsigned number type (byte) 1
Successful SSA optimization PassNFinalizeNumberTypeConversions
Removing C-classic struct-unwound assignment [2] (struct Point) main::point1 ← struct-unwound {*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y)}
Simplifying expression containing zero (byte*)&main::point1 in [0] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
Simplifying expression containing zero (byte*)&main::point1 in [3] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero SCREEN in [3] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) main::point1)
Simplifying expression containing zero (byte*)&main::point1 in [1] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero SCREEN in [1] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) main::point1)
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant (const byte) OFFSET_STRUCT_POINT_X
Successful SSA optimization PassNEliminateUnusedVars
@ -85,13 +82,12 @@ FINAL CONTROL FLOW GRAPH
(void()) main()
main: scope:[main] from @1
[4] *((byte*)&(struct Point) main::point1) ← (byte) 2
[5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
[6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1)
[7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y)
[4] *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
[5] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1)
[6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y)
to:main::@return
main::@return: scope:[main] from main
[8] return
[7] return
to:@return
@ -117,6 +113,7 @@ Target platform is c64basic / MOS6502X
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1
// @begin
__bbegin:
@ -135,31 +132,32 @@ __bend:
// main
main: {
.label point1 = 2
// [4] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z point1
// [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta point1+OFFSET_STRUCT_POINT_Y
// [6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2
// [4] *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta point1-1,y
dey
bne !-
// [5] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2
lda.z point1
sta SCREEN
// [7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda point1+OFFSET_STRUCT_POINT_Y
sta SCREEN+1
jmp __breturn
// main::@return
__breturn:
// [8] return
// [7] return
rts
}
// File Data
__0: .byte 2, 3
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] *((byte*)&(struct Point) main::point1) ← (byte) 2 [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a
Statement [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a
Statement [6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a
Statement [7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [4] *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a reg byte y
Statement [5] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a
Statement [6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) [ ] ( main:2 [ ] ) always clobbers reg byte a
Potential registers zp[2]:2 [ main::point1 ] : zp[2]:2 ,
REGISTER UPLIFT SCOPES
@ -167,9 +165,9 @@ Uplift Scope [Point]
Uplift Scope [main] 0: zp[2]:2 [ main::point1 ]
Uplift Scope []
Uplifting [Point] best 47 combination
Uplifting [main] best 47 combination zp[2]:2 [ main::point1 ]
Uplifting [] best 47 combination
Uplifting [Point] best 52 combination
Uplifting [main] best 52 combination zp[2]:2 [ main::point1 ]
Uplifting [] best 52 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
@ -180,6 +178,7 @@ ASSEMBLER BEFORE OPTIMIZATION
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1
// @begin
__bbegin:
@ -198,25 +197,27 @@ __bend:
// main
main: {
.label point1 = 2
// [4] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z point1
// [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta point1+OFFSET_STRUCT_POINT_Y
// [6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2
// [4] *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta point1-1,y
dey
bne !-
// [5] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2
lda.z point1
sta SCREEN
// [7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda point1+OFFSET_STRUCT_POINT_Y
sta SCREEN+1
jmp __breturn
// main::@return
__breturn:
// [8] return
// [7] return
rts
}
// File Data
__0: .byte 2, 3
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
@ -238,6 +239,7 @@ Removing instruction __b1:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
(const struct Point) $0 = { x: (byte) 2, y: (byte) 3 }
(label) @1
(label) @begin
(label) @end
@ -245,6 +247,7 @@ FINAL SYMBOL TABLE
(byte) Point::x
(byte) Point::y
(const byte*) SCREEN = (byte*) 1024
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(void()) main()
(label) main::@return
(struct Point) main::point1 loadstore zp[2]:2
@ -253,7 +256,7 @@ zp[2]:2 [ main::point1 ]
FINAL ASSEMBLER
Score: 32
Score: 37
// File Comments
// Minimal struct with C-Standard behavior - initializer
@ -263,6 +266,7 @@ Score: 32
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1
// @begin
// [1] phi from @begin to @1 [phi:@begin->@1]
@ -274,24 +278,26 @@ Score: 32
main: {
.label point1 = 2
// point1 = { 2, 3 }
// [4] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z point1
// [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta point1+OFFSET_STRUCT_POINT_Y
// [4] *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta point1-1,y
dey
bne !-
// SCREEN[0] = point1.x
// [6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2
// [5] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2
lda.z point1
sta SCREEN
// SCREEN[1] = point1.y
// [7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda point1+OFFSET_STRUCT_POINT_Y
sta SCREEN+1
// main::@return
// }
// [8] return
// [7] return
rts
}
// File Data
__0: .byte 2, 3

View File

@ -1,3 +1,4 @@
(const struct Point) $0 = { x: (byte) 2, y: (byte) 3 }
(label) @1
(label) @begin
(label) @end
@ -5,6 +6,7 @@
(byte) Point::x
(byte) Point::y
(const byte*) SCREEN = (byte*) 1024
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(void()) main()
(label) main::@return
(struct Point) main::point1 loadstore zp[2]:2

View File

@ -3,15 +3,17 @@
:BasicUpstart(main)
.pc = $80d "Program"
.label SCREEN = $400
.const SIZEOF_STRUCT_VECTOR = 4
.const OFFSET_STRUCT_VECTOR_Q = 2
.const OFFSET_STRUCT_POINT_Y = 1
main: {
.label v = 2
ldy #SIZEOF_STRUCT_VECTOR
lda #0
sta.z v
sta v+OFFSET_STRUCT_POINT_Y
sta v+OFFSET_STRUCT_VECTOR_Q
sta v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
!:
dey
sta v,y
bne !-
lda #2
sta.z v
lda #3

View File

@ -10,19 +10,16 @@
(void()) main()
main: scope:[main] from @1
[4] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte) 0
[5] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0
[6] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (byte) 0
[7] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0
[8] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte) 2
[9] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
[10] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (byte) 4
[11] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5
[12] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v)
[13] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y)
[14] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q)
[15] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y)
[4] *(&(struct Vector) main::v) ← memset(struct Vector, (const byte) SIZEOF_STRUCT_VECTOR)
[5] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte) 2
[6] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
[7] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (byte) 4
[8] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5
[9] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v)
[10] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y)
[11] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q)
[12] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y)
to:main::@return
main::@return: scope:[main] from main
[16] return
[13] return
to:@return

View File

@ -1,5 +1,4 @@
Adding struct value member variable copy *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P) ← { x: (byte) 0, y: (byte) 0 }
Adding struct value member variable copy *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← { x: (byte) 0, y: (byte) 0 }
Adding struct value member variable copy *(&(struct Vector) main::v) ← memset(struct Vector, (const byte) SIZEOF_STRUCT_VECTOR)
Replacing struct member reference (struct Vector) main::v.p with member unwinding reference *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P)
Replacing struct member reference (struct Vector) main::v.p with member unwinding reference *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P)
Replacing struct member reference (struct Vector) main::v.q with member unwinding reference *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q)
@ -8,10 +7,6 @@ Replacing struct member reference (struct Vector) main::v.p with member unwindin
Replacing struct member reference (struct Vector) main::v.p with member unwinding reference *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P)
Replacing struct member reference (struct Vector) main::v.q with member unwinding reference *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q)
Replacing struct member reference (struct Vector) main::v.q with member unwinding reference *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q)
Adding struct value member variable copy *((byte*~) main::$0) ← (byte) 0
Adding struct value member variable copy *((byte*~) main::$1) ← (byte) 0
Adding struct value member variable copy *((byte*~) main::$2) ← (byte) 0
Adding struct value member variable copy *((byte*~) main::$3) ← (byte) 0
Rewriting struct pointer member access *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P).x
Rewriting struct pointer member access *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P).y
Rewriting struct pointer member access *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q).x
@ -27,31 +22,23 @@ CONTROL FLOW GRAPH SSA
(void()) main()
main: scope:[main] from @1
*(&(struct Vector) main::v) ← memset(struct Vector, (const byte) SIZEOF_STRUCT_VECTOR)
(byte*~) main::$0 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_X
*((byte*~) main::$0) ← (byte) 0
*((byte*~) main::$0) ← (number) 2
(byte*~) main::$1 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_Y
*((byte*~) main::$1) ← (byte) 0
*((byte*~) main::$1) ← (number) 3
(byte*~) main::$2 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_X
*((byte*~) main::$2) ← (byte) 0
*((byte*~) main::$2) ← (number) 4
(byte*~) main::$3 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_Y
*((byte*~) main::$3) ← (byte) 0
(struct Vector) main::v ← struct-unwound {*((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P), *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q)}
*((byte*~) main::$3) ← (number) 5
(byte*~) main::$4 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_X
*((byte*~) main::$4) ← (number) 2
*((const byte*) SCREEN + (number) 0) ← *((byte*~) main::$4)
(byte*~) main::$5 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_Y
*((byte*~) main::$5) ← (number) 3
*((const byte*) SCREEN + (number) 1) ← *((byte*~) main::$5)
(byte*~) main::$6 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_X
*((byte*~) main::$6) ← (number) 4
*((const byte*) SCREEN + (number) 2) ← *((byte*~) main::$6)
(byte*~) main::$7 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_Y
*((byte*~) main::$7) ← (number) 5
(byte*~) main::$8 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_X
*((const byte*) SCREEN + (number) 0) ← *((byte*~) main::$8)
(byte*~) main::$9 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_Y
*((const byte*) SCREEN + (number) 1) ← *((byte*~) main::$9)
(byte*~) main::$10 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_X
*((const byte*) SCREEN + (number) 2) ← *((byte*~) main::$10)
(byte*~) main::$11 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_Y
*((const byte*) SCREEN + (number) 3) ← *((byte*~) main::$11)
*((const byte*) SCREEN + (number) 3) ← *((byte*~) main::$7)
to:main::@return
main::@return: scope:[main] from main
return
@ -75,37 +62,34 @@ SYMBOL TABLE SSA
(byte) Point::x
(byte) Point::y
(const byte*) SCREEN = (byte*)(number) $400
(const byte) SIZEOF_STRUCT_VECTOR = (byte) 4
(struct Point) Vector::p
(struct Point) Vector::q
(void()) main()
(byte*~) main::$0
(byte*~) main::$1
(byte*~) main::$10
(byte*~) main::$11
(byte*~) main::$2
(byte*~) main::$3
(byte*~) main::$4
(byte*~) main::$5
(byte*~) main::$6
(byte*~) main::$7
(byte*~) main::$8
(byte*~) main::$9
(label) main::@return
(struct Vector) main::v loadstore
Adding number conversion cast (unumber) 2 in *((byte*~) main::$4) ← (number) 2
Adding number conversion cast (unumber) 3 in *((byte*~) main::$5) ← (number) 3
Adding number conversion cast (unumber) 4 in *((byte*~) main::$6) ← (number) 4
Adding number conversion cast (unumber) 5 in *((byte*~) main::$7) ← (number) 5
Adding number conversion cast (unumber) 0 in *((const byte*) SCREEN + (number) 0) ← *((byte*~) main::$8)
Adding number conversion cast (unumber) 1 in *((const byte*) SCREEN + (number) 1) ← *((byte*~) main::$9)
Adding number conversion cast (unumber) 2 in *((const byte*) SCREEN + (number) 2) ← *((byte*~) main::$10)
Adding number conversion cast (unumber) 3 in *((const byte*) SCREEN + (number) 3) ← *((byte*~) main::$11)
Adding number conversion cast (unumber) 2 in *((byte*~) main::$0) ← (number) 2
Adding number conversion cast (unumber) 3 in *((byte*~) main::$1) ← (number) 3
Adding number conversion cast (unumber) 4 in *((byte*~) main::$2) ← (number) 4
Adding number conversion cast (unumber) 5 in *((byte*~) main::$3) ← (number) 5
Adding number conversion cast (unumber) 0 in *((const byte*) SCREEN + (number) 0) ← *((byte*~) main::$4)
Adding number conversion cast (unumber) 1 in *((const byte*) SCREEN + (number) 1) ← *((byte*~) main::$5)
Adding number conversion cast (unumber) 2 in *((const byte*) SCREEN + (number) 2) ← *((byte*~) main::$6)
Adding number conversion cast (unumber) 3 in *((const byte*) SCREEN + (number) 3) ← *((byte*~) main::$7)
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast *((byte*~) main::$4) ← (unumber)(number) 2
Inlining cast *((byte*~) main::$5) ← (unumber)(number) 3
Inlining cast *((byte*~) main::$6) ← (unumber)(number) 4
Inlining cast *((byte*~) main::$7) ← (unumber)(number) 5
Inlining cast *((byte*~) main::$0) ← (unumber)(number) 2
Inlining cast *((byte*~) main::$1) ← (unumber)(number) 3
Inlining cast *((byte*~) main::$2) ← (unumber)(number) 4
Inlining cast *((byte*~) main::$3) ← (unumber)(number) 5
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (byte*) 1024
Simplifying constant integer cast 2
@ -126,19 +110,14 @@ Finalized unsigned number type (byte) 1
Finalized unsigned number type (byte) 2
Finalized unsigned number type (byte) 3
Successful SSA optimization PassNFinalizeNumberTypeConversions
Removing C-classic struct-unwound assignment [8] (struct Vector) main::v ← struct-unwound {*((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P), *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q)}
Constant right-side identified [0] (byte*~) main::$0 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [2] (byte*~) main::$1 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_Y
Constant right-side identified [4] (byte*~) main::$2 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [6] (byte*~) main::$3 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_Y
Constant right-side identified [1] (byte*~) main::$0 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [3] (byte*~) main::$1 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_Y
Constant right-side identified [5] (byte*~) main::$2 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [7] (byte*~) main::$3 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_Y
Constant right-side identified [9] (byte*~) main::$4 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [11] (byte*~) main::$5 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_Y
Constant right-side identified [13] (byte*~) main::$6 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [15] (byte*~) main::$7 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_Y
Constant right-side identified [17] (byte*~) main::$8 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [19] (byte*~) main::$9 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_Y
Constant right-side identified [21] (byte*~) main::$10 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [23] (byte*~) main::$11 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_Y
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant (const byte*) main::$0 = (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_P+OFFSET_STRUCT_POINT_X
Constant (const byte*) main::$1 = (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_P+OFFSET_STRUCT_POINT_Y
@ -148,10 +127,6 @@ Constant (const byte*) main::$4 = (byte*)(struct Point*)&main::v+OFFSET_STRUCT_V
Constant (const byte*) main::$5 = (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_P+OFFSET_STRUCT_POINT_Y
Constant (const byte*) main::$6 = (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_X
Constant (const byte*) main::$7 = (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
Constant (const byte*) main::$8 = (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_P+OFFSET_STRUCT_POINT_X
Constant (const byte*) main::$9 = (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_P+OFFSET_STRUCT_POINT_Y
Constant (const byte*) main::$10 = (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_X
Constant (const byte*) main::$11 = (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_P in
Simplifying expression containing zero (struct Point*)&main::v in
@ -161,17 +136,11 @@ Simplifying expression containing zero (byte*)(struct Point*)&main::v+OFFSET_STR
Simplifying expression containing zero (struct Point*)&main::v in
Simplifying expression containing zero (struct Point*)&main::v in
Simplifying expression containing zero (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_Q in
Simplifying expression containing zero (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_P in
Simplifying expression containing zero (struct Point*)&main::v in
Simplifying expression containing zero (struct Point*)&main::v in
Simplifying expression containing zero (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_Q in
Simplifying expression containing zero SCREEN in [18] *((const byte*) SCREEN + (byte) 0) ← *((const byte*) main::$8)
Simplifying expression containing zero SCREEN in [10] *((const byte*) SCREEN + (byte) 0) ← *((const byte*) main::$4)
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant (const byte) OFFSET_STRUCT_VECTOR_P
Eliminating unused constant (const byte) OFFSET_STRUCT_POINT_X
Successful SSA optimization PassNEliminateUnusedVars
Constant inlined main::$10 = (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q
Constant inlined main::$11 = (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y
Constant inlined main::$1 = (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y
Constant inlined main::$2 = (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q
Constant inlined main::$0 = (byte*)(struct Point*)&(struct Vector) main::v
@ -179,9 +148,7 @@ Constant inlined main::$5 = (byte*)(struct Point*)&(struct Vector) main::v+(cons
Constant inlined main::$6 = (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q
Constant inlined main::$3 = (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y
Constant inlined main::$4 = (byte*)(struct Point*)&(struct Vector) main::v
Constant inlined main::$9 = (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y
Constant inlined main::$7 = (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y
Constant inlined main::$8 = (byte*)(struct Point*)&(struct Vector) main::v
Successful SSA optimization Pass2ConstantInlining
Consolidated array index constant in *(SCREEN+1)
Consolidated array index constant in *(SCREEN+2)
@ -214,21 +181,18 @@ FINAL CONTROL FLOW GRAPH
(void()) main()
main: scope:[main] from @1
[4] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte) 0
[5] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0
[6] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (byte) 0
[7] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0
[8] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte) 2
[9] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
[10] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (byte) 4
[11] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5
[12] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v)
[13] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y)
[14] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q)
[15] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y)
[4] *(&(struct Vector) main::v) ← memset(struct Vector, (const byte) SIZEOF_STRUCT_VECTOR)
[5] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte) 2
[6] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
[7] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (byte) 4
[8] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5
[9] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v)
[10] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y)
[11] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q)
[12] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y)
to:main::@return
main::@return: scope:[main] from main
[16] return
[13] return
to:@return
@ -256,6 +220,7 @@ Target platform is c64basic / MOS6502X
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_VECTOR = 4
.const OFFSET_STRUCT_VECTOR_Q = 2
.const OFFSET_STRUCT_POINT_Y = 1
// @begin
@ -275,63 +240,55 @@ __bend:
// main
main: {
.label v = 2
// [4] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte) 0 -- _deref_pbuc1=vbuc2
// [4] *(&(struct Vector) main::v) ← memset(struct Vector, (const byte) SIZEOF_STRUCT_VECTOR) -- _deref_pssc1=_memset_vbuc2
ldy #SIZEOF_STRUCT_VECTOR
lda #0
sta.z v
// [5] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0 -- _deref_pbuc1=vbuc2
lda #0
sta v+OFFSET_STRUCT_POINT_Y
// [6] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (byte) 0 -- _deref_pbuc1=vbuc2
lda #0
sta v+OFFSET_STRUCT_VECTOR_Q
// [7] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0 -- _deref_pbuc1=vbuc2
lda #0
sta v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
// [8] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte) 2 -- _deref_pbuc1=vbuc2
!:
dey
sta v,y
bne !-
// [5] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z v
// [9] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
// [6] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta v+OFFSET_STRUCT_POINT_Y
// [10] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (byte) 4 -- _deref_pbuc1=vbuc2
// [7] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (byte) 4 -- _deref_pbuc1=vbuc2
lda #4
sta v+OFFSET_STRUCT_VECTOR_Q
// [11] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5 -- _deref_pbuc1=vbuc2
// [8] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5 -- _deref_pbuc1=vbuc2
lda #5
sta v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
// [12] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v) -- _deref_pbuc1=_deref_pbuc2
// [9] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v) -- _deref_pbuc1=_deref_pbuc2
lda.z v
sta SCREEN
// [13] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [10] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_POINT_Y
sta SCREEN+1
// [14] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) -- _deref_pbuc1=_deref_pbuc2
// [11] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_VECTOR_Q
sta SCREEN+2
// [15] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [12] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
sta SCREEN+3
jmp __breturn
// main::@return
__breturn:
// [16] return
// [13] return
rts
}
// File Data
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte) 0 [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [5] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0 [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [6] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (byte) 0 [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [7] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0 [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [8] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte) 2 [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [9] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [10] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (byte) 4 [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [11] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5 [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [12] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v) [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [13] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [14] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [15] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [4] *(&(struct Vector) main::v) ← memset(struct Vector, (const byte) SIZEOF_STRUCT_VECTOR) [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a reg byte y
Statement [5] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte) 2 [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [6] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [7] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (byte) 4 [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [8] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5 [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [9] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v) [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [10] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [11] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [12] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) [ ] ( main:2 [ ] ) always clobbers reg byte a
Potential registers zp[4]:2 [ main::v ] : zp[4]:2 ,
REGISTER UPLIFT SCOPES
@ -340,10 +297,10 @@ Uplift Scope [Vector]
Uplift Scope [main] 0: zp[4]:2 [ main::v ]
Uplift Scope []
Uplifting [Point] best 98 combination
Uplifting [Vector] best 98 combination
Uplifting [main] best 98 combination zp[4]:2 [ main::v ]
Uplifting [] best 98 combination
Uplifting [Point] best 88 combination
Uplifting [Vector] best 88 combination
Uplifting [main] best 88 combination zp[4]:2 [ main::v ]
Uplifting [] best 88 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
@ -354,6 +311,7 @@ ASSEMBLER BEFORE OPTIMIZATION
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_VECTOR = 4
.const OFFSET_STRUCT_VECTOR_Q = 2
.const OFFSET_STRUCT_POINT_Y = 1
// @begin
@ -373,46 +331,41 @@ __bend:
// main
main: {
.label v = 2
// [4] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte) 0 -- _deref_pbuc1=vbuc2
// [4] *(&(struct Vector) main::v) ← memset(struct Vector, (const byte) SIZEOF_STRUCT_VECTOR) -- _deref_pssc1=_memset_vbuc2
ldy #SIZEOF_STRUCT_VECTOR
lda #0
sta.z v
// [5] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0 -- _deref_pbuc1=vbuc2
lda #0
sta v+OFFSET_STRUCT_POINT_Y
// [6] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (byte) 0 -- _deref_pbuc1=vbuc2
lda #0
sta v+OFFSET_STRUCT_VECTOR_Q
// [7] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0 -- _deref_pbuc1=vbuc2
lda #0
sta v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
// [8] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte) 2 -- _deref_pbuc1=vbuc2
!:
dey
sta v,y
bne !-
// [5] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z v
// [9] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
// [6] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta v+OFFSET_STRUCT_POINT_Y
// [10] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (byte) 4 -- _deref_pbuc1=vbuc2
// [7] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (byte) 4 -- _deref_pbuc1=vbuc2
lda #4
sta v+OFFSET_STRUCT_VECTOR_Q
// [11] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5 -- _deref_pbuc1=vbuc2
// [8] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5 -- _deref_pbuc1=vbuc2
lda #5
sta v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
// [12] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v) -- _deref_pbuc1=_deref_pbuc2
// [9] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v) -- _deref_pbuc1=_deref_pbuc2
lda.z v
sta SCREEN
// [13] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [10] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_POINT_Y
sta SCREEN+1
// [14] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) -- _deref_pbuc1=_deref_pbuc2
// [11] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_VECTOR_Q
sta SCREEN+2
// [15] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [12] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
sta SCREEN+3
jmp __breturn
// main::@return
__breturn:
// [16] return
// [13] return
rts
}
// File Data
@ -422,10 +375,6 @@ Removing instruction jmp __b1
Removing instruction jmp __bend
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction lda #0
Removing instruction lda #0
Removing instruction lda #0
Succesful ASM optimization Pass5UnnecesaryLoadElimination
Replacing label __bbegin with __b1
Removing instruction __bbegin:
Removing instruction __b1_from___bbegin:
@ -449,6 +398,7 @@ FINAL SYMBOL TABLE
(byte) Point::x
(byte) Point::y
(const byte*) SCREEN = (byte*) 1024
(const byte) SIZEOF_STRUCT_VECTOR = (byte) 4
(struct Point) Vector::p
(struct Point) Vector::q
(void()) main()
@ -459,7 +409,7 @@ zp[4]:2 [ main::v ]
FINAL ASSEMBLER
Score: 77
Score: 73
// File Comments
// Minimal struct with C-Standard behavior - struct containing struct
@ -469,6 +419,7 @@ Score: 77
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_VECTOR = 4
.const OFFSET_STRUCT_VECTOR_Q = 2
.const OFFSET_STRUCT_POINT_Y = 1
// @begin
@ -481,50 +432,48 @@ Score: 77
main: {
.label v = 2
// v
// [4] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte) 0 -- _deref_pbuc1=vbuc2
// [4] *(&(struct Vector) main::v) ← memset(struct Vector, (const byte) SIZEOF_STRUCT_VECTOR) -- _deref_pssc1=_memset_vbuc2
ldy #SIZEOF_STRUCT_VECTOR
lda #0
sta.z v
// [5] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0 -- _deref_pbuc1=vbuc2
sta v+OFFSET_STRUCT_POINT_Y
// [6] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (byte) 0 -- _deref_pbuc1=vbuc2
sta v+OFFSET_STRUCT_VECTOR_Q
// [7] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0 -- _deref_pbuc1=vbuc2
sta v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
!:
dey
sta v,y
bne !-
// v.p.x = 2
// [8] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte) 2 -- _deref_pbuc1=vbuc2
// [5] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z v
// v.p.y = 3
// [9] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
// [6] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta v+OFFSET_STRUCT_POINT_Y
// v.q.x = 4
// [10] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (byte) 4 -- _deref_pbuc1=vbuc2
// [7] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (byte) 4 -- _deref_pbuc1=vbuc2
lda #4
sta v+OFFSET_STRUCT_VECTOR_Q
// v.q.y = 5
// [11] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5 -- _deref_pbuc1=vbuc2
// [8] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5 -- _deref_pbuc1=vbuc2
lda #5
sta v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
// SCREEN[0] = v.p.x
// [12] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v) -- _deref_pbuc1=_deref_pbuc2
// [9] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v) -- _deref_pbuc1=_deref_pbuc2
lda.z v
sta SCREEN
// SCREEN[1] = v.p.y
// [13] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [10] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_POINT_Y
sta SCREEN+1
// SCREEN[2] = v.q.x
// [14] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) -- _deref_pbuc1=_deref_pbuc2
// [11] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_VECTOR_Q
sta SCREEN+2
// SCREEN[3] = v.q.y
// [15] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [12] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
sta SCREEN+3
// main::@return
// }
// [16] return
// [13] return
rts
}
// File Data

View File

@ -6,6 +6,7 @@
(byte) Point::x
(byte) Point::y
(const byte*) SCREEN = (byte*) 1024
(const byte) SIZEOF_STRUCT_VECTOR = (byte) 4
(struct Point) Vector::p
(struct Point) Vector::q
(void()) main()

View File

@ -3,18 +3,17 @@
:BasicUpstart(main)
.pc = $80d "Program"
.label SCREEN = $400
.const SIZEOF_STRUCT_VECTOR = 4
.const OFFSET_STRUCT_VECTOR_Q = 2
.const OFFSET_STRUCT_POINT_Y = 1
main: {
.label v = 2
lda #2
sta.z v
lda #3
sta v+OFFSET_STRUCT_POINT_Y
lda #4
sta v+OFFSET_STRUCT_VECTOR_Q
lda #5
sta v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
ldy #SIZEOF_STRUCT_VECTOR
!:
lda __0-1,y
sta v-1,y
dey
bne !-
lda.z v
sta SCREEN
lda v+OFFSET_STRUCT_POINT_Y
@ -25,3 +24,4 @@ main: {
sta SCREEN+3
rts
}
__0: .byte 2, 3, 4, 5

View File

@ -10,15 +10,12 @@
(void()) main()
main: scope:[main] from @1
[4] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte) 2
[5] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
[6] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (byte) 4
[7] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5
[8] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v)
[9] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y)
[10] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q)
[11] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y)
[4] *(&(struct Vector) main::v) ← memcpy(*(&(const struct Vector) $0), struct Vector, (const byte) SIZEOF_STRUCT_VECTOR)
[5] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v)
[6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y)
[7] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q)
[8] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y)
to:main::@return
main::@return: scope:[main] from main
[12] return
[9] return
to:@return

View File

@ -1,13 +1,8 @@
Adding struct value member variable copy *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P) ← { x: (byte) 2, y: (byte) 3 }
Adding struct value member variable copy *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← { x: (byte) 4, y: (byte) 5 }
Adding struct value member variable copy *(&(struct Vector) main::v) ← memcpy(*(&(const struct Vector) $0), struct Vector, (const byte) SIZEOF_STRUCT_VECTOR)
Replacing struct member reference (struct Vector) main::v.p with member unwinding reference *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P)
Replacing struct member reference (struct Vector) main::v.p with member unwinding reference *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P)
Replacing struct member reference (struct Vector) main::v.q with member unwinding reference *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q)
Replacing struct member reference (struct Vector) main::v.q with member unwinding reference *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q)
Adding struct value member variable copy *((byte*~) main::$0) ← (byte) 2
Adding struct value member variable copy *((byte*~) main::$1) ← (byte) 3
Adding struct value member variable copy *((byte*~) main::$2) ← (byte) 4
Adding struct value member variable copy *((byte*~) main::$3) ← (byte) 5
Rewriting struct pointer member access *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P).x
Rewriting struct pointer member access *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P).y
Rewriting struct pointer member access *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q).x
@ -19,23 +14,15 @@ CONTROL FLOW GRAPH SSA
(void()) main()
main: scope:[main] from @1
*(&(struct Vector) main::v) ← memcpy(*(&(const struct Vector) $0), struct Vector, (const byte) SIZEOF_STRUCT_VECTOR)
(byte*~) main::$0 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_X
*((byte*~) main::$0) ← (byte) 2
*((const byte*) SCREEN + (number) 0) ← *((byte*~) main::$0)
(byte*~) main::$1 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_Y
*((byte*~) main::$1) ← (byte) 3
*((const byte*) SCREEN + (number) 1) ← *((byte*~) main::$1)
(byte*~) main::$2 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_X
*((byte*~) main::$2) ← (byte) 4
*((const byte*) SCREEN + (number) 2) ← *((byte*~) main::$2)
(byte*~) main::$3 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_Y
*((byte*~) main::$3) ← (byte) 5
(struct Vector) main::v ← struct-unwound {*((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P), *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q)}
(byte*~) main::$4 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_X
*((const byte*) SCREEN + (number) 0) ← *((byte*~) main::$4)
(byte*~) main::$5 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_Y
*((const byte*) SCREEN + (number) 1) ← *((byte*~) main::$5)
(byte*~) main::$6 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_X
*((const byte*) SCREEN + (number) 2) ← *((byte*~) main::$6)
(byte*~) main::$7 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_Y
*((const byte*) SCREEN + (number) 3) ← *((byte*~) main::$7)
*((const byte*) SCREEN + (number) 3) ← *((byte*~) main::$3)
to:main::@return
main::@return: scope:[main] from main
return
@ -48,6 +35,7 @@ main::@return: scope:[main] from main
@end: scope:[] from @2
SYMBOL TABLE SSA
(const struct Vector) $0 = { p: { x: (byte) 2, y: (byte) 3 }, q: { x: (byte) 4, y: (byte) 5 } }
(label) @1
(label) @2
(label) @begin
@ -59,6 +47,7 @@ SYMBOL TABLE SSA
(byte) Point::x
(byte) Point::y
(const byte*) SCREEN = (byte*)(number) $400
(const byte) SIZEOF_STRUCT_VECTOR = (byte) 4
(struct Point) Vector::p
(struct Point) Vector::q
(void()) main()
@ -66,17 +55,13 @@ SYMBOL TABLE SSA
(byte*~) main::$1
(byte*~) main::$2
(byte*~) main::$3
(byte*~) main::$4
(byte*~) main::$5
(byte*~) main::$6
(byte*~) main::$7
(label) main::@return
(struct Vector) main::v loadstore
Adding number conversion cast (unumber) 0 in *((const byte*) SCREEN + (number) 0) ← *((byte*~) main::$4)
Adding number conversion cast (unumber) 1 in *((const byte*) SCREEN + (number) 1) ← *((byte*~) main::$5)
Adding number conversion cast (unumber) 2 in *((const byte*) SCREEN + (number) 2) ← *((byte*~) main::$6)
Adding number conversion cast (unumber) 3 in *((const byte*) SCREEN + (number) 3) ← *((byte*~) main::$7)
Adding number conversion cast (unumber) 0 in *((const byte*) SCREEN + (number) 0) ← *((byte*~) main::$0)
Adding number conversion cast (unumber) 1 in *((const byte*) SCREEN + (number) 1) ← *((byte*~) main::$1)
Adding number conversion cast (unumber) 2 in *((const byte*) SCREEN + (number) 2) ← *((byte*~) main::$2)
Adding number conversion cast (unumber) 3 in *((const byte*) SCREEN + (number) 3) ← *((byte*~) main::$3)
Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant pointer cast (byte*) 1024
Simplifying constant integer cast 0
@ -89,46 +74,29 @@ Finalized unsigned number type (byte) 1
Finalized unsigned number type (byte) 2
Finalized unsigned number type (byte) 3
Successful SSA optimization PassNFinalizeNumberTypeConversions
Removing C-classic struct-unwound assignment [8] (struct Vector) main::v ← struct-unwound {*((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P), *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q)}
Constant right-side identified [0] (byte*~) main::$0 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [2] (byte*~) main::$1 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_Y
Constant right-side identified [4] (byte*~) main::$2 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [6] (byte*~) main::$3 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_Y
Constant right-side identified [9] (byte*~) main::$4 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [11] (byte*~) main::$5 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_Y
Constant right-side identified [13] (byte*~) main::$6 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [15] (byte*~) main::$7 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_Y
Constant right-side identified [1] (byte*~) main::$0 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [3] (byte*~) main::$1 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_Y
Constant right-side identified [5] (byte*~) main::$2 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [7] (byte*~) main::$3 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_Y
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant (const byte*) main::$0 = (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_P+OFFSET_STRUCT_POINT_X
Constant (const byte*) main::$1 = (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_P+OFFSET_STRUCT_POINT_Y
Constant (const byte*) main::$2 = (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_X
Constant (const byte*) main::$3 = (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
Constant (const byte*) main::$4 = (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_P+OFFSET_STRUCT_POINT_X
Constant (const byte*) main::$5 = (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_P+OFFSET_STRUCT_POINT_Y
Constant (const byte*) main::$6 = (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_X
Constant (const byte*) main::$7 = (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_P in
Simplifying expression containing zero (struct Point*)&main::v in
Simplifying expression containing zero (struct Point*)&main::v in
Simplifying expression containing zero (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_Q in
Simplifying expression containing zero (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_P in
Simplifying expression containing zero (struct Point*)&main::v in
Simplifying expression containing zero (struct Point*)&main::v in
Simplifying expression containing zero (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_Q in
Simplifying expression containing zero SCREEN in [10] *((const byte*) SCREEN + (byte) 0) ← *((const byte*) main::$4)
Simplifying expression containing zero SCREEN in [2] *((const byte*) SCREEN + (byte) 0) ← *((const byte*) main::$0)
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant (const byte) OFFSET_STRUCT_VECTOR_P
Eliminating unused constant (const byte) OFFSET_STRUCT_POINT_X
Successful SSA optimization PassNEliminateUnusedVars
Constant inlined main::$3 = (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y
Constant inlined main::$1 = (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y
Constant inlined main::$2 = (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q
Constant inlined main::$0 = (byte*)(struct Point*)&(struct Vector) main::v
Constant inlined main::$5 = (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y
Constant inlined main::$6 = (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q
Constant inlined main::$3 = (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y
Constant inlined main::$4 = (byte*)(struct Point*)&(struct Vector) main::v
Constant inlined main::$7 = (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y
Successful SSA optimization Pass2ConstantInlining
Consolidated array index constant in *(SCREEN+1)
Consolidated array index constant in *(SCREEN+2)
@ -161,17 +129,14 @@ FINAL CONTROL FLOW GRAPH
(void()) main()
main: scope:[main] from @1
[4] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte) 2
[5] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
[6] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (byte) 4
[7] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5
[8] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v)
[9] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y)
[10] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q)
[11] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y)
[4] *(&(struct Vector) main::v) ← memcpy(*(&(const struct Vector) $0), struct Vector, (const byte) SIZEOF_STRUCT_VECTOR)
[5] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v)
[6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y)
[7] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q)
[8] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y)
to:main::@return
main::@return: scope:[main] from main
[12] return
[9] return
to:@return
@ -199,6 +164,7 @@ Target platform is c64basic / MOS6502X
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_VECTOR = 4
.const OFFSET_STRUCT_VECTOR_Q = 2
.const OFFSET_STRUCT_POINT_Y = 1
// @begin
@ -218,47 +184,40 @@ __bend:
// main
main: {
.label v = 2
// [4] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z v
// [5] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta v+OFFSET_STRUCT_POINT_Y
// [6] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (byte) 4 -- _deref_pbuc1=vbuc2
lda #4
sta v+OFFSET_STRUCT_VECTOR_Q
// [7] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5 -- _deref_pbuc1=vbuc2
lda #5
sta v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
// [8] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v) -- _deref_pbuc1=_deref_pbuc2
// [4] *(&(struct Vector) main::v) ← memcpy(*(&(const struct Vector) $0), struct Vector, (const byte) SIZEOF_STRUCT_VECTOR) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_VECTOR
!:
lda __0-1,y
sta v-1,y
dey
bne !-
// [5] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v) -- _deref_pbuc1=_deref_pbuc2
lda.z v
sta SCREEN
// [9] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_POINT_Y
sta SCREEN+1
// [10] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) -- _deref_pbuc1=_deref_pbuc2
// [7] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_VECTOR_Q
sta SCREEN+2
// [11] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [8] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
sta SCREEN+3
jmp __breturn
// main::@return
__breturn:
// [12] return
// [9] return
rts
}
// File Data
__0: .byte 2, 3, 4, 5
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte) 2 [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [5] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [6] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (byte) 4 [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [7] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5 [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [8] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v) [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [9] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [10] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [11] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [4] *(&(struct Vector) main::v) ← memcpy(*(&(const struct Vector) $0), struct Vector, (const byte) SIZEOF_STRUCT_VECTOR) [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a reg byte y
Statement [5] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v) [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [7] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [8] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) [ ] ( main:2 [ ] ) always clobbers reg byte a
Potential registers zp[4]:2 [ main::v ] : zp[4]:2 ,
REGISTER UPLIFT SCOPES
@ -267,10 +226,10 @@ Uplift Scope [Vector]
Uplift Scope [main] 0: zp[4]:2 [ main::v ]
Uplift Scope []
Uplifting [Point] best 75 combination
Uplifting [Vector] best 75 combination
Uplifting [main] best 75 combination zp[4]:2 [ main::v ]
Uplifting [] best 75 combination
Uplifting [Point] best 68 combination
Uplifting [Vector] best 68 combination
Uplifting [main] best 68 combination zp[4]:2 [ main::v ]
Uplifting [] best 68 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
@ -281,6 +240,7 @@ ASSEMBLER BEFORE OPTIMIZATION
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_VECTOR = 4
.const OFFSET_STRUCT_VECTOR_Q = 2
.const OFFSET_STRUCT_POINT_Y = 1
// @begin
@ -300,37 +260,33 @@ __bend:
// main
main: {
.label v = 2
// [4] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z v
// [5] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta v+OFFSET_STRUCT_POINT_Y
// [6] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (byte) 4 -- _deref_pbuc1=vbuc2
lda #4
sta v+OFFSET_STRUCT_VECTOR_Q
// [7] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5 -- _deref_pbuc1=vbuc2
lda #5
sta v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
// [8] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v) -- _deref_pbuc1=_deref_pbuc2
// [4] *(&(struct Vector) main::v) ← memcpy(*(&(const struct Vector) $0), struct Vector, (const byte) SIZEOF_STRUCT_VECTOR) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_VECTOR
!:
lda __0-1,y
sta v-1,y
dey
bne !-
// [5] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v) -- _deref_pbuc1=_deref_pbuc2
lda.z v
sta SCREEN
// [9] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_POINT_Y
sta SCREEN+1
// [10] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) -- _deref_pbuc1=_deref_pbuc2
// [7] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_VECTOR_Q
sta SCREEN+2
// [11] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [8] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
sta SCREEN+3
jmp __breturn
// main::@return
__breturn:
// [12] return
// [9] return
rts
}
// File Data
__0: .byte 2, 3, 4, 5
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
@ -352,6 +308,7 @@ Removing instruction __b1:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
(const struct Vector) $0 = { p: { x: (byte) 2, y: (byte) 3 }, q: { x: (byte) 4, y: (byte) 5 } }
(label) @1
(label) @begin
(label) @end
@ -360,6 +317,7 @@ FINAL SYMBOL TABLE
(byte) Point::x
(byte) Point::y
(const byte*) SCREEN = (byte*) 1024
(const byte) SIZEOF_STRUCT_VECTOR = (byte) 4
(struct Point) Vector::p
(struct Point) Vector::q
(void()) main()
@ -370,7 +328,7 @@ zp[4]:2 [ main::v ]
FINAL ASSEMBLER
Score: 60
Score: 53
// File Comments
// Minimal struct with C-Standard behavior - struct containing struct with initializer
@ -380,6 +338,7 @@ Score: 60
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_VECTOR = 4
.const OFFSET_STRUCT_VECTOR_Q = 2
.const OFFSET_STRUCT_POINT_Y = 1
// @begin
@ -392,38 +351,34 @@ Score: 60
main: {
.label v = 2
// v = { {2, 3}, {4, 5} }
// [4] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z v
// [5] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta v+OFFSET_STRUCT_POINT_Y
// [6] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (byte) 4 -- _deref_pbuc1=vbuc2
lda #4
sta v+OFFSET_STRUCT_VECTOR_Q
// [7] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5 -- _deref_pbuc1=vbuc2
lda #5
sta v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
// [4] *(&(struct Vector) main::v) ← memcpy(*(&(const struct Vector) $0), struct Vector, (const byte) SIZEOF_STRUCT_VECTOR) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_VECTOR
!:
lda __0-1,y
sta v-1,y
dey
bne !-
// SCREEN[0] = v.p.x
// [8] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v) -- _deref_pbuc1=_deref_pbuc2
// [5] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v) -- _deref_pbuc1=_deref_pbuc2
lda.z v
sta SCREEN
// SCREEN[1] = v.p.y
// [9] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_POINT_Y
sta SCREEN+1
// SCREEN[2] = v.q.x
// [10] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) -- _deref_pbuc1=_deref_pbuc2
// [7] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_VECTOR_Q
sta SCREEN+2
// SCREEN[3] = v.q.y
// [11] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [8] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
sta SCREEN+3
// main::@return
// }
// [12] return
// [9] return
rts
}
// File Data
__0: .byte 2, 3, 4, 5

View File

@ -1,3 +1,4 @@
(const struct Vector) $0 = { p: { x: (byte) 2, y: (byte) 3 }, q: { x: (byte) 4, y: (byte) 5 } }
(label) @1
(label) @begin
(label) @end
@ -6,6 +7,7 @@
(byte) Point::x
(byte) Point::y
(const byte*) SCREEN = (byte*) 1024
(const byte) SIZEOF_STRUCT_VECTOR = (byte) 4
(struct Point) Vector::p
(struct Point) Vector::q
(void()) main()

View File

@ -3,25 +3,32 @@
:BasicUpstart(main)
.pc = $80d "Program"
.label SCREEN = $400
.const SIZEOF_STRUCT_VECTOR = 4
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_VECTOR_Q = 2
.const OFFSET_STRUCT_POINT_Y = 1
main: {
.label v = 2
.label p1 = 6
.label p2 = 8
ldy #SIZEOF_STRUCT_VECTOR
lda #0
sta.z v
sta v+OFFSET_STRUCT_POINT_Y
sta v+OFFSET_STRUCT_VECTOR_Q
sta v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
lda #2
sta.z p1
lda #3
sta p1+OFFSET_STRUCT_POINT_Y
lda #4
sta.z p2
lda #5
sta p2+OFFSET_STRUCT_POINT_Y
!:
dey
sta v,y
bne !-
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta p1-1,y
dey
bne !-
ldy #SIZEOF_STRUCT_POINT
!:
lda __1-1,y
sta p2-1,y
dey
bne !-
lda.z p1
sta.z v
lda p1+OFFSET_STRUCT_POINT_Y
@ -40,3 +47,5 @@ main: {
sta SCREEN+3
rts
}
__0: .byte 2, 3
__1: .byte 4, 5

View File

@ -10,23 +10,18 @@
(void()) main()
main: scope:[main] from @1
[4] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte) 0
[5] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0
[6] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (byte) 0
[7] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0
[8] *((byte*)&(struct Point) main::p1) ← (byte) 2
[9] *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
[10] *((byte*)&(struct Point) main::p2) ← (byte) 4
[11] *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5
[12] *((byte*)(struct Point*)&(struct Vector) main::v) ← *((byte*)&(struct Point) main::p1)
[13] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y)
[14] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← *((byte*)&(struct Point) main::p2)
[15] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y)
[16] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v)
[17] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y)
[18] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q)
[19] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y)
[4] *(&(struct Vector) main::v) ← memset(struct Vector, (const byte) SIZEOF_STRUCT_VECTOR)
[5] *(&(struct Point) main::p1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
[6] *(&(struct Point) main::p2) ← memcpy(*(&(const struct Point) $1), struct Point, (const byte) SIZEOF_STRUCT_POINT)
[7] *((byte*)(struct Point*)&(struct Vector) main::v) ← *((byte*)&(struct Point) main::p1)
[8] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y)
[9] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← *((byte*)&(struct Point) main::p2)
[10] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y)
[11] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v)
[12] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y)
[13] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q)
[14] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y)
to:main::@return
main::@return: scope:[main] from main
[20] return
[15] return
to:@return

View File

@ -1,23 +1,16 @@
Adding struct value member variable copy *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P) ← { x: (byte) 0, y: (byte) 0 }
Adding struct value member variable copy *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← { x: (byte) 0, y: (byte) 0 }
Adding struct value member variable copy *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
Adding struct value member variable copy *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
Adding struct value member variable copy *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 4
Adding struct value member variable copy *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5
Adding struct value member variable copy *(&(struct Vector) main::v) ← memset(struct Vector, (const byte) SIZEOF_STRUCT_VECTOR)
Adding struct value member variable copy *(&(struct Point) main::p1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
Adding struct value member variable copy *(&(struct Point) main::p2) ← memcpy(*(&(const struct Point) $1), struct Point, (const byte) SIZEOF_STRUCT_POINT)
Replacing struct member reference (struct Vector) main::v.p with member unwinding reference *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P)
Replacing struct member reference (struct Vector) main::v.q with member unwinding reference *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q)
Replacing struct member reference (struct Vector) main::v.p with member unwinding reference *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P)
Replacing struct member reference (struct Vector) main::v.p with member unwinding reference *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P)
Replacing struct member reference (struct Vector) main::v.q with member unwinding reference *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q)
Replacing struct member reference (struct Vector) main::v.q with member unwinding reference *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q)
Adding struct value member variable copy *((byte*~) main::$0) ← (byte) 0
Adding struct value member variable copy *((byte*~) main::$1) ← (byte) 0
Adding struct value member variable copy *((byte*~) main::$2) ← (byte) 0
Adding struct value member variable copy *((byte*~) main::$3) ← (byte) 0
Adding struct value member variable copy *((byte*~) main::$4) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_X)
Adding struct value member variable copy *((byte*~) main::$5) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y)
Adding struct value member variable copy *((byte*~) main::$6) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_X)
Adding struct value member variable copy *((byte*~) main::$7) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y)
Adding struct value member variable copy *((byte*~) main::$0) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_X)
Adding struct value member variable copy *((byte*~) main::$1) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y)
Adding struct value member variable copy *((byte*~) main::$2) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_X)
Adding struct value member variable copy *((byte*~) main::$3) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y)
Rewriting struct pointer member access *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P).x
Rewriting struct pointer member access *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P).y
Rewriting struct pointer member access *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q).x
@ -29,37 +22,25 @@ CONTROL FLOW GRAPH SSA
(void()) main()
main: scope:[main] from @1
*(&(struct Vector) main::v) ← memset(struct Vector, (const byte) SIZEOF_STRUCT_VECTOR)
*(&(struct Point) main::p1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
*(&(struct Point) main::p2) ← memcpy(*(&(const struct Point) $1), struct Point, (const byte) SIZEOF_STRUCT_POINT)
(byte*~) main::$0 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_X
*((byte*~) main::$0) ← (byte) 0
*((byte*~) main::$0) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_X)
(byte*~) main::$1 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_Y
*((byte*~) main::$1) ← (byte) 0
*((byte*~) main::$1) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y)
(byte*~) main::$2 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_X
*((byte*~) main::$2) ← (byte) 0
*((byte*~) main::$2) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_X)
(byte*~) main::$3 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_Y
*((byte*~) main::$3) ← (byte) 0
(struct Vector) main::v ← struct-unwound {*((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P), *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q)}
*((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
*((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
(struct Point) main::p1 ← struct-unwound {*((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y)}
*((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 4
*((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5
(struct Point) main::p2 ← struct-unwound {*((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y)}
*((byte*~) main::$3) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y)
(byte*~) main::$4 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_X
*((byte*~) main::$4) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_X)
*((const byte*) SCREEN + (number) 0) ← *((byte*~) main::$4)
(byte*~) main::$5 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_Y
*((byte*~) main::$5) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y)
*((const byte*) SCREEN + (number) 1) ← *((byte*~) main::$5)
(byte*~) main::$6 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_X
*((byte*~) main::$6) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_X)
*((const byte*) SCREEN + (number) 2) ← *((byte*~) main::$6)
(byte*~) main::$7 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_Y
*((byte*~) main::$7) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y)
(byte*~) main::$8 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_X
*((const byte*) SCREEN + (number) 0) ← *((byte*~) main::$8)
(byte*~) main::$9 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_Y
*((const byte*) SCREEN + (number) 1) ← *((byte*~) main::$9)
(byte*~) main::$10 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_X
*((const byte*) SCREEN + (number) 2) ← *((byte*~) main::$10)
(byte*~) main::$11 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_Y
*((const byte*) SCREEN + (number) 3) ← *((byte*~) main::$11)
*((const byte*) SCREEN + (number) 3) ← *((byte*~) main::$7)
to:main::@return
main::@return: scope:[main] from main
return
@ -72,6 +53,8 @@ main::@return: scope:[main] from main
@end: scope:[] from @2
SYMBOL TABLE SSA
(const struct Point) $0 = { x: (byte) 2, y: (byte) 3 }
(const struct Point) $1 = { x: (byte) 4, y: (byte) 5 }
(label) @1
(label) @2
(label) @begin
@ -83,30 +66,28 @@ SYMBOL TABLE SSA
(byte) Point::x
(byte) Point::y
(const byte*) SCREEN = (byte*)(number) $400
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(const byte) SIZEOF_STRUCT_VECTOR = (byte) 4
(struct Point) Vector::p
(struct Point) Vector::q
(void()) main()
(byte*~) main::$0
(byte*~) main::$1
(byte*~) main::$10
(byte*~) main::$11
(byte*~) main::$2
(byte*~) main::$3
(byte*~) main::$4
(byte*~) main::$5
(byte*~) main::$6
(byte*~) main::$7
(byte*~) main::$8
(byte*~) main::$9
(label) main::@return
(struct Point) main::p1 loadstore
(struct Point) main::p2 loadstore
(struct Vector) main::v loadstore
Adding number conversion cast (unumber) 0 in *((const byte*) SCREEN + (number) 0) ← *((byte*~) main::$8)
Adding number conversion cast (unumber) 1 in *((const byte*) SCREEN + (number) 1) ← *((byte*~) main::$9)
Adding number conversion cast (unumber) 2 in *((const byte*) SCREEN + (number) 2) ← *((byte*~) main::$10)
Adding number conversion cast (unumber) 3 in *((const byte*) SCREEN + (number) 3) ← *((byte*~) main::$11)
Adding number conversion cast (unumber) 0 in *((const byte*) SCREEN + (number) 0) ← *((byte*~) main::$4)
Adding number conversion cast (unumber) 1 in *((const byte*) SCREEN + (number) 1) ← *((byte*~) main::$5)
Adding number conversion cast (unumber) 2 in *((const byte*) SCREEN + (number) 2) ← *((byte*~) main::$6)
Adding number conversion cast (unumber) 3 in *((const byte*) SCREEN + (number) 3) ← *((byte*~) main::$7)
Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant pointer cast (byte*) 1024
Simplifying constant integer cast 0
@ -119,21 +100,14 @@ Finalized unsigned number type (byte) 1
Finalized unsigned number type (byte) 2
Finalized unsigned number type (byte) 3
Successful SSA optimization PassNFinalizeNumberTypeConversions
Removing C-classic struct-unwound assignment [8] (struct Vector) main::v ← struct-unwound {*((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P), *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q)}
Removing C-classic struct-unwound assignment [11] (struct Point) main::p1 ← struct-unwound {*((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y)}
Removing C-classic struct-unwound assignment [14] (struct Point) main::p2 ← struct-unwound {*((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y)}
Constant right-side identified [0] (byte*~) main::$0 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [2] (byte*~) main::$1 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_Y
Constant right-side identified [4] (byte*~) main::$2 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [6] (byte*~) main::$3 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_Y
Constant right-side identified [15] (byte*~) main::$4 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [17] (byte*~) main::$5 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_Y
Constant right-side identified [19] (byte*~) main::$6 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [21] (byte*~) main::$7 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_Y
Constant right-side identified [23] (byte*~) main::$8 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [25] (byte*~) main::$9 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_Y
Constant right-side identified [27] (byte*~) main::$10 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [29] (byte*~) main::$11 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_Y
Constant right-side identified [3] (byte*~) main::$0 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [5] (byte*~) main::$1 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_Y
Constant right-side identified [7] (byte*~) main::$2 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [9] (byte*~) main::$3 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_Y
Constant right-side identified [11] (byte*~) main::$4 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [13] (byte*~) main::$5 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_Y
Constant right-side identified [15] (byte*~) main::$6 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [17] (byte*~) main::$7 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_Y
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant (const byte*) main::$0 = (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_P+OFFSET_STRUCT_POINT_X
Constant (const byte*) main::$1 = (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_P+OFFSET_STRUCT_POINT_Y
@ -143,10 +117,6 @@ Constant (const byte*) main::$4 = (byte*)(struct Point*)&main::v+OFFSET_STRUCT_V
Constant (const byte*) main::$5 = (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_P+OFFSET_STRUCT_POINT_Y
Constant (const byte*) main::$6 = (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_X
Constant (const byte*) main::$7 = (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
Constant (const byte*) main::$8 = (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_P+OFFSET_STRUCT_POINT_X
Constant (const byte*) main::$9 = (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_P+OFFSET_STRUCT_POINT_Y
Constant (const byte*) main::$10 = (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_X
Constant (const byte*) main::$11 = (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_P in
Simplifying expression containing zero (struct Point*)&main::v in
@ -156,21 +126,13 @@ Simplifying expression containing zero (byte*)(struct Point*)&main::v+OFFSET_STR
Simplifying expression containing zero (struct Point*)&main::v in
Simplifying expression containing zero (struct Point*)&main::v in
Simplifying expression containing zero (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_Q in
Simplifying expression containing zero (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_P in
Simplifying expression containing zero (struct Point*)&main::v in
Simplifying expression containing zero (struct Point*)&main::v in
Simplifying expression containing zero (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_Q in
Simplifying expression containing zero (byte*)&main::p1 in [9] *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
Simplifying expression containing zero (byte*)&main::p2 in [12] *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 4
Simplifying expression containing zero (byte*)&main::p1 in [16] *((const byte*) main::$4) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero (byte*)&main::p2 in [20] *((const byte*) main::$6) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero SCREEN in [24] *((const byte*) SCREEN + (byte) 0) ← *((const byte*) main::$8)
Simplifying expression containing zero (byte*)&main::p1 in [4] *((const byte*) main::$0) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero (byte*)&main::p2 in [8] *((const byte*) main::$2) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero SCREEN in [12] *((const byte*) SCREEN + (byte) 0) ← *((const byte*) main::$4)
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant (const byte) OFFSET_STRUCT_VECTOR_P
Eliminating unused constant (const byte) OFFSET_STRUCT_POINT_X
Successful SSA optimization PassNEliminateUnusedVars
Constant inlined main::$10 = (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q
Constant inlined main::$11 = (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y
Constant inlined main::$1 = (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y
Constant inlined main::$2 = (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q
Constant inlined main::$0 = (byte*)(struct Point*)&(struct Vector) main::v
@ -178,9 +140,7 @@ Constant inlined main::$5 = (byte*)(struct Point*)&(struct Vector) main::v+(cons
Constant inlined main::$6 = (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q
Constant inlined main::$3 = (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y
Constant inlined main::$4 = (byte*)(struct Point*)&(struct Vector) main::v
Constant inlined main::$9 = (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y
Constant inlined main::$7 = (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y
Constant inlined main::$8 = (byte*)(struct Point*)&(struct Vector) main::v
Successful SSA optimization Pass2ConstantInlining
Consolidated array index constant in *(SCREEN+1)
Consolidated array index constant in *(SCREEN+2)
@ -213,25 +173,20 @@ FINAL CONTROL FLOW GRAPH
(void()) main()
main: scope:[main] from @1
[4] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte) 0
[5] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0
[6] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (byte) 0
[7] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0
[8] *((byte*)&(struct Point) main::p1) ← (byte) 2
[9] *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
[10] *((byte*)&(struct Point) main::p2) ← (byte) 4
[11] *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5
[12] *((byte*)(struct Point*)&(struct Vector) main::v) ← *((byte*)&(struct Point) main::p1)
[13] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y)
[14] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← *((byte*)&(struct Point) main::p2)
[15] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y)
[16] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v)
[17] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y)
[18] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q)
[19] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y)
[4] *(&(struct Vector) main::v) ← memset(struct Vector, (const byte) SIZEOF_STRUCT_VECTOR)
[5] *(&(struct Point) main::p1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
[6] *(&(struct Point) main::p2) ← memcpy(*(&(const struct Point) $1), struct Point, (const byte) SIZEOF_STRUCT_POINT)
[7] *((byte*)(struct Point*)&(struct Vector) main::v) ← *((byte*)&(struct Point) main::p1)
[8] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y)
[9] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← *((byte*)&(struct Point) main::p2)
[10] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y)
[11] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v)
[12] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y)
[13] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q)
[14] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y)
to:main::@return
main::@return: scope:[main] from main
[20] return
[15] return
to:@return
@ -267,6 +222,8 @@ Target platform is c64basic / MOS6502X
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_VECTOR = 4
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_VECTOR_Q = 2
.const OFFSET_STRUCT_POINT_Y = 1
// @begin
@ -288,79 +245,73 @@ main: {
.label v = 2
.label p1 = 6
.label p2 = 8
// [4] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte) 0 -- _deref_pbuc1=vbuc2
// [4] *(&(struct Vector) main::v) ← memset(struct Vector, (const byte) SIZEOF_STRUCT_VECTOR) -- _deref_pssc1=_memset_vbuc2
ldy #SIZEOF_STRUCT_VECTOR
lda #0
sta.z v
// [5] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0 -- _deref_pbuc1=vbuc2
lda #0
sta v+OFFSET_STRUCT_POINT_Y
// [6] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (byte) 0 -- _deref_pbuc1=vbuc2
lda #0
sta v+OFFSET_STRUCT_VECTOR_Q
// [7] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0 -- _deref_pbuc1=vbuc2
lda #0
sta v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
// [8] *((byte*)&(struct Point) main::p1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z p1
// [9] *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta p1+OFFSET_STRUCT_POINT_Y
// [10] *((byte*)&(struct Point) main::p2) ← (byte) 4 -- _deref_pbuc1=vbuc2
lda #4
sta.z p2
// [11] *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5 -- _deref_pbuc1=vbuc2
lda #5
sta p2+OFFSET_STRUCT_POINT_Y
// [12] *((byte*)(struct Point*)&(struct Vector) main::v) ← *((byte*)&(struct Point) main::p1) -- _deref_pbuc1=_deref_pbuc2
!:
dey
sta v,y
bne !-
// [5] *(&(struct Point) main::p1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta p1-1,y
dey
bne !-
// [6] *(&(struct Point) main::p2) ← memcpy(*(&(const struct Point) $1), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __1-1,y
sta p2-1,y
dey
bne !-
// [7] *((byte*)(struct Point*)&(struct Vector) main::v) ← *((byte*)&(struct Point) main::p1) -- _deref_pbuc1=_deref_pbuc2
lda.z p1
sta.z v
// [13] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [8] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda p1+OFFSET_STRUCT_POINT_Y
sta v+OFFSET_STRUCT_POINT_Y
// [14] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← *((byte*)&(struct Point) main::p2) -- _deref_pbuc1=_deref_pbuc2
// [9] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← *((byte*)&(struct Point) main::p2) -- _deref_pbuc1=_deref_pbuc2
lda.z p2
sta v+OFFSET_STRUCT_VECTOR_Q
// [15] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [10] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda p2+OFFSET_STRUCT_POINT_Y
sta v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
// [16] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v) -- _deref_pbuc1=_deref_pbuc2
// [11] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v) -- _deref_pbuc1=_deref_pbuc2
lda.z v
sta SCREEN
// [17] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [12] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_POINT_Y
sta SCREEN+1
// [18] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) -- _deref_pbuc1=_deref_pbuc2
// [13] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_VECTOR_Q
sta SCREEN+2
// [19] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [14] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
sta SCREEN+3
jmp __breturn
// main::@return
__breturn:
// [20] return
// [15] return
rts
}
// File Data
__0: .byte 2, 3
__1: .byte 4, 5
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte) 0 [ main::v main::p1 main::p2 ] ( main:2 [ main::v main::p1 main::p2 ] ) always clobbers reg byte a
Statement [5] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0 [ main::v main::p1 main::p2 ] ( main:2 [ main::v main::p1 main::p2 ] ) always clobbers reg byte a
Statement [6] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (byte) 0 [ main::v main::p1 main::p2 ] ( main:2 [ main::v main::p1 main::p2 ] ) always clobbers reg byte a
Statement [7] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0 [ main::v main::p1 main::p2 ] ( main:2 [ main::v main::p1 main::p2 ] ) always clobbers reg byte a
Statement [8] *((byte*)&(struct Point) main::p1) ← (byte) 2 [ main::v main::p1 main::p2 ] ( main:2 [ main::v main::p1 main::p2 ] ) always clobbers reg byte a
Statement [9] *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 [ main::v main::p1 main::p2 ] ( main:2 [ main::v main::p1 main::p2 ] ) always clobbers reg byte a
Statement [10] *((byte*)&(struct Point) main::p2) ← (byte) 4 [ main::v main::p1 main::p2 ] ( main:2 [ main::v main::p1 main::p2 ] ) always clobbers reg byte a
Statement [11] *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5 [ main::v main::p1 main::p2 ] ( main:2 [ main::v main::p1 main::p2 ] ) always clobbers reg byte a
Statement [12] *((byte*)(struct Point*)&(struct Vector) main::v) ← *((byte*)&(struct Point) main::p1) [ main::v main::p1 main::p2 ] ( main:2 [ main::v main::p1 main::p2 ] ) always clobbers reg byte a
Statement [13] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) [ main::v main::p2 ] ( main:2 [ main::v main::p2 ] ) always clobbers reg byte a
Statement [14] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← *((byte*)&(struct Point) main::p2) [ main::v main::p2 ] ( main:2 [ main::v main::p2 ] ) always clobbers reg byte a
Statement [15] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [16] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v) [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [17] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [18] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [19] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [4] *(&(struct Vector) main::v) ← memset(struct Vector, (const byte) SIZEOF_STRUCT_VECTOR) [ main::v main::p1 main::p2 ] ( main:2 [ main::v main::p1 main::p2 ] ) always clobbers reg byte a reg byte y
Statement [5] *(&(struct Point) main::p1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) [ main::v main::p1 main::p2 ] ( main:2 [ main::v main::p1 main::p2 ] ) always clobbers reg byte a reg byte y
Statement [6] *(&(struct Point) main::p2) ← memcpy(*(&(const struct Point) $1), struct Point, (const byte) SIZEOF_STRUCT_POINT) [ main::v main::p1 main::p2 ] ( main:2 [ main::v main::p1 main::p2 ] ) always clobbers reg byte a reg byte y
Statement [7] *((byte*)(struct Point*)&(struct Vector) main::v) ← *((byte*)&(struct Point) main::p1) [ main::v main::p1 main::p2 ] ( main:2 [ main::v main::p1 main::p2 ] ) always clobbers reg byte a
Statement [8] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) [ main::v main::p2 ] ( main:2 [ main::v main::p2 ] ) always clobbers reg byte a
Statement [9] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← *((byte*)&(struct Point) main::p2) [ main::v main::p2 ] ( main:2 [ main::v main::p2 ] ) always clobbers reg byte a
Statement [10] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [11] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v) [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [12] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [13] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [14] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) [ ] ( main:2 [ ] ) always clobbers reg byte a
Potential registers zp[4]:2 [ main::v ] : zp[4]:2 ,
Potential registers zp[2]:6 [ main::p1 ] : zp[2]:6 ,
Potential registers zp[2]:8 [ main::p2 ] : zp[2]:8 ,
@ -385,6 +336,8 @@ ASSEMBLER BEFORE OPTIMIZATION
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_VECTOR = 4
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_VECTOR_Q = 2
.const OFFSET_STRUCT_POINT_Y = 1
// @begin
@ -406,71 +359,66 @@ main: {
.label v = 2
.label p1 = 6
.label p2 = 8
// [4] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte) 0 -- _deref_pbuc1=vbuc2
// [4] *(&(struct Vector) main::v) ← memset(struct Vector, (const byte) SIZEOF_STRUCT_VECTOR) -- _deref_pssc1=_memset_vbuc2
ldy #SIZEOF_STRUCT_VECTOR
lda #0
sta.z v
// [5] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0 -- _deref_pbuc1=vbuc2
lda #0
sta v+OFFSET_STRUCT_POINT_Y
// [6] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (byte) 0 -- _deref_pbuc1=vbuc2
lda #0
sta v+OFFSET_STRUCT_VECTOR_Q
// [7] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0 -- _deref_pbuc1=vbuc2
lda #0
sta v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
// [8] *((byte*)&(struct Point) main::p1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z p1
// [9] *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta p1+OFFSET_STRUCT_POINT_Y
// [10] *((byte*)&(struct Point) main::p2) ← (byte) 4 -- _deref_pbuc1=vbuc2
lda #4
sta.z p2
// [11] *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5 -- _deref_pbuc1=vbuc2
lda #5
sta p2+OFFSET_STRUCT_POINT_Y
// [12] *((byte*)(struct Point*)&(struct Vector) main::v) ← *((byte*)&(struct Point) main::p1) -- _deref_pbuc1=_deref_pbuc2
!:
dey
sta v,y
bne !-
// [5] *(&(struct Point) main::p1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta p1-1,y
dey
bne !-
// [6] *(&(struct Point) main::p2) ← memcpy(*(&(const struct Point) $1), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __1-1,y
sta p2-1,y
dey
bne !-
// [7] *((byte*)(struct Point*)&(struct Vector) main::v) ← *((byte*)&(struct Point) main::p1) -- _deref_pbuc1=_deref_pbuc2
lda.z p1
sta.z v
// [13] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [8] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda p1+OFFSET_STRUCT_POINT_Y
sta v+OFFSET_STRUCT_POINT_Y
// [14] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← *((byte*)&(struct Point) main::p2) -- _deref_pbuc1=_deref_pbuc2
// [9] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← *((byte*)&(struct Point) main::p2) -- _deref_pbuc1=_deref_pbuc2
lda.z p2
sta v+OFFSET_STRUCT_VECTOR_Q
// [15] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [10] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda p2+OFFSET_STRUCT_POINT_Y
sta v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
// [16] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v) -- _deref_pbuc1=_deref_pbuc2
// [11] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v) -- _deref_pbuc1=_deref_pbuc2
lda.z v
sta SCREEN
// [17] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [12] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_POINT_Y
sta SCREEN+1
// [18] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) -- _deref_pbuc1=_deref_pbuc2
// [13] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_VECTOR_Q
sta SCREEN+2
// [19] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [14] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
sta SCREEN+3
jmp __breturn
// main::@return
__breturn:
// [20] return
// [15] return
rts
}
// File Data
__0: .byte 2, 3
__1: .byte 4, 5
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __bend
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction lda #0
Removing instruction lda #0
Removing instruction lda #0
Succesful ASM optimization Pass5UnnecesaryLoadElimination
Replacing label __bbegin with __b1
Removing instruction __bbegin:
Removing instruction __b1_from___bbegin:
@ -486,6 +434,8 @@ Removing instruction __b1:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
(const struct Point) $0 = { x: (byte) 2, y: (byte) 3 }
(const struct Point) $1 = { x: (byte) 4, y: (byte) 5 }
(label) @1
(label) @begin
(label) @end
@ -494,6 +444,8 @@ FINAL SYMBOL TABLE
(byte) Point::x
(byte) Point::y
(const byte*) SCREEN = (byte*) 1024
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(const byte) SIZEOF_STRUCT_VECTOR = (byte) 4
(struct Point) Vector::p
(struct Point) Vector::q
(void()) main()
@ -508,7 +460,7 @@ zp[2]:8 [ main::p2 ]
FINAL ASSEMBLER
Score: 105
Score: 111
// File Comments
// Minimal struct with C-Standard behavior - struct containing struct with assignment of sub-struct
@ -518,6 +470,8 @@ Score: 105
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_VECTOR = 4
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_VECTOR_Q = 2
.const OFFSET_STRUCT_POINT_Y = 1
// @begin
@ -532,63 +486,65 @@ main: {
.label p1 = 6
.label p2 = 8
// v
// [4] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte) 0 -- _deref_pbuc1=vbuc2
// [4] *(&(struct Vector) main::v) ← memset(struct Vector, (const byte) SIZEOF_STRUCT_VECTOR) -- _deref_pssc1=_memset_vbuc2
ldy #SIZEOF_STRUCT_VECTOR
lda #0
sta.z v
// [5] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0 -- _deref_pbuc1=vbuc2
sta v+OFFSET_STRUCT_POINT_Y
// [6] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (byte) 0 -- _deref_pbuc1=vbuc2
sta v+OFFSET_STRUCT_VECTOR_Q
// [7] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 0 -- _deref_pbuc1=vbuc2
sta v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
!:
dey
sta v,y
bne !-
// p1 = { 2, 3 }
// [8] *((byte*)&(struct Point) main::p1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z p1
// [9] *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta p1+OFFSET_STRUCT_POINT_Y
// [5] *(&(struct Point) main::p1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta p1-1,y
dey
bne !-
// p2 = { 4, 5 }
// [10] *((byte*)&(struct Point) main::p2) ← (byte) 4 -- _deref_pbuc1=vbuc2
lda #4
sta.z p2
// [11] *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5 -- _deref_pbuc1=vbuc2
lda #5
sta p2+OFFSET_STRUCT_POINT_Y
// [6] *(&(struct Point) main::p2) ← memcpy(*(&(const struct Point) $1), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __1-1,y
sta p2-1,y
dey
bne !-
// v.p = p1
// [12] *((byte*)(struct Point*)&(struct Vector) main::v) ← *((byte*)&(struct Point) main::p1) -- _deref_pbuc1=_deref_pbuc2
// [7] *((byte*)(struct Point*)&(struct Vector) main::v) ← *((byte*)&(struct Point) main::p1) -- _deref_pbuc1=_deref_pbuc2
lda.z p1
sta.z v
// [13] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [8] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda p1+OFFSET_STRUCT_POINT_Y
sta v+OFFSET_STRUCT_POINT_Y
// v.q = p2
// [14] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← *((byte*)&(struct Point) main::p2) -- _deref_pbuc1=_deref_pbuc2
// [9] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← *((byte*)&(struct Point) main::p2) -- _deref_pbuc1=_deref_pbuc2
lda.z p2
sta v+OFFSET_STRUCT_VECTOR_Q
// [15] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [10] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda p2+OFFSET_STRUCT_POINT_Y
sta v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
// SCREEN[0] = v.p.x
// [16] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v) -- _deref_pbuc1=_deref_pbuc2
// [11] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v) -- _deref_pbuc1=_deref_pbuc2
lda.z v
sta SCREEN
// SCREEN[1] = v.p.y
// [17] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [12] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_POINT_Y
sta SCREEN+1
// SCREEN[2] = v.q.x
// [18] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) -- _deref_pbuc1=_deref_pbuc2
// [13] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_VECTOR_Q
sta SCREEN+2
// SCREEN[3] = v.q.y
// [19] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [14] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
sta SCREEN+3
// main::@return
// }
// [20] return
// [15] return
rts
}
// File Data
__0: .byte 2, 3
__1: .byte 4, 5

View File

@ -1,3 +1,5 @@
(const struct Point) $0 = { x: (byte) 2, y: (byte) 3 }
(const struct Point) $1 = { x: (byte) 4, y: (byte) 5 }
(label) @1
(label) @begin
(label) @end
@ -6,6 +8,8 @@
(byte) Point::x
(byte) Point::y
(const byte*) SCREEN = (byte*) 1024
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(const byte) SIZEOF_STRUCT_VECTOR = (byte) 4
(struct Point) Vector::p
(struct Point) Vector::q
(void()) main()

View File

@ -3,20 +3,25 @@
:BasicUpstart(main)
.pc = $80d "Program"
.label SCREEN = $400
.const OFFSET_STRUCT_POINT_Y = 1
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_VECTOR_Q = 2
.const OFFSET_STRUCT_POINT_Y = 1
main: {
.label p1 = 2
.label p2 = 4
.label v = 6
lda #2
sta.z p1
lda #3
sta p1+OFFSET_STRUCT_POINT_Y
lda #4
sta.z p2
lda #5
sta p2+OFFSET_STRUCT_POINT_Y
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta p1-1,y
dey
bne !-
ldy #SIZEOF_STRUCT_POINT
!:
lda __1-1,y
sta p2-1,y
dey
bne !-
lda.z p1
sta.z v
lda p1+OFFSET_STRUCT_POINT_Y
@ -35,3 +40,5 @@ main: {
sta SCREEN+3
rts
}
__0: .byte 2, 3
__1: .byte 4, 5

View File

@ -10,19 +10,17 @@
(void()) main()
main: scope:[main] from @1
[4] *((byte*)&(struct Point) main::p1) ← (byte) 2
[5] *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
[6] *((byte*)&(struct Point) main::p2) ← (byte) 4
[7] *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5
[8] *((byte*)(struct Point*)&(struct Vector) main::v) ← *((byte*)&(struct Point) main::p1)
[9] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y)
[10] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← *((byte*)&(struct Point) main::p2)
[11] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y)
[12] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v)
[13] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y)
[14] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q)
[15] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y)
[4] *(&(struct Point) main::p1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
[5] *(&(struct Point) main::p2) ← memcpy(*(&(const struct Point) $1), struct Point, (const byte) SIZEOF_STRUCT_POINT)
[6] *((byte*)(struct Point*)&(struct Vector) main::v) ← *((byte*)&(struct Point) main::p1)
[7] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y)
[8] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← *((byte*)&(struct Point) main::p2)
[9] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y)
[10] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v)
[11] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y)
[12] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q)
[13] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y)
to:main::@return
main::@return: scope:[main] from main
[16] return
[14] return
to:@return

View File

@ -1,7 +1,5 @@
Adding struct value member variable copy *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
Adding struct value member variable copy *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
Adding struct value member variable copy *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 4
Adding struct value member variable copy *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5
Adding struct value member variable copy *(&(struct Point) main::p1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
Adding struct value member variable copy *(&(struct Point) main::p2) ← memcpy(*(&(const struct Point) $1), struct Point, (const byte) SIZEOF_STRUCT_POINT)
Adding struct value member variable copy *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P) ← (struct Point) main::p1
Adding struct value member variable copy *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← (struct Point) main::p2
Replacing struct member reference (struct Vector) main::v.p with member unwinding reference *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P)
@ -23,12 +21,8 @@ CONTROL FLOW GRAPH SSA
(void()) main()
main: scope:[main] from @1
*((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
*((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
(struct Point) main::p1 ← struct-unwound {*((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y)}
*((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 4
*((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5
(struct Point) main::p2 ← struct-unwound {*((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y)}
*(&(struct Point) main::p1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
*(&(struct Point) main::p2) ← memcpy(*(&(const struct Point) $1), struct Point, (const byte) SIZEOF_STRUCT_POINT)
(byte*~) main::$0 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_X
*((byte*~) main::$0) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_X)
(byte*~) main::$1 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_Y
@ -58,6 +52,8 @@ main::@return: scope:[main] from main
@end: scope:[] from @2
SYMBOL TABLE SSA
(const struct Point) $0 = { x: (byte) 2, y: (byte) 3 }
(const struct Point) $1 = { x: (byte) 4, y: (byte) 5 }
(label) @1
(label) @2
(label) @begin
@ -69,6 +65,7 @@ SYMBOL TABLE SSA
(byte) Point::x
(byte) Point::y
(const byte*) SCREEN = (byte*)(number) $400
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(struct Point) Vector::p
(struct Point) Vector::q
(void()) main()
@ -101,17 +98,15 @@ Finalized unsigned number type (byte) 1
Finalized unsigned number type (byte) 2
Finalized unsigned number type (byte) 3
Successful SSA optimization PassNFinalizeNumberTypeConversions
Removing C-classic struct-unwound assignment [2] (struct Point) main::p1 ← struct-unwound {*((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y)}
Removing C-classic struct-unwound assignment [5] (struct Point) main::p2 ← struct-unwound {*((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y)}
Removing C-classic struct-unwound assignment [14] (struct Vector) main::v ← struct-unwound {*((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P), *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q)}
Constant right-side identified [6] (byte*~) main::$0 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [8] (byte*~) main::$1 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_Y
Constant right-side identified [10] (byte*~) main::$2 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [12] (byte*~) main::$3 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_Y
Constant right-side identified [15] (byte*~) main::$4 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [17] (byte*~) main::$5 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_Y
Constant right-side identified [19] (byte*~) main::$6 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [21] (byte*~) main::$7 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_Y
Removing C-classic struct-unwound assignment [10] (struct Vector) main::v ← struct-unwound {*((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P), *((struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q)}
Constant right-side identified [2] (byte*~) main::$0 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [4] (byte*~) main::$1 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_Y
Constant right-side identified [6] (byte*~) main::$2 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [8] (byte*~) main::$3 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_Y
Constant right-side identified [11] (byte*~) main::$4 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [13] (byte*~) main::$5 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P + (const byte) OFFSET_STRUCT_POINT_Y
Constant right-side identified [15] (byte*~) main::$6 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [17] (byte*~) main::$7 ← (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q + (const byte) OFFSET_STRUCT_POINT_Y
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant (const byte*) main::$0 = (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_P+OFFSET_STRUCT_POINT_X
Constant (const byte*) main::$1 = (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_P+OFFSET_STRUCT_POINT_Y
@ -130,14 +125,12 @@ Simplifying expression containing zero (byte*)(struct Point*)&main::v+OFFSET_STR
Simplifying expression containing zero (struct Point*)&main::v in
Simplifying expression containing zero (struct Point*)&main::v in
Simplifying expression containing zero (byte*)(struct Point*)&main::v+OFFSET_STRUCT_VECTOR_Q in
Simplifying expression containing zero (byte*)&main::p1 in [0] *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
Simplifying expression containing zero (byte*)&main::p2 in [3] *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 4
Simplifying expression containing zero (byte*)&main::p1 in [7] *((const byte*) main::$0) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero (byte*)&main::p2 in [11] *((const byte*) main::$2) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero SCREEN in [16] *((const byte*) SCREEN + (byte) 0) ← *((const byte*) main::$4)
Simplifying expression containing zero (byte*)&main::p1 in [3] *((const byte*) main::$0) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero (byte*)&main::p2 in [7] *((const byte*) main::$2) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero SCREEN in [12] *((const byte*) SCREEN + (byte) 0) ← *((const byte*) main::$4)
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant (const byte) OFFSET_STRUCT_POINT_X
Eliminating unused constant (const byte) OFFSET_STRUCT_VECTOR_P
Eliminating unused constant (const byte) OFFSET_STRUCT_POINT_X
Successful SSA optimization PassNEliminateUnusedVars
Constant inlined main::$1 = (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y
Constant inlined main::$2 = (byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q
@ -179,21 +172,19 @@ FINAL CONTROL FLOW GRAPH
(void()) main()
main: scope:[main] from @1
[4] *((byte*)&(struct Point) main::p1) ← (byte) 2
[5] *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
[6] *((byte*)&(struct Point) main::p2) ← (byte) 4
[7] *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5
[8] *((byte*)(struct Point*)&(struct Vector) main::v) ← *((byte*)&(struct Point) main::p1)
[9] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y)
[10] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← *((byte*)&(struct Point) main::p2)
[11] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y)
[12] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v)
[13] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y)
[14] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q)
[15] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y)
[4] *(&(struct Point) main::p1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
[5] *(&(struct Point) main::p2) ← memcpy(*(&(const struct Point) $1), struct Point, (const byte) SIZEOF_STRUCT_POINT)
[6] *((byte*)(struct Point*)&(struct Vector) main::v) ← *((byte*)&(struct Point) main::p1)
[7] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y)
[8] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← *((byte*)&(struct Point) main::p2)
[9] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y)
[10] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v)
[11] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y)
[12] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q)
[13] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y)
to:main::@return
main::@return: scope:[main] from main
[16] return
[14] return
to:@return
@ -229,8 +220,9 @@ Target platform is c64basic / MOS6502X
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const OFFSET_STRUCT_POINT_Y = 1
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_VECTOR_Q = 2
.const OFFSET_STRUCT_POINT_Y = 1
// @begin
__bbegin:
// [1] phi from @begin to @1 [phi:@begin->@1]
@ -250,63 +242,65 @@ main: {
.label p1 = 2
.label p2 = 4
.label v = 6
// [4] *((byte*)&(struct Point) main::p1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z p1
// [5] *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta p1+OFFSET_STRUCT_POINT_Y
// [6] *((byte*)&(struct Point) main::p2) ← (byte) 4 -- _deref_pbuc1=vbuc2
lda #4
sta.z p2
// [7] *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5 -- _deref_pbuc1=vbuc2
lda #5
sta p2+OFFSET_STRUCT_POINT_Y
// [8] *((byte*)(struct Point*)&(struct Vector) main::v) ← *((byte*)&(struct Point) main::p1) -- _deref_pbuc1=_deref_pbuc2
// [4] *(&(struct Point) main::p1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta p1-1,y
dey
bne !-
// [5] *(&(struct Point) main::p2) ← memcpy(*(&(const struct Point) $1), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __1-1,y
sta p2-1,y
dey
bne !-
// [6] *((byte*)(struct Point*)&(struct Vector) main::v) ← *((byte*)&(struct Point) main::p1) -- _deref_pbuc1=_deref_pbuc2
lda.z p1
sta.z v
// [9] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [7] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda p1+OFFSET_STRUCT_POINT_Y
sta v+OFFSET_STRUCT_POINT_Y
// [10] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← *((byte*)&(struct Point) main::p2) -- _deref_pbuc1=_deref_pbuc2
// [8] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← *((byte*)&(struct Point) main::p2) -- _deref_pbuc1=_deref_pbuc2
lda.z p2
sta v+OFFSET_STRUCT_VECTOR_Q
// [11] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [9] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda p2+OFFSET_STRUCT_POINT_Y
sta v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
// [12] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v) -- _deref_pbuc1=_deref_pbuc2
// [10] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v) -- _deref_pbuc1=_deref_pbuc2
lda.z v
sta SCREEN
// [13] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [11] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_POINT_Y
sta SCREEN+1
// [14] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) -- _deref_pbuc1=_deref_pbuc2
// [12] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_VECTOR_Q
sta SCREEN+2
// [15] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [13] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
sta SCREEN+3
jmp __breturn
// main::@return
__breturn:
// [16] return
// [14] return
rts
}
// File Data
__0: .byte 2, 3
__1: .byte 4, 5
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] *((byte*)&(struct Point) main::p1) ← (byte) 2 [ main::p1 main::p2 main::v ] ( main:2 [ main::p1 main::p2 main::v ] ) always clobbers reg byte a
Statement [5] *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 [ main::p1 main::p2 main::v ] ( main:2 [ main::p1 main::p2 main::v ] ) always clobbers reg byte a
Statement [6] *((byte*)&(struct Point) main::p2) ← (byte) 4 [ main::p1 main::p2 main::v ] ( main:2 [ main::p1 main::p2 main::v ] ) always clobbers reg byte a
Statement [7] *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5 [ main::p1 main::p2 main::v ] ( main:2 [ main::p1 main::p2 main::v ] ) always clobbers reg byte a
Statement [8] *((byte*)(struct Point*)&(struct Vector) main::v) ← *((byte*)&(struct Point) main::p1) [ main::p1 main::p2 main::v ] ( main:2 [ main::p1 main::p2 main::v ] ) always clobbers reg byte a
Statement [9] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) [ main::p2 main::v ] ( main:2 [ main::p2 main::v ] ) always clobbers reg byte a
Statement [10] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← *((byte*)&(struct Point) main::p2) [ main::p2 main::v ] ( main:2 [ main::p2 main::v ] ) always clobbers reg byte a
Statement [11] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [12] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v) [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [13] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [14] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [15] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [4] *(&(struct Point) main::p1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) [ main::p1 main::p2 main::v ] ( main:2 [ main::p1 main::p2 main::v ] ) always clobbers reg byte a reg byte y
Statement [5] *(&(struct Point) main::p2) ← memcpy(*(&(const struct Point) $1), struct Point, (const byte) SIZEOF_STRUCT_POINT) [ main::p1 main::p2 main::v ] ( main:2 [ main::p1 main::p2 main::v ] ) always clobbers reg byte a reg byte y
Statement [6] *((byte*)(struct Point*)&(struct Vector) main::v) ← *((byte*)&(struct Point) main::p1) [ main::p1 main::p2 main::v ] ( main:2 [ main::p1 main::p2 main::v ] ) always clobbers reg byte a
Statement [7] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) [ main::p2 main::v ] ( main:2 [ main::p2 main::v ] ) always clobbers reg byte a
Statement [8] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← *((byte*)&(struct Point) main::p2) [ main::p2 main::v ] ( main:2 [ main::p2 main::v ] ) always clobbers reg byte a
Statement [9] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [10] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v) [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [11] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [12] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) [ main::v ] ( main:2 [ main::v ] ) always clobbers reg byte a
Statement [13] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) [ ] ( main:2 [ ] ) always clobbers reg byte a
Potential registers zp[2]:2 [ main::p1 ] : zp[2]:2 ,
Potential registers zp[2]:4 [ main::p2 ] : zp[2]:4 ,
Potential registers zp[4]:6 [ main::v ] : zp[4]:6 ,
@ -317,10 +311,10 @@ Uplift Scope [Vector]
Uplift Scope [main] 0: zp[2]:2 [ main::p1 ] 0: zp[2]:4 [ main::p2 ] 0: zp[4]:6 [ main::v ]
Uplift Scope []
Uplifting [Point] best 103 combination
Uplifting [Vector] best 103 combination
Uplifting [main] best 103 combination zp[2]:2 [ main::p1 ] zp[2]:4 [ main::p2 ] zp[4]:6 [ main::v ]
Uplifting [] best 103 combination
Uplifting [Point] best 113 combination
Uplifting [Vector] best 113 combination
Uplifting [main] best 113 combination zp[2]:2 [ main::p1 ] zp[2]:4 [ main::p2 ] zp[4]:6 [ main::v ]
Uplifting [] best 113 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
@ -331,8 +325,9 @@ ASSEMBLER BEFORE OPTIMIZATION
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const OFFSET_STRUCT_POINT_Y = 1
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_VECTOR_Q = 2
.const OFFSET_STRUCT_POINT_Y = 1
// @begin
__bbegin:
// [1] phi from @begin to @1 [phi:@begin->@1]
@ -352,49 +347,53 @@ main: {
.label p1 = 2
.label p2 = 4
.label v = 6
// [4] *((byte*)&(struct Point) main::p1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z p1
// [5] *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta p1+OFFSET_STRUCT_POINT_Y
// [6] *((byte*)&(struct Point) main::p2) ← (byte) 4 -- _deref_pbuc1=vbuc2
lda #4
sta.z p2
// [7] *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5 -- _deref_pbuc1=vbuc2
lda #5
sta p2+OFFSET_STRUCT_POINT_Y
// [8] *((byte*)(struct Point*)&(struct Vector) main::v) ← *((byte*)&(struct Point) main::p1) -- _deref_pbuc1=_deref_pbuc2
// [4] *(&(struct Point) main::p1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta p1-1,y
dey
bne !-
// [5] *(&(struct Point) main::p2) ← memcpy(*(&(const struct Point) $1), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __1-1,y
sta p2-1,y
dey
bne !-
// [6] *((byte*)(struct Point*)&(struct Vector) main::v) ← *((byte*)&(struct Point) main::p1) -- _deref_pbuc1=_deref_pbuc2
lda.z p1
sta.z v
// [9] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [7] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda p1+OFFSET_STRUCT_POINT_Y
sta v+OFFSET_STRUCT_POINT_Y
// [10] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← *((byte*)&(struct Point) main::p2) -- _deref_pbuc1=_deref_pbuc2
// [8] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← *((byte*)&(struct Point) main::p2) -- _deref_pbuc1=_deref_pbuc2
lda.z p2
sta v+OFFSET_STRUCT_VECTOR_Q
// [11] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [9] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda p2+OFFSET_STRUCT_POINT_Y
sta v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
// [12] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v) -- _deref_pbuc1=_deref_pbuc2
// [10] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v) -- _deref_pbuc1=_deref_pbuc2
lda.z v
sta SCREEN
// [13] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [11] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_POINT_Y
sta SCREEN+1
// [14] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) -- _deref_pbuc1=_deref_pbuc2
// [12] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_VECTOR_Q
sta SCREEN+2
// [15] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [13] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
sta SCREEN+3
jmp __breturn
// main::@return
__breturn:
// [16] return
// [14] return
rts
}
// File Data
__0: .byte 2, 3
__1: .byte 4, 5
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
@ -416,6 +415,8 @@ Removing instruction __b1:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
(const struct Point) $0 = { x: (byte) 2, y: (byte) 3 }
(const struct Point) $1 = { x: (byte) 4, y: (byte) 5 }
(label) @1
(label) @begin
(label) @end
@ -424,6 +425,7 @@ FINAL SYMBOL TABLE
(byte) Point::x
(byte) Point::y
(const byte*) SCREEN = (byte*) 1024
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(struct Point) Vector::p
(struct Point) Vector::q
(void()) main()
@ -438,7 +440,7 @@ zp[4]:6 [ main::v ]
FINAL ASSEMBLER
Score: 88
Score: 98
// File Comments
// Minimal struct with C-Standard behavior - struct containing struct with initializer using sub-struct value
@ -448,8 +450,9 @@ Score: 88
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const OFFSET_STRUCT_POINT_Y = 1
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_VECTOR_Q = 2
.const OFFSET_STRUCT_POINT_Y = 1
// @begin
// [1] phi from @begin to @1 [phi:@begin->@1]
// @1
@ -462,52 +465,56 @@ main: {
.label p2 = 4
.label v = 6
// p1 = { 2, 3 }
// [4] *((byte*)&(struct Point) main::p1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z p1
// [5] *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta p1+OFFSET_STRUCT_POINT_Y
// [4] *(&(struct Point) main::p1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta p1-1,y
dey
bne !-
// p2 = { 4, 5 }
// [6] *((byte*)&(struct Point) main::p2) ← (byte) 4 -- _deref_pbuc1=vbuc2
lda #4
sta.z p2
// [7] *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5 -- _deref_pbuc1=vbuc2
lda #5
sta p2+OFFSET_STRUCT_POINT_Y
// [5] *(&(struct Point) main::p2) ← memcpy(*(&(const struct Point) $1), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __1-1,y
sta p2-1,y
dey
bne !-
// v = { p1, p2 }
// [8] *((byte*)(struct Point*)&(struct Vector) main::v) ← *((byte*)&(struct Point) main::p1) -- _deref_pbuc1=_deref_pbuc2
// [6] *((byte*)(struct Point*)&(struct Vector) main::v) ← *((byte*)&(struct Point) main::p1) -- _deref_pbuc1=_deref_pbuc2
lda.z p1
sta.z v
// [9] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [7] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p1+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda p1+OFFSET_STRUCT_POINT_Y
sta v+OFFSET_STRUCT_POINT_Y
// [10] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← *((byte*)&(struct Point) main::p2) -- _deref_pbuc1=_deref_pbuc2
// [8] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) ← *((byte*)&(struct Point) main::p2) -- _deref_pbuc1=_deref_pbuc2
lda.z p2
sta v+OFFSET_STRUCT_VECTOR_Q
// [11] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [9] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) main::p2+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda p2+OFFSET_STRUCT_POINT_Y
sta v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
// SCREEN[0] = v.p.x
// [12] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v) -- _deref_pbuc1=_deref_pbuc2
// [10] *((const byte*) SCREEN) ← *((byte*)(struct Point*)&(struct Vector) main::v) -- _deref_pbuc1=_deref_pbuc2
lda.z v
sta SCREEN
// SCREEN[1] = v.p.y
// [13] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [11] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_POINT_Y
sta SCREEN+1
// SCREEN[2] = v.q.x
// [14] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) -- _deref_pbuc1=_deref_pbuc2
// [12] *((const byte*) SCREEN+(byte) 2) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_VECTOR_Q
sta SCREEN+2
// SCREEN[3] = v.q.y
// [15] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [13] *((const byte*) SCREEN+(byte) 3) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_Q+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda v+OFFSET_STRUCT_VECTOR_Q+OFFSET_STRUCT_POINT_Y
sta SCREEN+3
// main::@return
// }
// [16] return
// [14] return
rts
}
// File Data
__0: .byte 2, 3
__1: .byte 4, 5

View File

@ -1,3 +1,5 @@
(const struct Point) $0 = { x: (byte) 2, y: (byte) 3 }
(const struct Point) $1 = { x: (byte) 4, y: (byte) 5 }
(label) @1
(label) @begin
(label) @end
@ -6,6 +8,7 @@
(byte) Point::x
(byte) Point::y
(const byte*) SCREEN = (byte*) 1024
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(struct Point) Vector::p
(struct Point) Vector::q
(void()) main()

View File

@ -3,17 +3,21 @@
:BasicUpstart(main)
.pc = $80d "Program"
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1
main: {
.label ptr = point1
.label point1 = 2
lda #2
sta.z point1
lda #3
sta point1+OFFSET_STRUCT_POINT_Y
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta point1-1,y
dey
bne !-
lda.z ptr
sta SCREEN
lda ptr+OFFSET_STRUCT_POINT_Y
sta SCREEN+1
rts
}
__0: .byte 2, 3

View File

@ -10,11 +10,10 @@
(void()) main()
main: scope:[main] from @1
[4] *((byte*)&(struct Point) main::point1) ← (byte) 2
[5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
[6] *((const byte*) SCREEN) ← *((byte*)(const struct Point*) main::ptr)
[7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(const struct Point*) main::ptr+(const byte) OFFSET_STRUCT_POINT_Y)
[4] *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
[5] *((const byte*) SCREEN) ← *((byte*)(const struct Point*) main::ptr)
[6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(const struct Point*) main::ptr+(const byte) OFFSET_STRUCT_POINT_Y)
to:main::@return
main::@return: scope:[main] from main
[8] return
[7] return
to:@return

View File

@ -1,6 +1,5 @@
Setting inferred volatile on symbol affected by address-of (struct Point*) main::ptr ← &(struct Point) main::point1
Adding struct value member variable copy *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
Adding struct value member variable copy *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
Adding struct value member variable copy *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
Rewriting struct pointer member access *((struct Point*) main::ptr).x
Rewriting struct pointer member access *((struct Point*) main::ptr).y
Identified constant variable (struct Point*) main::ptr
@ -11,9 +10,7 @@ CONTROL FLOW GRAPH SSA
(void()) main()
main: scope:[main] from @1
*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
(struct Point) main::point1 ← struct-unwound {*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y)}
*(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
(byte*~) main::$0 ← (byte*)(const struct Point*) main::ptr + (const byte) OFFSET_STRUCT_POINT_X
*((const byte*) SCREEN + (number) 0) ← *((byte*~) main::$0)
(byte*~) main::$1 ← (byte*)(const struct Point*) main::ptr + (const byte) OFFSET_STRUCT_POINT_Y
@ -30,6 +27,7 @@ main::@return: scope:[main] from main
@end: scope:[] from @2
SYMBOL TABLE SSA
(const struct Point) $0 = { x: (byte) 2, y: (byte) 3 }
(label) @1
(label) @2
(label) @begin
@ -39,6 +37,7 @@ SYMBOL TABLE SSA
(byte) Point::x
(byte) Point::y
(const byte*) SCREEN = (byte*)(number) $400
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(void()) main()
(byte*~) main::$0
(byte*~) main::$1
@ -56,16 +55,14 @@ Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) 0
Finalized unsigned number type (byte) 1
Successful SSA optimization PassNFinalizeNumberTypeConversions
Removing C-classic struct-unwound assignment [2] (struct Point) main::point1 ← struct-unwound {*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y)}
Constant right-side identified [3] (byte*~) main::$0 ← (byte*)(const struct Point*) main::ptr + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [5] (byte*~) main::$1 ← (byte*)(const struct Point*) main::ptr + (const byte) OFFSET_STRUCT_POINT_Y
Constant right-side identified [1] (byte*~) main::$0 ← (byte*)(const struct Point*) main::ptr + (const byte) OFFSET_STRUCT_POINT_X
Constant right-side identified [3] (byte*~) main::$1 ← (byte*)(const struct Point*) main::ptr + (const byte) OFFSET_STRUCT_POINT_Y
Successful SSA optimization Pass2ConstantRValueConsolidation
Constant (const byte*) main::$0 = (byte*)main::ptr+OFFSET_STRUCT_POINT_X
Constant (const byte*) main::$1 = (byte*)main::ptr+OFFSET_STRUCT_POINT_Y
Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero (byte*)main::ptr in
Simplifying expression containing zero (byte*)&main::point1 in [0] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
Simplifying expression containing zero SCREEN in [4] *((const byte*) SCREEN + (byte) 0) ← *((const byte*) main::$0)
Simplifying expression containing zero SCREEN in [2] *((const byte*) SCREEN + (byte) 0) ← *((const byte*) main::$0)
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant (const byte) OFFSET_STRUCT_POINT_X
Successful SSA optimization PassNEliminateUnusedVars
@ -101,13 +98,12 @@ FINAL CONTROL FLOW GRAPH
(void()) main()
main: scope:[main] from @1
[4] *((byte*)&(struct Point) main::point1) ← (byte) 2
[5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
[6] *((const byte*) SCREEN) ← *((byte*)(const struct Point*) main::ptr)
[7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(const struct Point*) main::ptr+(const byte) OFFSET_STRUCT_POINT_Y)
[4] *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
[5] *((const byte*) SCREEN) ← *((byte*)(const struct Point*) main::ptr)
[6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(const struct Point*) main::ptr+(const byte) OFFSET_STRUCT_POINT_Y)
to:main::@return
main::@return: scope:[main] from main
[8] return
[7] return
to:@return
@ -133,6 +129,7 @@ Target platform is c64basic / MOS6502X
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1
// @begin
__bbegin:
@ -152,31 +149,32 @@ __bend:
main: {
.label ptr = point1
.label point1 = 2
// [4] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z point1
// [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta point1+OFFSET_STRUCT_POINT_Y
// [6] *((const byte*) SCREEN) ← *((byte*)(const struct Point*) main::ptr) -- _deref_pbuc1=_deref_pbuc2
// [4] *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta point1-1,y
dey
bne !-
// [5] *((const byte*) SCREEN) ← *((byte*)(const struct Point*) main::ptr) -- _deref_pbuc1=_deref_pbuc2
lda.z ptr
sta SCREEN
// [7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(const struct Point*) main::ptr+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(const struct Point*) main::ptr+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda ptr+OFFSET_STRUCT_POINT_Y
sta SCREEN+1
jmp __breturn
// main::@return
__breturn:
// [8] return
// [7] return
rts
}
// File Data
__0: .byte 2, 3
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] *((byte*)&(struct Point) main::point1) ← (byte) 2 [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a
Statement [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [6] *((const byte*) SCREEN) ← *((byte*)(const struct Point*) main::ptr) [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(const struct Point*) main::ptr+(const byte) OFFSET_STRUCT_POINT_Y) [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [4] *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) [ ] ( main:2 [ ] ) always clobbers reg byte a reg byte y
Statement [5] *((const byte*) SCREEN) ← *((byte*)(const struct Point*) main::ptr) [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(const struct Point*) main::ptr+(const byte) OFFSET_STRUCT_POINT_Y) [ ] ( main:2 [ ] ) always clobbers reg byte a
Potential registers zp[2]:2 [ main::point1 ] : zp[2]:2 ,
REGISTER UPLIFT SCOPES
@ -184,9 +182,9 @@ Uplift Scope [Point]
Uplift Scope [main] 0: zp[2]:2 [ main::point1 ]
Uplift Scope []
Uplifting [Point] best 47 combination
Uplifting [main] best 47 combination zp[2]:2 [ main::point1 ]
Uplifting [] best 47 combination
Uplifting [Point] best 52 combination
Uplifting [main] best 52 combination zp[2]:2 [ main::point1 ]
Uplifting [] best 52 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
@ -197,6 +195,7 @@ ASSEMBLER BEFORE OPTIMIZATION
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1
// @begin
__bbegin:
@ -216,25 +215,27 @@ __bend:
main: {
.label ptr = point1
.label point1 = 2
// [4] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z point1
// [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta point1+OFFSET_STRUCT_POINT_Y
// [6] *((const byte*) SCREEN) ← *((byte*)(const struct Point*) main::ptr) -- _deref_pbuc1=_deref_pbuc2
// [4] *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta point1-1,y
dey
bne !-
// [5] *((const byte*) SCREEN) ← *((byte*)(const struct Point*) main::ptr) -- _deref_pbuc1=_deref_pbuc2
lda.z ptr
sta SCREEN
// [7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(const struct Point*) main::ptr+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(const struct Point*) main::ptr+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda ptr+OFFSET_STRUCT_POINT_Y
sta SCREEN+1
jmp __breturn
// main::@return
__breturn:
// [8] return
// [7] return
rts
}
// File Data
__0: .byte 2, 3
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
@ -256,6 +257,7 @@ Removing instruction __b1:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
(const struct Point) $0 = { x: (byte) 2, y: (byte) 3 }
(label) @1
(label) @begin
(label) @end
@ -263,6 +265,7 @@ FINAL SYMBOL TABLE
(byte) Point::x
(byte) Point::y
(const byte*) SCREEN = (byte*) 1024
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(void()) main()
(label) main::@return
(struct Point) main::point1 loadstore zp[2]:2
@ -272,7 +275,7 @@ zp[2]:2 [ main::point1 ]
FINAL ASSEMBLER
Score: 32
Score: 37
// File Comments
// Minimal struct with C-Standard behavior - address-of
@ -282,6 +285,7 @@ Score: 32
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1
// @begin
// [1] phi from @begin to @1 [phi:@begin->@1]
@ -294,24 +298,26 @@ main: {
.label ptr = point1
.label point1 = 2
// point1 = { 2, 3 }
// [4] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z point1
// [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta point1+OFFSET_STRUCT_POINT_Y
// [4] *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta point1-1,y
dey
bne !-
// SCREEN[0] = ptr->x
// [6] *((const byte*) SCREEN) ← *((byte*)(const struct Point*) main::ptr) -- _deref_pbuc1=_deref_pbuc2
// [5] *((const byte*) SCREEN) ← *((byte*)(const struct Point*) main::ptr) -- _deref_pbuc1=_deref_pbuc2
lda.z ptr
sta SCREEN
// SCREEN[1] = ptr->y
// [7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(const struct Point*) main::ptr+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
// [6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(const struct Point*) main::ptr+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda ptr+OFFSET_STRUCT_POINT_Y
sta SCREEN+1
// main::@return
// }
// [8] return
// [7] return
rts
}
// File Data
__0: .byte 2, 3

View File

@ -1,3 +1,4 @@
(const struct Point) $0 = { x: (byte) 2, y: (byte) 3 }
(label) @1
(label) @begin
(label) @end
@ -5,6 +6,7 @@
(byte) Point::x
(byte) Point::y
(const byte*) SCREEN = (byte*) 1024
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(void()) main()
(label) main::@return
(struct Point) main::point1 loadstore zp[2]:2

View File

@ -3,18 +3,23 @@
:BasicUpstart(main)
.pc = $80d "Program"
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1
main: {
.label point1 = 2
.label point2 = 4
lda #2
sta.z point1
lda #3
sta point1+OFFSET_STRUCT_POINT_Y
lda #4
sta.z point2
lda #5
sta point2+OFFSET_STRUCT_POINT_Y
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta point1-1,y
dey
bne !-
ldy #SIZEOF_STRUCT_POINT
!:
lda __1-1,y
sta point2-1,y
dey
bne !-
lda.z point1
ldx point1+OFFSET_STRUCT_POINT_Y
jsr print
@ -29,3 +34,5 @@ print: {
stx SCREEN+1
rts
}
__0: .byte 2, 3
__1: .byte 4, 5

View File

@ -10,30 +10,28 @@
(void()) main()
main: scope:[main] from @1
[4] *((byte*)&(struct Point) main::point1) ← (byte) 2
[5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
[6] *((byte*)&(struct Point) main::point2) ← (byte) 4
[7] *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5
[8] (byte) print::p_x#0 ← *((byte*)&(struct Point) main::point1)
[9] (byte) print::p_y#0 ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y)
[10] call print
[4] *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
[5] *(&(struct Point) main::point2) ← memcpy(*(&(const struct Point) $1), struct Point, (const byte) SIZEOF_STRUCT_POINT)
[6] (byte) print::p_x#0 ← *((byte*)&(struct Point) main::point1)
[7] (byte) print::p_y#0 ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y)
[8] call print
to:main::@1
main::@1: scope:[main] from main
[11] (byte) print::p_x#1 ← *((byte*)&(struct Point) main::point2)
[12] (byte) print::p_y#1 ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y)
[13] call print
[9] (byte) print::p_x#1 ← *((byte*)&(struct Point) main::point2)
[10] (byte) print::p_y#1 ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y)
[11] call print
to:main::@return
main::@return: scope:[main] from main::@1
[14] return
[12] return
to:@return
(void()) print((byte) print::p_x , (byte) print::p_y)
print: scope:[print] from main main::@1
[15] (byte) print::p_y#2 ← phi( main/(byte) print::p_y#0 main::@1/(byte) print::p_y#1 )
[15] (byte) print::p_x#2 ← phi( main/(byte) print::p_x#0 main::@1/(byte) print::p_x#1 )
[16] *((const byte*) SCREEN) ← (byte) print::p_x#2
[17] *((const byte*) SCREEN+(byte) 1) ← (byte) print::p_y#2
[13] (byte) print::p_y#2 ← phi( main/(byte) print::p_y#0 main::@1/(byte) print::p_y#1 )
[13] (byte) print::p_x#2 ← phi( main/(byte) print::p_x#0 main::@1/(byte) print::p_x#1 )
[14] *((const byte*) SCREEN) ← (byte) print::p_x#2
[15] *((const byte*) SCREEN+(byte) 1) ← (byte) print::p_y#2
to:print::@return
print::@return: scope:[print] from print
[18] return
[16] return
to:@return

View File

@ -2,10 +2,8 @@ Created struct value member variable (byte) print::p_x
Created struct value member variable (byte) print::p_y
Converted struct value to member variables (struct Point) print::p
Converted procedure struct value parameter to member unwinding (void()) print((byte) print::p_x , (byte) print::p_y)
Adding struct value member variable copy *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
Adding struct value member variable copy *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
Adding struct value member variable copy *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 4
Adding struct value member variable copy *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5
Adding struct value member variable copy *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
Adding struct value member variable copy *(&(struct Point) main::point2) ← memcpy(*(&(const struct Point) $1), struct Point, (const byte) SIZEOF_STRUCT_POINT)
Converted procedure struct value parameter to member unwinding in call (void~) main::$0 ← call print *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y)
Converted procedure struct value parameter to member unwinding in call (void~) main::$1 ← call print *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X) *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y)
Replacing struct member reference (struct Point) print::p.x with member unwinding reference (byte) print::p_x
@ -18,12 +16,8 @@ CONTROL FLOW GRAPH SSA
(void()) main()
main: scope:[main] from @2
*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
(struct Point) main::point1 ← struct-unwound {*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y)}
*((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 4
*((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5
(struct Point) main::point2 ← struct-unwound {*((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y)}
*(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
*(&(struct Point) main::point2) ← memcpy(*(&(const struct Point) $1), struct Point, (const byte) SIZEOF_STRUCT_POINT)
(byte) print::p_x#0 ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X)
(byte) print::p_y#0 ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y)
call print
@ -57,6 +51,8 @@ print::@return: scope:[print] from print
@end: scope:[] from @3
SYMBOL TABLE SSA
(const struct Point) $0 = { x: (byte) 2, y: (byte) 3 }
(const struct Point) $1 = { x: (byte) 4, y: (byte) 5 }
(label) @2
(label) @3
(label) @begin
@ -66,6 +62,7 @@ SYMBOL TABLE SSA
(byte) Point::x
(byte) Point::y
(const byte*) SCREEN = (byte*)(number) $400
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(void()) main()
(label) main::@1
(label) main::@2
@ -94,13 +91,9 @@ Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) 0
Finalized unsigned number type (byte) 1
Successful SSA optimization PassNFinalizeNumberTypeConversions
Removing C-classic struct-unwound assignment [2] (struct Point) main::point1 ← struct-unwound {*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y)}
Removing C-classic struct-unwound assignment [5] (struct Point) main::point2 ← struct-unwound {*((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y)}
Simplifying expression containing zero (byte*)&main::point1 in [0] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
Simplifying expression containing zero (byte*)&main::point2 in [3] *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 4
Simplifying expression containing zero (byte*)&main::point1 in [6] (byte) print::p_x#0 ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero (byte*)&main::point2 in [9] (byte) print::p_x#1 ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero SCREEN in [14] *((const byte*) SCREEN + (byte) 0) ← (byte) print::p_x#2
Simplifying expression containing zero (byte*)&main::point1 in [2] (byte) print::p_x#0 ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero (byte*)&main::point2 in [5] (byte) print::p_x#1 ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero SCREEN in [10] *((const byte*) SCREEN + (byte) 0) ← (byte) print::p_x#2
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant (const byte) OFFSET_STRUCT_POINT_X
Successful SSA optimization PassNEliminateUnusedVars
@ -113,13 +106,13 @@ Adding NOP phi() at start of @end
Adding NOP phi() at start of main::@2
CALL GRAPH
Calls in [] to main:2
Calls in [main] to print:13 print:18
Calls in [main] to print:11 print:16
Created 2 initial phi equivalence classes
Coalesced [11] print::p_x#3 ← print::p_x#0
Coalesced [12] print::p_y#3 ← print::p_y#0
Coalesced [16] print::p_x#4 ← print::p_x#1
Coalesced [17] print::p_y#4 ← print::p_y#1
Coalesced [9] print::p_x#3 ← print::p_x#0
Coalesced [10] print::p_y#3 ← print::p_y#0
Coalesced [14] print::p_x#4 ← print::p_x#1
Coalesced [15] print::p_y#4 ← print::p_y#1
Coalesced down to 2 phi equivalence classes
Culled Empty Block (label) @3
Culled Empty Block (label) main::@2
@ -141,32 +134,30 @@ FINAL CONTROL FLOW GRAPH
(void()) main()
main: scope:[main] from @1
[4] *((byte*)&(struct Point) main::point1) ← (byte) 2
[5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
[6] *((byte*)&(struct Point) main::point2) ← (byte) 4
[7] *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5
[8] (byte) print::p_x#0 ← *((byte*)&(struct Point) main::point1)
[9] (byte) print::p_y#0 ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y)
[10] call print
[4] *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
[5] *(&(struct Point) main::point2) ← memcpy(*(&(const struct Point) $1), struct Point, (const byte) SIZEOF_STRUCT_POINT)
[6] (byte) print::p_x#0 ← *((byte*)&(struct Point) main::point1)
[7] (byte) print::p_y#0 ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y)
[8] call print
to:main::@1
main::@1: scope:[main] from main
[11] (byte) print::p_x#1 ← *((byte*)&(struct Point) main::point2)
[12] (byte) print::p_y#1 ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y)
[13] call print
[9] (byte) print::p_x#1 ← *((byte*)&(struct Point) main::point2)
[10] (byte) print::p_y#1 ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y)
[11] call print
to:main::@return
main::@return: scope:[main] from main::@1
[14] return
[12] return
to:@return
(void()) print((byte) print::p_x , (byte) print::p_y)
print: scope:[print] from main main::@1
[15] (byte) print::p_y#2 ← phi( main/(byte) print::p_y#0 main::@1/(byte) print::p_y#1 )
[15] (byte) print::p_x#2 ← phi( main/(byte) print::p_x#0 main::@1/(byte) print::p_x#1 )
[16] *((const byte*) SCREEN) ← (byte) print::p_x#2
[17] *((const byte*) SCREEN+(byte) 1) ← (byte) print::p_y#2
[13] (byte) print::p_y#2 ← phi( main/(byte) print::p_y#0 main::@1/(byte) print::p_y#1 )
[13] (byte) print::p_x#2 ← phi( main/(byte) print::p_x#0 main::@1/(byte) print::p_x#1 )
[14] *((const byte*) SCREEN) ← (byte) print::p_x#2
[15] *((const byte*) SCREEN+(byte) 1) ← (byte) print::p_y#2
to:print::@return
print::@return: scope:[print] from print
[18] return
[16] return
to:@return
@ -212,6 +203,7 @@ Target platform is c64basic / MOS6502X
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1
// @begin
__bbegin:
@ -231,49 +223,51 @@ __bend:
main: {
.label point1 = 4
.label point2 = 6
// [4] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z point1
// [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta point1+OFFSET_STRUCT_POINT_Y
// [6] *((byte*)&(struct Point) main::point2) ← (byte) 4 -- _deref_pbuc1=vbuc2
lda #4
sta.z point2
// [7] *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5 -- _deref_pbuc1=vbuc2
lda #5
sta point2+OFFSET_STRUCT_POINT_Y
// [8] (byte) print::p_x#0 ← *((byte*)&(struct Point) main::point1) -- vbuz1=_deref_pbuc1
// [4] *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta point1-1,y
dey
bne !-
// [5] *(&(struct Point) main::point2) ← memcpy(*(&(const struct Point) $1), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __1-1,y
sta point2-1,y
dey
bne !-
// [6] (byte) print::p_x#0 ← *((byte*)&(struct Point) main::point1) -- vbuz1=_deref_pbuc1
lda.z point1
sta.z print.p_x
// [9] (byte) print::p_y#0 ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) -- vbuz1=_deref_pbuc1
// [7] (byte) print::p_y#0 ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) -- vbuz1=_deref_pbuc1
lda point1+OFFSET_STRUCT_POINT_Y
sta.z print.p_y
// [10] call print
// [15] phi from main to print [phi:main->print]
// [8] call print
// [13] phi from main to print [phi:main->print]
print_from_main:
// [15] phi (byte) print::p_y#2 = (byte) print::p_y#0 [phi:main->print#0] -- register_copy
// [15] phi (byte) print::p_x#2 = (byte) print::p_x#0 [phi:main->print#1] -- register_copy
// [13] phi (byte) print::p_y#2 = (byte) print::p_y#0 [phi:main->print#0] -- register_copy
// [13] phi (byte) print::p_x#2 = (byte) print::p_x#0 [phi:main->print#1] -- register_copy
jsr print
jmp __b1
// main::@1
__b1:
// [11] (byte) print::p_x#1 ← *((byte*)&(struct Point) main::point2) -- vbuz1=_deref_pbuc1
// [9] (byte) print::p_x#1 ← *((byte*)&(struct Point) main::point2) -- vbuz1=_deref_pbuc1
lda.z point2
sta.z print.p_x
// [12] (byte) print::p_y#1 ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) -- vbuz1=_deref_pbuc1
// [10] (byte) print::p_y#1 ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) -- vbuz1=_deref_pbuc1
lda point2+OFFSET_STRUCT_POINT_Y
sta.z print.p_y
// [13] call print
// [15] phi from main::@1 to print [phi:main::@1->print]
// [11] call print
// [13] phi from main::@1 to print [phi:main::@1->print]
print_from___b1:
// [15] phi (byte) print::p_y#2 = (byte) print::p_y#1 [phi:main::@1->print#0] -- register_copy
// [15] phi (byte) print::p_x#2 = (byte) print::p_x#1 [phi:main::@1->print#1] -- register_copy
// [13] phi (byte) print::p_y#2 = (byte) print::p_y#1 [phi:main::@1->print#0] -- register_copy
// [13] phi (byte) print::p_x#2 = (byte) print::p_x#1 [phi:main::@1->print#1] -- register_copy
jsr print
jmp __breturn
// main::@return
__breturn:
// [14] return
// [12] return
rts
}
// print
@ -281,25 +275,25 @@ main: {
print: {
.label p_x = 2
.label p_y = 3
// [16] *((const byte*) SCREEN) ← (byte) print::p_x#2 -- _deref_pbuc1=vbuz1
// [14] *((const byte*) SCREEN) ← (byte) print::p_x#2 -- _deref_pbuc1=vbuz1
lda.z p_x
sta SCREEN
// [17] *((const byte*) SCREEN+(byte) 1) ← (byte) print::p_y#2 -- _deref_pbuc1=vbuz1
// [15] *((const byte*) SCREEN+(byte) 1) ← (byte) print::p_y#2 -- _deref_pbuc1=vbuz1
lda.z p_y
sta SCREEN+1
jmp __breturn
// print::@return
__breturn:
// [18] return
// [16] return
rts
}
// File Data
__0: .byte 2, 3
__1: .byte 4, 5
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] *((byte*)&(struct Point) main::point1) ← (byte) 2 [ main::point1 main::point2 ] ( main:2 [ main::point1 main::point2 ] ) always clobbers reg byte a
Statement [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 [ main::point1 main::point2 ] ( main:2 [ main::point1 main::point2 ] ) always clobbers reg byte a
Statement [6] *((byte*)&(struct Point) main::point2) ← (byte) 4 [ main::point1 main::point2 ] ( main:2 [ main::point1 main::point2 ] ) always clobbers reg byte a
Statement [7] *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5 [ main::point1 main::point2 ] ( main:2 [ main::point1 main::point2 ] ) always clobbers reg byte a
Statement [4] *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) [ main::point1 main::point2 ] ( main:2 [ main::point1 main::point2 ] ) always clobbers reg byte a reg byte y
Statement [5] *(&(struct Point) main::point2) ← memcpy(*(&(const struct Point) $1), struct Point, (const byte) SIZEOF_STRUCT_POINT) [ main::point1 main::point2 ] ( main:2 [ main::point1 main::point2 ] ) always clobbers reg byte a reg byte y
Potential registers zp[1]:2 [ print::p_x#2 print::p_x#0 print::p_x#1 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:3 [ print::p_y#2 print::p_y#0 print::p_y#1 ] : zp[1]:3 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[2]:4 [ main::point1 ] : zp[2]:4 ,
@ -311,10 +305,10 @@ Uplift Scope [Point]
Uplift Scope [main] 0: zp[2]:4 [ main::point1 ] 0: zp[2]:6 [ main::point2 ]
Uplift Scope []
Uplifting [print] best 89 combination reg byte x [ print::p_y#2 print::p_y#0 print::p_y#1 ] reg byte a [ print::p_x#2 print::p_x#0 print::p_x#1 ]
Uplifting [Point] best 89 combination
Uplifting [main] best 89 combination zp[2]:4 [ main::point1 ] zp[2]:6 [ main::point2 ]
Uplifting [] best 89 combination
Uplifting [print] best 99 combination reg byte x [ print::p_y#2 print::p_y#0 print::p_y#1 ] reg byte a [ print::p_x#2 print::p_x#0 print::p_x#1 ]
Uplifting [Point] best 99 combination
Uplifting [main] best 99 combination zp[2]:4 [ main::point1 ] zp[2]:6 [ main::point2 ]
Uplifting [] best 99 combination
Allocated (was zp[2]:4) zp[2]:2 [ main::point1 ]
Allocated (was zp[2]:6) zp[2]:4 [ main::point2 ]
@ -327,6 +321,7 @@ ASSEMBLER BEFORE OPTIMIZATION
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1
// @begin
__bbegin:
@ -346,61 +341,65 @@ __bend:
main: {
.label point1 = 2
.label point2 = 4
// [4] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z point1
// [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta point1+OFFSET_STRUCT_POINT_Y
// [6] *((byte*)&(struct Point) main::point2) ← (byte) 4 -- _deref_pbuc1=vbuc2
lda #4
sta.z point2
// [7] *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5 -- _deref_pbuc1=vbuc2
lda #5
sta point2+OFFSET_STRUCT_POINT_Y
// [8] (byte) print::p_x#0 ← *((byte*)&(struct Point) main::point1) -- vbuaa=_deref_pbuc1
// [4] *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta point1-1,y
dey
bne !-
// [5] *(&(struct Point) main::point2) ← memcpy(*(&(const struct Point) $1), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __1-1,y
sta point2-1,y
dey
bne !-
// [6] (byte) print::p_x#0 ← *((byte*)&(struct Point) main::point1) -- vbuaa=_deref_pbuc1
lda.z point1
// [9] (byte) print::p_y#0 ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) -- vbuxx=_deref_pbuc1
// [7] (byte) print::p_y#0 ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) -- vbuxx=_deref_pbuc1
ldx point1+OFFSET_STRUCT_POINT_Y
// [10] call print
// [15] phi from main to print [phi:main->print]
// [8] call print
// [13] phi from main to print [phi:main->print]
print_from_main:
// [15] phi (byte) print::p_y#2 = (byte) print::p_y#0 [phi:main->print#0] -- register_copy
// [15] phi (byte) print::p_x#2 = (byte) print::p_x#0 [phi:main->print#1] -- register_copy
// [13] phi (byte) print::p_y#2 = (byte) print::p_y#0 [phi:main->print#0] -- register_copy
// [13] phi (byte) print::p_x#2 = (byte) print::p_x#0 [phi:main->print#1] -- register_copy
jsr print
jmp __b1
// main::@1
__b1:
// [11] (byte) print::p_x#1 ← *((byte*)&(struct Point) main::point2) -- vbuaa=_deref_pbuc1
// [9] (byte) print::p_x#1 ← *((byte*)&(struct Point) main::point2) -- vbuaa=_deref_pbuc1
lda.z point2
// [12] (byte) print::p_y#1 ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) -- vbuxx=_deref_pbuc1
// [10] (byte) print::p_y#1 ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) -- vbuxx=_deref_pbuc1
ldx point2+OFFSET_STRUCT_POINT_Y
// [13] call print
// [15] phi from main::@1 to print [phi:main::@1->print]
// [11] call print
// [13] phi from main::@1 to print [phi:main::@1->print]
print_from___b1:
// [15] phi (byte) print::p_y#2 = (byte) print::p_y#1 [phi:main::@1->print#0] -- register_copy
// [15] phi (byte) print::p_x#2 = (byte) print::p_x#1 [phi:main::@1->print#1] -- register_copy
// [13] phi (byte) print::p_y#2 = (byte) print::p_y#1 [phi:main::@1->print#0] -- register_copy
// [13] phi (byte) print::p_x#2 = (byte) print::p_x#1 [phi:main::@1->print#1] -- register_copy
jsr print
jmp __breturn
// main::@return
__breturn:
// [14] return
// [12] return
rts
}
// print
// print(byte register(A) p_x, byte register(X) p_y)
print: {
// [16] *((const byte*) SCREEN) ← (byte) print::p_x#2 -- _deref_pbuc1=vbuaa
// [14] *((const byte*) SCREEN) ← (byte) print::p_x#2 -- _deref_pbuc1=vbuaa
sta SCREEN
// [17] *((const byte*) SCREEN+(byte) 1) ← (byte) print::p_y#2 -- _deref_pbuc1=vbuxx
// [15] *((const byte*) SCREEN+(byte) 1) ← (byte) print::p_y#2 -- _deref_pbuc1=vbuxx
stx SCREEN+1
jmp __breturn
// print::@return
__breturn:
// [18] return
// [16] return
rts
}
// File Data
__0: .byte 2, 3
__1: .byte 4, 5
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
@ -428,6 +427,8 @@ Removing instruction __b1:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
(const struct Point) $0 = { x: (byte) 2, y: (byte) 3 }
(const struct Point) $1 = { x: (byte) 4, y: (byte) 5 }
(label) @1
(label) @begin
(label) @end
@ -435,6 +436,7 @@ FINAL SYMBOL TABLE
(byte) Point::x
(byte) Point::y
(const byte*) SCREEN = (byte*) 1024
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(void()) main()
(label) main::@1
(label) main::@return
@ -459,7 +461,7 @@ zp[2]:4 [ main::point2 ]
FINAL ASSEMBLER
Score: 68
Score: 78
// File Comments
// Minimal struct with C-Standard behavior - call parameter (not supported yet)
@ -469,6 +471,7 @@ Score: 68
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1
// @begin
// [1] phi from @begin to @1 [phi:@begin->@1]
@ -481,58 +484,62 @@ main: {
.label point1 = 2
.label point2 = 4
// point1 = { 2, 3 }
// [4] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z point1
// [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta point1+OFFSET_STRUCT_POINT_Y
// [4] *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta point1-1,y
dey
bne !-
// point2 = { 4, 5 }
// [6] *((byte*)&(struct Point) main::point2) ← (byte) 4 -- _deref_pbuc1=vbuc2
lda #4
sta.z point2
// [7] *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 5 -- _deref_pbuc1=vbuc2
lda #5
sta point2+OFFSET_STRUCT_POINT_Y
// [5] *(&(struct Point) main::point2) ← memcpy(*(&(const struct Point) $1), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __1-1,y
sta point2-1,y
dey
bne !-
// print(point1)
// [8] (byte) print::p_x#0 ← *((byte*)&(struct Point) main::point1) -- vbuaa=_deref_pbuc1
// [6] (byte) print::p_x#0 ← *((byte*)&(struct Point) main::point1) -- vbuaa=_deref_pbuc1
lda.z point1
// [9] (byte) print::p_y#0 ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) -- vbuxx=_deref_pbuc1
// [7] (byte) print::p_y#0 ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) -- vbuxx=_deref_pbuc1
ldx point1+OFFSET_STRUCT_POINT_Y
// [10] call print
// [15] phi from main to print [phi:main->print]
// [15] phi (byte) print::p_y#2 = (byte) print::p_y#0 [phi:main->print#0] -- register_copy
// [15] phi (byte) print::p_x#2 = (byte) print::p_x#0 [phi:main->print#1] -- register_copy
// [8] call print
// [13] phi from main to print [phi:main->print]
// [13] phi (byte) print::p_y#2 = (byte) print::p_y#0 [phi:main->print#0] -- register_copy
// [13] phi (byte) print::p_x#2 = (byte) print::p_x#0 [phi:main->print#1] -- register_copy
jsr print
// main::@1
// print(point2)
// [11] (byte) print::p_x#1 ← *((byte*)&(struct Point) main::point2) -- vbuaa=_deref_pbuc1
// [9] (byte) print::p_x#1 ← *((byte*)&(struct Point) main::point2) -- vbuaa=_deref_pbuc1
lda.z point2
// [12] (byte) print::p_y#1 ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) -- vbuxx=_deref_pbuc1
// [10] (byte) print::p_y#1 ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) -- vbuxx=_deref_pbuc1
ldx point2+OFFSET_STRUCT_POINT_Y
// [13] call print
// [15] phi from main::@1 to print [phi:main::@1->print]
// [15] phi (byte) print::p_y#2 = (byte) print::p_y#1 [phi:main::@1->print#0] -- register_copy
// [15] phi (byte) print::p_x#2 = (byte) print::p_x#1 [phi:main::@1->print#1] -- register_copy
// [11] call print
// [13] phi from main::@1 to print [phi:main::@1->print]
// [13] phi (byte) print::p_y#2 = (byte) print::p_y#1 [phi:main::@1->print#0] -- register_copy
// [13] phi (byte) print::p_x#2 = (byte) print::p_x#1 [phi:main::@1->print#1] -- register_copy
jsr print
// main::@return
// }
// [14] return
// [12] return
rts
}
// print
// print(byte register(A) p_x, byte register(X) p_y)
print: {
// SCREEN[0] = p.x
// [16] *((const byte*) SCREEN) ← (byte) print::p_x#2 -- _deref_pbuc1=vbuaa
// [14] *((const byte*) SCREEN) ← (byte) print::p_x#2 -- _deref_pbuc1=vbuaa
sta SCREEN
// SCREEN[1] = p.y
// [17] *((const byte*) SCREEN+(byte) 1) ← (byte) print::p_y#2 -- _deref_pbuc1=vbuxx
// [15] *((const byte*) SCREEN+(byte) 1) ← (byte) print::p_y#2 -- _deref_pbuc1=vbuxx
stx SCREEN+1
// print::@return
// }
// [18] return
// [16] return
rts
}
// File Data
__0: .byte 2, 3
__1: .byte 4, 5

View File

@ -1,3 +1,5 @@
(const struct Point) $0 = { x: (byte) 2, y: (byte) 3 }
(const struct Point) $1 = { x: (byte) 4, y: (byte) 5 }
(label) @1
(label) @begin
(label) @end
@ -5,6 +7,7 @@
(byte) Point::x
(byte) Point::y
(const byte*) SCREEN = (byte*) 1024
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(void()) main()
(label) main::@1
(label) main::@return

View File

@ -3,15 +3,15 @@
:BasicUpstart(main)
.pc = $80d "Program"
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 3
.const OFFSET_STRUCT_POINT_INITIALS = 1
main: {
.label point1 = 2
ldy #SIZEOF_STRUCT_POINT
lda #0
sta.z point1
ldx #2
!:
dex
sta point1+OFFSET_STRUCT_POINT_INITIALS,x
dey
sta point1,y
bne !-
lda #2
sta.z point1

View File

@ -10,15 +10,14 @@
(void()) main()
main: scope:[main] from @1
[4] *((byte*)&(struct Point) main::point1) ← (byte) 0
[5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memset((number) 2)
[6] *((byte*)&(struct Point) main::point1) ← (byte) 2
[7] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← (byte) 'j'
[8] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) ← (byte) 'g'
[9] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1)
[10] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS)
[11] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1)
[4] *(&(struct Point) main::point1) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT)
[5] *((byte*)&(struct Point) main::point1) ← (byte) 2
[6] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← (byte) 'j'
[7] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) ← (byte) 'g'
[8] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1)
[9] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS)
[10] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1)
to:main::@return
main::@return: scope:[main] from main
[12] return
[11] return
to:@return

View File

@ -1,8 +1,7 @@
Fixing struct type size struct Point to 3
Fixing struct type SIZE_OF struct Point to 3
Fixing struct type SIZE_OF struct Point to 3
Adding struct value member variable copy *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 0
Adding struct value member variable copy *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memset((number) 2)
Adding struct value member variable copy *(&(struct Point) main::point1) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT)
Replacing struct member reference (struct Point) main::point1.x with member unwinding reference *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X)
Replacing struct member reference (struct Point) main::point1.initials with member unwinding reference (byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS
Replacing struct member reference (struct Point) main::point1.initials with member unwinding reference (byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS
@ -16,9 +15,7 @@ CONTROL FLOW GRAPH SSA
(void()) main()
main: scope:[main] from @1
*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 0
*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memset((number) 2)
(struct Point) main::point1 ← struct-unwound {*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS)}
*(&(struct Point) main::point1) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT)
*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (number) 2
*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (number) 0) ← (byte) 'j'
*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (number) 1) ← (byte) 'g'
@ -46,6 +43,7 @@ SYMBOL TABLE SSA
(const byte*) Point::initials[(number) 2] = { fill( 2, 0) }
(byte) Point::x
(const byte*) SCREEN = (byte*)(number) $400
(const byte) SIZEOF_STRUCT_POINT = (byte) 3
(void()) main()
(label) main::@return
(struct Point) main::point1 loadstore
@ -80,13 +78,11 @@ Finalized unsigned number type (byte) 1
Finalized unsigned number type (byte) 1
Finalized unsigned number type (byte) 2
Successful SSA optimization PassNFinalizeNumberTypeConversions
Removing C-classic struct-unwound assignment [2] (struct Point) main::point1 ← struct-unwound {*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS)}
Simplifying expression containing zero (byte*)&main::point1 in [0] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 0
Simplifying expression containing zero (byte*)&main::point1 in [3] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
Simplifying expression containing zero (byte*)&main::point1+OFFSET_STRUCT_POINT_INITIALS in [4] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (byte) 0) ← (byte) 'j'
Simplifying expression containing zero (byte*)&main::point1 in [6] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero SCREEN in [6] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) main::point1)
Simplifying expression containing zero (byte*)&main::point1+OFFSET_STRUCT_POINT_INITIALS in [7] *((const byte*) SCREEN + (byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (byte) 0)
Simplifying expression containing zero (byte*)&main::point1 in [1] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
Simplifying expression containing zero (byte*)&main::point1+OFFSET_STRUCT_POINT_INITIALS in [2] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (byte) 0) ← (byte) 'j'
Simplifying expression containing zero (byte*)&main::point1 in [4] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero SCREEN in [4] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) main::point1)
Simplifying expression containing zero (byte*)&main::point1+OFFSET_STRUCT_POINT_INITIALS in [5] *((const byte*) SCREEN + (byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (byte) 0)
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant (const byte) OFFSET_STRUCT_POINT_X
Successful SSA optimization PassNEliminateUnusedVars
@ -122,17 +118,16 @@ FINAL CONTROL FLOW GRAPH
(void()) main()
main: scope:[main] from @1
[4] *((byte*)&(struct Point) main::point1) ← (byte) 0
[5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memset((number) 2)
[6] *((byte*)&(struct Point) main::point1) ← (byte) 2
[7] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← (byte) 'j'
[8] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) ← (byte) 'g'
[9] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1)
[10] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS)
[11] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1)
[4] *(&(struct Point) main::point1) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT)
[5] *((byte*)&(struct Point) main::point1) ← (byte) 2
[6] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← (byte) 'j'
[7] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) ← (byte) 'g'
[8] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1)
[9] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS)
[10] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1)
to:main::@return
main::@return: scope:[main] from main
[12] return
[11] return
to:@return
@ -157,6 +152,7 @@ Target platform is c64basic / MOS6502X
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 3
.const OFFSET_STRUCT_POINT_INITIALS = 1
// @begin
__bbegin:
@ -175,51 +171,47 @@ __bend:
// main
main: {
.label point1 = 2
// [4] *((byte*)&(struct Point) main::point1) ← (byte) 0 -- _deref_pbuc1=vbuc2
lda #0
sta.z point1
// [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memset((number) 2) -- _deref_pbuc1=_memset_vbuc2
ldx #2
// [4] *(&(struct Point) main::point1) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_memset_vbuc2
ldy #SIZEOF_STRUCT_POINT
lda #0
!:
dex
sta point1+OFFSET_STRUCT_POINT_INITIALS,x
dey
sta point1,y
bne !-
// [6] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
// [5] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z point1
// [7] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← (byte) 'j' -- _deref_pbuc1=vbuc2
// [6] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← (byte) 'j' -- _deref_pbuc1=vbuc2
lda #'j'
sta point1+OFFSET_STRUCT_POINT_INITIALS
// [8] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) ← (byte) 'g' -- _deref_pbuc1=vbuc2
// [7] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) ← (byte) 'g' -- _deref_pbuc1=vbuc2
lda #'g'
sta point1+OFFSET_STRUCT_POINT_INITIALS+1
// [9] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2
// [8] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2
lda.z point1
sta SCREEN
// [10] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2
// [9] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2
lda point1+OFFSET_STRUCT_POINT_INITIALS
sta SCREEN+1
// [11] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2
// [10] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2
lda point1+OFFSET_STRUCT_POINT_INITIALS+1
sta SCREEN+2
jmp __breturn
// main::@return
__breturn:
// [12] return
// [11] return
rts
}
// File Data
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] *((byte*)&(struct Point) main::point1) ← (byte) 0 [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a
Statement [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memset((number) 2) [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a reg byte x
Statement [6] *((byte*)&(struct Point) main::point1) ← (byte) 2 [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a
Statement [7] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← (byte) 'j' [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a
Statement [8] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) ← (byte) 'g' [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a
Statement [9] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a
Statement [10] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a
Statement [11] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [4] *(&(struct Point) main::point1) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT) [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a reg byte y
Statement [5] *((byte*)&(struct Point) main::point1) ← (byte) 2 [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a
Statement [6] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← (byte) 'j' [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a
Statement [7] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) ← (byte) 'g' [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a
Statement [8] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a
Statement [9] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a
Statement [10] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) [ ] ( main:2 [ ] ) always clobbers reg byte a
Potential registers zp[3]:2 [ main::point1 ] : zp[3]:2 ,
REGISTER UPLIFT SCOPES
@ -227,9 +219,9 @@ Uplift Scope [Point]
Uplift Scope [main] 0: zp[3]:2 [ main::point1 ]
Uplift Scope []
Uplifting [Point] best 79 combination
Uplifting [main] best 79 combination zp[3]:2 [ main::point1 ]
Uplifting [] best 79 combination
Uplifting [Point] best 74 combination
Uplifting [main] best 74 combination zp[3]:2 [ main::point1 ]
Uplifting [] best 74 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
@ -240,6 +232,7 @@ ASSEMBLER BEFORE OPTIMIZATION
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 3
.const OFFSET_STRUCT_POINT_INITIALS = 1
// @begin
__bbegin:
@ -258,38 +251,35 @@ __bend:
// main
main: {
.label point1 = 2
// [4] *((byte*)&(struct Point) main::point1) ← (byte) 0 -- _deref_pbuc1=vbuc2
lda #0
sta.z point1
// [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memset((number) 2) -- _deref_pbuc1=_memset_vbuc2
ldx #2
// [4] *(&(struct Point) main::point1) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_memset_vbuc2
ldy #SIZEOF_STRUCT_POINT
lda #0
!:
dex
sta point1+OFFSET_STRUCT_POINT_INITIALS,x
dey
sta point1,y
bne !-
// [6] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
// [5] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z point1
// [7] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← (byte) 'j' -- _deref_pbuc1=vbuc2
// [6] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← (byte) 'j' -- _deref_pbuc1=vbuc2
lda #'j'
sta point1+OFFSET_STRUCT_POINT_INITIALS
// [8] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) ← (byte) 'g' -- _deref_pbuc1=vbuc2
// [7] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) ← (byte) 'g' -- _deref_pbuc1=vbuc2
lda #'g'
sta point1+OFFSET_STRUCT_POINT_INITIALS+1
// [9] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2
// [8] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2
lda.z point1
sta SCREEN
// [10] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2
// [9] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2
lda point1+OFFSET_STRUCT_POINT_INITIALS
sta SCREEN+1
// [11] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2
// [10] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2
lda point1+OFFSET_STRUCT_POINT_INITIALS+1
sta SCREEN+2
jmp __breturn
// main::@return
__breturn:
// [12] return
// [11] return
rts
}
// File Data
@ -299,8 +289,6 @@ Removing instruction jmp __b1
Removing instruction jmp __bend
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction lda #0
Succesful ASM optimization Pass5UnnecesaryLoadElimination
Replacing label __bbegin with __b1
Removing instruction __bbegin:
Removing instruction __b1_from___bbegin:
@ -323,6 +311,7 @@ FINAL SYMBOL TABLE
(const byte*) Point::initials[(number) 2] = { fill( 2, 0) }
(byte) Point::x
(const byte*) SCREEN = (byte*) 1024
(const byte) SIZEOF_STRUCT_POINT = (byte) 3
(void()) main()
(label) main::@return
(struct Point) main::point1 loadstore zp[3]:2
@ -331,7 +320,7 @@ zp[3]:2 [ main::point1 ]
FINAL ASSEMBLER
Score: 62
Score: 59
// File Comments
// Minimal struct with C-Standard behavior - member array
@ -341,6 +330,7 @@ Score: 62
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 3
.const OFFSET_STRUCT_POINT_INITIALS = 1
// @begin
// [1] phi from @begin to @1 [phi:@begin->@1]
@ -352,42 +342,40 @@ Score: 62
main: {
.label point1 = 2
// point1
// [4] *((byte*)&(struct Point) main::point1) ← (byte) 0 -- _deref_pbuc1=vbuc2
// [4] *(&(struct Point) main::point1) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_memset_vbuc2
ldy #SIZEOF_STRUCT_POINT
lda #0
sta.z point1
// [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memset((number) 2) -- _deref_pbuc1=_memset_vbuc2
ldx #2
!:
dex
sta point1+OFFSET_STRUCT_POINT_INITIALS,x
dey
sta point1,y
bne !-
// point1.x = 2
// [6] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
// [5] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z point1
// point1.initials[0] = 'j'
// [7] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← (byte) 'j' -- _deref_pbuc1=vbuc2
// [6] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← (byte) 'j' -- _deref_pbuc1=vbuc2
lda #'j'
sta point1+OFFSET_STRUCT_POINT_INITIALS
// point1.initials[1] = 'g'
// [8] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) ← (byte) 'g' -- _deref_pbuc1=vbuc2
// [7] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) ← (byte) 'g' -- _deref_pbuc1=vbuc2
lda #'g'
sta point1+OFFSET_STRUCT_POINT_INITIALS+1
// SCREEN[0] = point1.x
// [9] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2
// [8] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2
lda.z point1
sta SCREEN
// SCREEN[1] = point1.initials[0]
// [10] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2
// [9] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2
lda point1+OFFSET_STRUCT_POINT_INITIALS
sta SCREEN+1
// SCREEN[2] = point1.initials[1]
// [11] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2
// [10] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2
lda point1+OFFSET_STRUCT_POINT_INITIALS+1
sta SCREEN+2
// main::@return
// }
// [12] return
// [11] return
rts
}
// File Data

View File

@ -5,6 +5,7 @@
(const byte*) Point::initials[(number) 2] = { fill( 2, 0) }
(byte) Point::x
(const byte*) SCREEN = (byte*) 1024
(const byte) SIZEOF_STRUCT_POINT = (byte) 3
(void()) main()
(label) main::@return
(struct Point) main::point1 loadstore zp[3]:2

View File

@ -3,16 +3,16 @@
:BasicUpstart(main)
.pc = $80d "Program"
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 3
.const OFFSET_STRUCT_POINT_INITIALS = 1
main: {
.label point1 = 2
.label point2 = 5
ldy #SIZEOF_STRUCT_POINT
lda #0
sta.z point1
ldx #2
!:
dex
sta point1+OFFSET_STRUCT_POINT_INITIALS,x
dey
sta point1,y
bne !-
lda #2
sta.z point1
@ -20,12 +20,10 @@ main: {
sta point1+OFFSET_STRUCT_POINT_INITIALS
lda #'g'
sta point1+OFFSET_STRUCT_POINT_INITIALS+1
lda.z point1
sta.z point2
ldy #2
ldy #SIZEOF_STRUCT_POINT
!:
lda point1+OFFSET_STRUCT_POINT_INITIALS-1,y
sta point2+OFFSET_STRUCT_POINT_INITIALS-1,y
lda point1-1,y
sta point2-1,y
dey
bne !-
lda.z point2

View File

@ -10,17 +10,15 @@
(void()) main()
main: scope:[main] from @1
[4] *((byte*)&(struct Point) main::point1) ← (byte) 0
[5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memset((number) 2)
[6] *((byte*)&(struct Point) main::point1) ← (byte) 2
[7] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← (byte) 'j'
[8] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) ← (byte) 'g'
[9] *((byte*)&(struct Point) main::point2) ← *((byte*)&(struct Point) main::point1)
[10] *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS), (number) 2)
[11] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2)
[12] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS)
[13] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1)
[4] *(&(struct Point) main::point1) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT)
[5] *((byte*)&(struct Point) main::point1) ← (byte) 2
[6] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← (byte) 'j'
[7] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) ← (byte) 'g'
[8] *(&(struct Point) main::point2) ← memcpy(*(&(struct Point) main::point1), struct Point, (const byte) SIZEOF_STRUCT_POINT)
[9] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2)
[10] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS)
[11] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1)
to:main::@return
main::@return: scope:[main] from main
[14] return
[12] return
to:@return

View File

@ -2,10 +2,8 @@ Fixing struct type size struct Point to 3
Fixing struct type size struct Point to 3
Fixing struct type SIZE_OF struct Point to 3
Fixing struct type SIZE_OF struct Point to 3
Adding struct value member variable copy *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 0
Adding struct value member variable copy *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memset((number) 2)
Adding struct value member variable copy *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X)
Adding struct value member variable copy *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS), (number) 2)
Adding struct value member variable copy *(&(struct Point) main::point1) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT)
Adding struct value member variable copy *(&(struct Point) main::point2) ← memcpy(*(&(struct Point) main::point1), struct Point, (const byte) SIZEOF_STRUCT_POINT)
Replacing struct member reference (struct Point) main::point1.x with member unwinding reference *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X)
Replacing struct member reference (struct Point) main::point1.initials with member unwinding reference (byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS
Replacing struct member reference (struct Point) main::point1.initials with member unwinding reference (byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS
@ -19,15 +17,11 @@ CONTROL FLOW GRAPH SSA
(void()) main()
main: scope:[main] from @1
*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 0
*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memset((number) 2)
(struct Point) main::point1 ← struct-unwound {*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS)}
*(&(struct Point) main::point1) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT)
*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (number) 2
*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (number) 0) ← (byte) 'j'
*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (number) 1) ← (byte) 'g'
*((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X)
*((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS), (number) 2)
(struct Point) main::point2 ← struct-unwound {*((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS)}
*(&(struct Point) main::point2) ← memcpy(*(&(struct Point) main::point1), struct Point, (const byte) SIZEOF_STRUCT_POINT)
*((const byte*) SCREEN + (number) 0) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X)
*((const byte*) SCREEN + (number) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS + (number) 0)
*((const byte*) SCREEN + (number) 2) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS + (number) 1)
@ -52,6 +46,7 @@ SYMBOL TABLE SSA
(const byte*) Point::initials[(number) 2] = { fill( 2, 0) }
(byte) Point::x
(const byte*) SCREEN = (byte*)(number) $400
(const byte) SIZEOF_STRUCT_POINT = (byte) 3
(void()) main()
(label) main::@return
(struct Point) main::point1 loadstore
@ -87,16 +82,11 @@ Finalized unsigned number type (byte) 1
Finalized unsigned number type (byte) 1
Finalized unsigned number type (byte) 2
Successful SSA optimization PassNFinalizeNumberTypeConversions
Removing C-classic struct-unwound assignment [2] (struct Point) main::point1 ← struct-unwound {*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS)}
Removing C-classic struct-unwound assignment [8] (struct Point) main::point2 ← struct-unwound {*((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS)}
Simplifying expression containing zero (byte*)&main::point1 in [0] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 0
Simplifying expression containing zero (byte*)&main::point1 in [3] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
Simplifying expression containing zero (byte*)&main::point1+OFFSET_STRUCT_POINT_INITIALS in [4] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (byte) 0) ← (byte) 'j'
Simplifying expression containing zero (byte*)&main::point1 in [6] *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero (byte*)&main::point2 in [6] *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X) ← *((byte*)&(struct Point) main::point1)
Simplifying expression containing zero (byte*)&main::point2 in [9] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero SCREEN in [9] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) main::point2)
Simplifying expression containing zero (byte*)&main::point2+OFFSET_STRUCT_POINT_INITIALS in [10] *((const byte*) SCREEN + (byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS + (byte) 0)
Simplifying expression containing zero (byte*)&main::point1 in [1] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
Simplifying expression containing zero (byte*)&main::point1+OFFSET_STRUCT_POINT_INITIALS in [2] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (byte) 0) ← (byte) 'j'
Simplifying expression containing zero (byte*)&main::point2 in [5] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero SCREEN in [5] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) main::point2)
Simplifying expression containing zero (byte*)&main::point2+OFFSET_STRUCT_POINT_INITIALS in [6] *((const byte*) SCREEN + (byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS + (byte) 0)
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant (const byte) OFFSET_STRUCT_POINT_X
Successful SSA optimization PassNEliminateUnusedVars
@ -132,19 +122,17 @@ FINAL CONTROL FLOW GRAPH
(void()) main()
main: scope:[main] from @1
[4] *((byte*)&(struct Point) main::point1) ← (byte) 0
[5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memset((number) 2)
[6] *((byte*)&(struct Point) main::point1) ← (byte) 2
[7] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← (byte) 'j'
[8] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) ← (byte) 'g'
[9] *((byte*)&(struct Point) main::point2) ← *((byte*)&(struct Point) main::point1)
[10] *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS), (number) 2)
[11] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2)
[12] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS)
[13] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1)
[4] *(&(struct Point) main::point1) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT)
[5] *((byte*)&(struct Point) main::point1) ← (byte) 2
[6] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← (byte) 'j'
[7] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) ← (byte) 'g'
[8] *(&(struct Point) main::point2) ← memcpy(*(&(struct Point) main::point1), struct Point, (const byte) SIZEOF_STRUCT_POINT)
[9] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2)
[10] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS)
[11] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1)
to:main::@return
main::@return: scope:[main] from main
[14] return
[12] return
to:@return
@ -173,6 +161,7 @@ Target platform is c64basic / MOS6502X
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 3
.const OFFSET_STRUCT_POINT_INITIALS = 1
// @begin
__bbegin:
@ -192,63 +181,55 @@ __bend:
main: {
.label point1 = 2
.label point2 = 5
// [4] *((byte*)&(struct Point) main::point1) ← (byte) 0 -- _deref_pbuc1=vbuc2
lda #0
sta.z point1
// [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memset((number) 2) -- _deref_pbuc1=_memset_vbuc2
ldx #2
// [4] *(&(struct Point) main::point1) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_memset_vbuc2
ldy #SIZEOF_STRUCT_POINT
lda #0
!:
dex
sta point1+OFFSET_STRUCT_POINT_INITIALS,x
dey
sta point1,y
bne !-
// [6] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
// [5] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z point1
// [7] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← (byte) 'j' -- _deref_pbuc1=vbuc2
// [6] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← (byte) 'j' -- _deref_pbuc1=vbuc2
lda #'j'
sta point1+OFFSET_STRUCT_POINT_INITIALS
// [8] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) ← (byte) 'g' -- _deref_pbuc1=vbuc2
// [7] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) ← (byte) 'g' -- _deref_pbuc1=vbuc2
lda #'g'
sta point1+OFFSET_STRUCT_POINT_INITIALS+1
// [9] *((byte*)&(struct Point) main::point2) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2
lda.z point1
sta.z point2
// [10] *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS), (number) 2) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3
ldy #2
// [8] *(&(struct Point) main::point2) ← memcpy(*(&(struct Point) main::point1), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda point1+OFFSET_STRUCT_POINT_INITIALS-1,y
sta point2+OFFSET_STRUCT_POINT_INITIALS-1,y
lda point1-1,y
sta point2-1,y
dey
bne !-
// [11] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2) -- _deref_pbuc1=_deref_pbuc2
// [9] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2) -- _deref_pbuc1=_deref_pbuc2
lda.z point2
sta SCREEN
// [12] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2
// [10] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2
lda point2+OFFSET_STRUCT_POINT_INITIALS
sta SCREEN+1
// [13] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2
// [11] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2
lda point2+OFFSET_STRUCT_POINT_INITIALS+1
sta SCREEN+2
jmp __breturn
// main::@return
__breturn:
// [14] return
// [12] return
rts
}
// File Data
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] *((byte*)&(struct Point) main::point1) ← (byte) 0 [ main::point1 main::point2 ] ( main:2 [ main::point1 main::point2 ] ) always clobbers reg byte a
Statement [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memset((number) 2) [ main::point1 main::point2 ] ( main:2 [ main::point1 main::point2 ] ) always clobbers reg byte a reg byte x
Statement [6] *((byte*)&(struct Point) main::point1) ← (byte) 2 [ main::point1 main::point2 ] ( main:2 [ main::point1 main::point2 ] ) always clobbers reg byte a
Statement [7] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← (byte) 'j' [ main::point1 main::point2 ] ( main:2 [ main::point1 main::point2 ] ) always clobbers reg byte a
Statement [8] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) ← (byte) 'g' [ main::point1 main::point2 ] ( main:2 [ main::point1 main::point2 ] ) always clobbers reg byte a
Statement [9] *((byte*)&(struct Point) main::point2) ← *((byte*)&(struct Point) main::point1) [ main::point1 main::point2 ] ( main:2 [ main::point1 main::point2 ] ) always clobbers reg byte a
Statement [10] *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS), (number) 2) [ main::point2 ] ( main:2 [ main::point2 ] ) always clobbers reg byte a reg byte y
Statement [11] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2) [ main::point2 ] ( main:2 [ main::point2 ] ) always clobbers reg byte a
Statement [12] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS) [ main::point2 ] ( main:2 [ main::point2 ] ) always clobbers reg byte a
Statement [13] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [4] *(&(struct Point) main::point1) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT) [ main::point1 main::point2 ] ( main:2 [ main::point1 main::point2 ] ) always clobbers reg byte a reg byte y
Statement [5] *((byte*)&(struct Point) main::point1) ← (byte) 2 [ main::point1 main::point2 ] ( main:2 [ main::point1 main::point2 ] ) always clobbers reg byte a
Statement [6] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← (byte) 'j' [ main::point1 main::point2 ] ( main:2 [ main::point1 main::point2 ] ) always clobbers reg byte a
Statement [7] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) ← (byte) 'g' [ main::point1 main::point2 ] ( main:2 [ main::point1 main::point2 ] ) always clobbers reg byte a
Statement [8] *(&(struct Point) main::point2) ← memcpy(*(&(struct Point) main::point1), struct Point, (const byte) SIZEOF_STRUCT_POINT) [ main::point2 ] ( main:2 [ main::point2 ] ) always clobbers reg byte a reg byte y
Statement [9] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2) [ main::point2 ] ( main:2 [ main::point2 ] ) always clobbers reg byte a
Statement [10] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS) [ main::point2 ] ( main:2 [ main::point2 ] ) always clobbers reg byte a
Statement [11] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) [ ] ( main:2 [ ] ) always clobbers reg byte a
Potential registers zp[3]:2 [ main::point1 ] : zp[3]:2 ,
Potential registers zp[3]:5 [ main::point2 ] : zp[3]:5 ,
@ -257,9 +238,9 @@ Uplift Scope [Point]
Uplift Scope [main] 0: zp[3]:2 [ main::point1 ] 0: zp[3]:5 [ main::point2 ]
Uplift Scope []
Uplifting [Point] best 101 combination
Uplifting [main] best 101 combination zp[3]:2 [ main::point1 ] zp[3]:5 [ main::point2 ]
Uplifting [] best 101 combination
Uplifting [Point] best 90 combination
Uplifting [main] best 90 combination zp[3]:2 [ main::point1 ] zp[3]:5 [ main::point2 ]
Uplifting [] best 90 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
@ -270,6 +251,7 @@ ASSEMBLER BEFORE OPTIMIZATION
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 3
.const OFFSET_STRUCT_POINT_INITIALS = 1
// @begin
__bbegin:
@ -289,48 +271,42 @@ __bend:
main: {
.label point1 = 2
.label point2 = 5
// [4] *((byte*)&(struct Point) main::point1) ← (byte) 0 -- _deref_pbuc1=vbuc2
lda #0
sta.z point1
// [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memset((number) 2) -- _deref_pbuc1=_memset_vbuc2
ldx #2
// [4] *(&(struct Point) main::point1) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_memset_vbuc2
ldy #SIZEOF_STRUCT_POINT
lda #0
!:
dex
sta point1+OFFSET_STRUCT_POINT_INITIALS,x
dey
sta point1,y
bne !-
// [6] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
// [5] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z point1
// [7] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← (byte) 'j' -- _deref_pbuc1=vbuc2
// [6] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← (byte) 'j' -- _deref_pbuc1=vbuc2
lda #'j'
sta point1+OFFSET_STRUCT_POINT_INITIALS
// [8] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) ← (byte) 'g' -- _deref_pbuc1=vbuc2
// [7] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) ← (byte) 'g' -- _deref_pbuc1=vbuc2
lda #'g'
sta point1+OFFSET_STRUCT_POINT_INITIALS+1
// [9] *((byte*)&(struct Point) main::point2) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2
lda.z point1
sta.z point2
// [10] *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS), (number) 2) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3
ldy #2
// [8] *(&(struct Point) main::point2) ← memcpy(*(&(struct Point) main::point1), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda point1+OFFSET_STRUCT_POINT_INITIALS-1,y
sta point2+OFFSET_STRUCT_POINT_INITIALS-1,y
lda point1-1,y
sta point2-1,y
dey
bne !-
// [11] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2) -- _deref_pbuc1=_deref_pbuc2
// [9] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2) -- _deref_pbuc1=_deref_pbuc2
lda.z point2
sta SCREEN
// [12] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2
// [10] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2
lda point2+OFFSET_STRUCT_POINT_INITIALS
sta SCREEN+1
// [13] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2
// [11] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2
lda point2+OFFSET_STRUCT_POINT_INITIALS+1
sta SCREEN+2
jmp __breturn
// main::@return
__breturn:
// [14] return
// [12] return
rts
}
// File Data
@ -340,8 +316,6 @@ Removing instruction jmp __b1
Removing instruction jmp __bend
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction lda #0
Succesful ASM optimization Pass5UnnecesaryLoadElimination
Replacing label __bbegin with __b1
Removing instruction __bbegin:
Removing instruction __b1_from___bbegin:
@ -364,6 +338,7 @@ FINAL SYMBOL TABLE
(const byte*) Point::initials[(number) 2] = { fill( 2, 0) }
(byte) Point::x
(const byte*) SCREEN = (byte*) 1024
(const byte) SIZEOF_STRUCT_POINT = (byte) 3
(void()) main()
(label) main::@return
(struct Point) main::point1 loadstore zp[3]:2
@ -374,7 +349,7 @@ zp[3]:5 [ main::point2 ]
FINAL ASSEMBLER
Score: 84
Score: 75
// File Comments
// Minimal struct with C-Standard behavior - member is array, copy assignment
@ -384,6 +359,7 @@ Score: 84
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 3
.const OFFSET_STRUCT_POINT_INITIALS = 1
// @begin
// [1] phi from @begin to @1 [phi:@begin->@1]
@ -396,53 +372,48 @@ main: {
.label point1 = 2
.label point2 = 5
// point1
// [4] *((byte*)&(struct Point) main::point1) ← (byte) 0 -- _deref_pbuc1=vbuc2
// [4] *(&(struct Point) main::point1) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_memset_vbuc2
ldy #SIZEOF_STRUCT_POINT
lda #0
sta.z point1
// [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memset((number) 2) -- _deref_pbuc1=_memset_vbuc2
ldx #2
!:
dex
sta point1+OFFSET_STRUCT_POINT_INITIALS,x
dey
sta point1,y
bne !-
// point1.x = 2
// [6] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
// [5] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z point1
// point1.initials[0] = 'j'
// [7] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← (byte) 'j' -- _deref_pbuc1=vbuc2
// [6] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← (byte) 'j' -- _deref_pbuc1=vbuc2
lda #'j'
sta point1+OFFSET_STRUCT_POINT_INITIALS
// point1.initials[1] = 'g'
// [8] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) ← (byte) 'g' -- _deref_pbuc1=vbuc2
// [7] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) ← (byte) 'g' -- _deref_pbuc1=vbuc2
lda #'g'
sta point1+OFFSET_STRUCT_POINT_INITIALS+1
// point2 = point1
// [9] *((byte*)&(struct Point) main::point2) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2
lda.z point1
sta.z point2
// [10] *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS), (number) 2) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3
ldy #2
// [8] *(&(struct Point) main::point2) ← memcpy(*(&(struct Point) main::point1), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda point1+OFFSET_STRUCT_POINT_INITIALS-1,y
sta point2+OFFSET_STRUCT_POINT_INITIALS-1,y
lda point1-1,y
sta point2-1,y
dey
bne !-
// SCREEN[0] = point2.x
// [11] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2) -- _deref_pbuc1=_deref_pbuc2
// [9] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2) -- _deref_pbuc1=_deref_pbuc2
lda.z point2
sta SCREEN
// SCREEN[1] = point2.initials[0]
// [12] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2
// [10] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2
lda point2+OFFSET_STRUCT_POINT_INITIALS
sta SCREEN+1
// SCREEN[2] = point2.initials[1]
// [13] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2
// [11] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2
lda point2+OFFSET_STRUCT_POINT_INITIALS+1
sta SCREEN+2
// main::@return
// }
// [14] return
// [12] return
rts
}
// File Data

View File

@ -5,6 +5,7 @@
(const byte*) Point::initials[(number) 2] = { fill( 2, 0) }
(byte) Point::x
(const byte*) SCREEN = (byte*) 1024
(const byte) SIZEOF_STRUCT_POINT = (byte) 3
(void()) main()
(label) main::@return
(struct Point) main::point1 loadstore zp[3]:2

View File

@ -3,15 +3,14 @@
:BasicUpstart(main)
.pc = $80d "Program"
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 4
.const OFFSET_STRUCT_POINT_INITIALS = 1
main: {
.label point1 = 2
lda #2
sta.z point1
ldy #3
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta point1+OFFSET_STRUCT_POINT_INITIALS-1,y
sta point1-1,y
dey
bne !-
lda.z point1
@ -22,5 +21,6 @@ main: {
sta SCREEN+2
rts
}
__0: .text "jg"
__0: .byte 2
.text "jg"
.byte 0

View File

@ -10,12 +10,11 @@
(void()) main()
main: scope:[main] from @1
[4] *((byte*)&(struct Point) main::point1) ← (byte) 2
[5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 3)
[6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1)
[7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS)
[8] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1)
[4] *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
[5] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1)
[6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS)
[7] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1)
to:main::@return
main::@return: scope:[main] from main
[9] return
[8] return
to:@return

View File

@ -1,8 +1,7 @@
Fixing struct type size struct Point to 4
Fixing struct type SIZE_OF struct Point to 4
Fixing struct type SIZE_OF struct Point to 4
Adding struct value member variable copy *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
Adding struct value member variable copy *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 3)
Adding struct value member variable copy *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
Replacing struct member reference (struct Point) main::point1.x with member unwinding reference *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X)
Replacing struct member reference (struct Point) main::point1.initials with member unwinding reference (byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS
Replacing struct member reference (struct Point) main::point1.initials with member unwinding reference (byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS
@ -13,9 +12,7 @@ CONTROL FLOW GRAPH SSA
(void()) main()
main: scope:[main] from @1
*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 3)
(struct Point) main::point1 ← struct-unwound {*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS)}
*(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
*((const byte*) SCREEN + (number) 0) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X)
*((const byte*) SCREEN + (number) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (number) 0)
*((const byte*) SCREEN + (number) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (number) 1)
@ -31,7 +28,7 @@ main::@return: scope:[main] from main
@end: scope:[] from @2
SYMBOL TABLE SSA
(const byte*) $0[(number) 3] = (string) "jg"
(const struct Point) $0 = { x: (byte) 2, initials: (string) "jg" }
(label) @1
(label) @2
(label) @begin
@ -41,6 +38,7 @@ SYMBOL TABLE SSA
(const byte*) Point::initials[(number) 3] = { fill( 3, 0) }
(byte) Point::x
(const byte*) SCREEN = (byte*)(number) $400
(const byte) SIZEOF_STRUCT_POINT = (byte) 4
(void()) main()
(label) main::@return
(struct Point) main::point1 loadstore
@ -64,11 +62,9 @@ Finalized unsigned number type (byte) 1
Finalized unsigned number type (byte) 1
Finalized unsigned number type (byte) 2
Successful SSA optimization PassNFinalizeNumberTypeConversions
Removing C-classic struct-unwound assignment [2] (struct Point) main::point1 ← struct-unwound {*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS)}
Simplifying expression containing zero (byte*)&main::point1 in [0] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
Simplifying expression containing zero (byte*)&main::point1 in [3] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero SCREEN in [3] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) main::point1)
Simplifying expression containing zero (byte*)&main::point1+OFFSET_STRUCT_POINT_INITIALS in [4] *((const byte*) SCREEN + (byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (byte) 0)
Simplifying expression containing zero (byte*)&main::point1 in [1] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero SCREEN in [1] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) main::point1)
Simplifying expression containing zero (byte*)&main::point1+OFFSET_STRUCT_POINT_INITIALS in [2] *((const byte*) SCREEN + (byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (byte) 0)
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant (const byte) OFFSET_STRUCT_POINT_X
Successful SSA optimization PassNEliminateUnusedVars
@ -103,14 +99,13 @@ FINAL CONTROL FLOW GRAPH
(void()) main()
main: scope:[main] from @1
[4] *((byte*)&(struct Point) main::point1) ← (byte) 2
[5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 3)
[6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1)
[7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS)
[8] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1)
[4] *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
[5] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1)
[6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS)
[7] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1)
to:main::@return
main::@return: scope:[main] from main
[9] return
[8] return
to:@return
@ -135,6 +130,7 @@ Target platform is c64basic / MOS6502X
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 4
.const OFFSET_STRUCT_POINT_INITIALS = 1
// @begin
__bbegin:
@ -153,41 +149,38 @@ __bend:
// main
main: {
.label point1 = 2
// [4] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z point1
// [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 3) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3
ldy #3
// [4] *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta point1+OFFSET_STRUCT_POINT_INITIALS-1,y
sta point1-1,y
dey
bne !-
// [6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2
// [5] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2
lda.z point1
sta SCREEN
// [7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2
// [6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2
lda point1+OFFSET_STRUCT_POINT_INITIALS
sta SCREEN+1
// [8] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2
// [7] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2
lda point1+OFFSET_STRUCT_POINT_INITIALS+1
sta SCREEN+2
jmp __breturn
// main::@return
__breturn:
// [9] return
// [8] return
rts
}
// File Data
__0: .text "jg"
__0: .byte 2
.text "jg"
.byte 0
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] *((byte*)&(struct Point) main::point1) ← (byte) 2 [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a
Statement [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 3) [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a reg byte y
Statement [6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a
Statement [7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a
Statement [8] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [4] *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a reg byte y
Statement [5] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a
Statement [6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a
Statement [7] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) [ ] ( main:2 [ ] ) always clobbers reg byte a
Potential registers zp[4]:2 [ main::point1 ] : zp[4]:2 ,
REGISTER UPLIFT SCOPES
@ -195,9 +188,9 @@ Uplift Scope [Point]
Uplift Scope [main] 0: zp[4]:2 [ main::point1 ]
Uplift Scope []
Uplifting [Point] best 65 combination
Uplifting [main] best 65 combination zp[4]:2 [ main::point1 ]
Uplifting [] best 65 combination
Uplifting [Point] best 60 combination
Uplifting [main] best 60 combination zp[4]:2 [ main::point1 ]
Uplifting [] best 60 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
@ -208,6 +201,7 @@ ASSEMBLER BEFORE OPTIMIZATION
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 4
.const OFFSET_STRUCT_POINT_INITIALS = 1
// @begin
__bbegin:
@ -226,33 +220,31 @@ __bend:
// main
main: {
.label point1 = 2
// [4] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z point1
// [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 3) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3
ldy #3
// [4] *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta point1+OFFSET_STRUCT_POINT_INITIALS-1,y
sta point1-1,y
dey
bne !-
// [6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2
// [5] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2
lda.z point1
sta SCREEN
// [7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2
// [6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2
lda point1+OFFSET_STRUCT_POINT_INITIALS
sta SCREEN+1
// [8] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2
// [7] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2
lda point1+OFFSET_STRUCT_POINT_INITIALS+1
sta SCREEN+2
jmp __breturn
// main::@return
__breturn:
// [9] return
// [8] return
rts
}
// File Data
__0: .text "jg"
__0: .byte 2
.text "jg"
.byte 0
ASSEMBLER OPTIMIZATIONS
@ -275,7 +267,7 @@ Removing instruction __b1:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
(const byte*) $0[(number) 3] = (string) "jg"
(const struct Point) $0 = { x: (byte) 2, initials: (string) "jg" }
(label) @1
(label) @begin
(label) @end
@ -283,6 +275,7 @@ FINAL SYMBOL TABLE
(const byte*) Point::initials[(number) 3] = { fill( 3, 0) }
(byte) Point::x
(const byte*) SCREEN = (byte*) 1024
(const byte) SIZEOF_STRUCT_POINT = (byte) 4
(void()) main()
(label) main::@return
(struct Point) main::point1 loadstore zp[4]:2
@ -291,7 +284,7 @@ zp[4]:2 [ main::point1 ]
FINAL ASSEMBLER
Score: 50
Score: 45
// File Comments
// Minimal struct with C-Standard behavior - member is array, copy assignment
@ -301,6 +294,7 @@ Score: 50
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 4
.const OFFSET_STRUCT_POINT_INITIALS = 1
// @begin
// [1] phi from @begin to @1 [phi:@begin->@1]
@ -312,34 +306,32 @@ Score: 50
main: {
.label point1 = 2
// point1 = { 2, "jg" }
// [4] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z point1
// [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 3) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3
ldy #3
// [4] *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta point1+OFFSET_STRUCT_POINT_INITIALS-1,y
sta point1-1,y
dey
bne !-
// SCREEN[0] = point1.x
// [6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2
// [5] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2
lda.z point1
sta SCREEN
// SCREEN[1] = point1.initials[0]
// [7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2
// [6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2
lda point1+OFFSET_STRUCT_POINT_INITIALS
sta SCREEN+1
// SCREEN[2] = point1.initials[1]
// [8] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2
// [7] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2
lda point1+OFFSET_STRUCT_POINT_INITIALS+1
sta SCREEN+2
// main::@return
// }
// [9] return
// [8] return
rts
}
// File Data
__0: .text "jg"
__0: .byte 2
.text "jg"
.byte 0

View File

@ -1,4 +1,4 @@
(const byte*) $0[(number) 3] = (string) "jg"
(const struct Point) $0 = { x: (byte) 2, initials: (string) "jg" }
(label) @1
(label) @begin
(label) @end
@ -6,6 +6,7 @@
(const byte*) Point::initials[(number) 3] = { fill( 3, 0) }
(byte) Point::x
(const byte*) SCREEN = (byte*) 1024
(const byte) SIZEOF_STRUCT_POINT = (byte) 4
(void()) main()
(label) main::@return
(struct Point) main::point1 loadstore zp[4]:2

View File

@ -3,15 +3,14 @@
:BasicUpstart(main)
.pc = $80d "Program"
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 3
.const OFFSET_STRUCT_POINT_INITIALS = 1
main: {
.label point1 = 2
lda #2
sta.z point1
tay
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta point1+OFFSET_STRUCT_POINT_INITIALS-1,y
sta point1-1,y
dey
bne !-
lda.z point1
@ -22,4 +21,4 @@ main: {
sta SCREEN+2
rts
}
__0: .byte 'j', 'g'
__0: .byte 2, 'j', 'g'

View File

@ -10,12 +10,11 @@
(void()) main()
main: scope:[main] from @1
[4] *((byte*)&(struct Point) main::point1) ← (byte) 2
[5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 2)
[6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1)
[7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS)
[8] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1)
[4] *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
[5] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1)
[6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS)
[7] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1)
to:main::@return
main::@return: scope:[main] from main
[9] return
[8] return
to:@return

View File

@ -1,8 +1,7 @@
Fixing struct type size struct Point to 3
Fixing struct type SIZE_OF struct Point to 3
Fixing struct type SIZE_OF struct Point to 3
Adding struct value member variable copy *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
Adding struct value member variable copy *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 2)
Adding struct value member variable copy *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
Replacing struct member reference (struct Point) main::point1.x with member unwinding reference *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X)
Replacing struct member reference (struct Point) main::point1.initials with member unwinding reference (byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS
Replacing struct member reference (struct Point) main::point1.initials with member unwinding reference (byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS
@ -13,9 +12,7 @@ CONTROL FLOW GRAPH SSA
(void()) main()
main: scope:[main] from @1
*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 2)
(struct Point) main::point1 ← struct-unwound {*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS)}
*(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
*((const byte*) SCREEN + (number) 0) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X)
*((const byte*) SCREEN + (number) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (number) 0)
*((const byte*) SCREEN + (number) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (number) 1)
@ -31,7 +28,7 @@ main::@return: scope:[main] from main
@end: scope:[] from @2
SYMBOL TABLE SSA
(const byte*) $0[(number) 2] = { (byte) 'j', (byte) 'g' }
(const struct Point) $0 = { x: (byte) 2, initials: { (byte) 'j', (byte) 'g' } }
(label) @1
(label) @2
(label) @begin
@ -41,6 +38,7 @@ SYMBOL TABLE SSA
(const byte*) Point::initials[(number) 2] = { fill( 2, 0) }
(byte) Point::x
(const byte*) SCREEN = (byte*)(number) $400
(const byte) SIZEOF_STRUCT_POINT = (byte) 3
(void()) main()
(label) main::@return
(struct Point) main::point1 loadstore
@ -64,11 +62,9 @@ Finalized unsigned number type (byte) 1
Finalized unsigned number type (byte) 1
Finalized unsigned number type (byte) 2
Successful SSA optimization PassNFinalizeNumberTypeConversions
Removing C-classic struct-unwound assignment [2] (struct Point) main::point1 ← struct-unwound {*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS)}
Simplifying expression containing zero (byte*)&main::point1 in [0] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
Simplifying expression containing zero (byte*)&main::point1 in [3] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero SCREEN in [3] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) main::point1)
Simplifying expression containing zero (byte*)&main::point1+OFFSET_STRUCT_POINT_INITIALS in [4] *((const byte*) SCREEN + (byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (byte) 0)
Simplifying expression containing zero (byte*)&main::point1 in [1] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero SCREEN in [1] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) main::point1)
Simplifying expression containing zero (byte*)&main::point1+OFFSET_STRUCT_POINT_INITIALS in [2] *((const byte*) SCREEN + (byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (byte) 0)
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant (const byte) OFFSET_STRUCT_POINT_X
Successful SSA optimization PassNEliminateUnusedVars
@ -103,14 +99,13 @@ FINAL CONTROL FLOW GRAPH
(void()) main()
main: scope:[main] from @1
[4] *((byte*)&(struct Point) main::point1) ← (byte) 2
[5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 2)
[6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1)
[7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS)
[8] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1)
[4] *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
[5] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1)
[6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS)
[7] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1)
to:main::@return
main::@return: scope:[main] from main
[9] return
[8] return
to:@return
@ -135,6 +130,7 @@ Target platform is c64basic / MOS6502X
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 3
.const OFFSET_STRUCT_POINT_INITIALS = 1
// @begin
__bbegin:
@ -153,40 +149,36 @@ __bend:
// main
main: {
.label point1 = 2
// [4] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z point1
// [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 2) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3
ldy #2
// [4] *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta point1+OFFSET_STRUCT_POINT_INITIALS-1,y
sta point1-1,y
dey
bne !-
// [6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2
// [5] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2
lda.z point1
sta SCREEN
// [7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2
// [6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2
lda point1+OFFSET_STRUCT_POINT_INITIALS
sta SCREEN+1
// [8] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2
// [7] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2
lda point1+OFFSET_STRUCT_POINT_INITIALS+1
sta SCREEN+2
jmp __breturn
// main::@return
__breturn:
// [9] return
// [8] return
rts
}
// File Data
__0: .byte 'j', 'g'
__0: .byte 2, 'j', 'g'
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] *((byte*)&(struct Point) main::point1) ← (byte) 2 [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a
Statement [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 2) [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a reg byte y
Statement [6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a
Statement [7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a
Statement [8] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [4] *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a reg byte y
Statement [5] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a
Statement [6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) [ main::point1 ] ( main:2 [ main::point1 ] ) always clobbers reg byte a
Statement [7] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) [ ] ( main:2 [ ] ) always clobbers reg byte a
Potential registers zp[3]:2 [ main::point1 ] : zp[3]:2 ,
REGISTER UPLIFT SCOPES
@ -194,9 +186,9 @@ Uplift Scope [Point]
Uplift Scope [main] 0: zp[3]:2 [ main::point1 ]
Uplift Scope []
Uplifting [Point] best 65 combination
Uplifting [main] best 65 combination zp[3]:2 [ main::point1 ]
Uplifting [] best 65 combination
Uplifting [Point] best 60 combination
Uplifting [main] best 60 combination zp[3]:2 [ main::point1 ]
Uplifting [] best 60 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
@ -207,6 +199,7 @@ ASSEMBLER BEFORE OPTIMIZATION
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 3
.const OFFSET_STRUCT_POINT_INITIALS = 1
// @begin
__bbegin:
@ -225,40 +218,36 @@ __bend:
// main
main: {
.label point1 = 2
// [4] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z point1
// [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 2) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3
ldy #2
// [4] *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta point1+OFFSET_STRUCT_POINT_INITIALS-1,y
sta point1-1,y
dey
bne !-
// [6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2
// [5] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2
lda.z point1
sta SCREEN
// [7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2
// [6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2
lda point1+OFFSET_STRUCT_POINT_INITIALS
sta SCREEN+1
// [8] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2
// [7] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2
lda point1+OFFSET_STRUCT_POINT_INITIALS+1
sta SCREEN+2
jmp __breturn
// main::@return
__breturn:
// [9] return
// [8] return
rts
}
// File Data
__0: .byte 'j', 'g'
__0: .byte 2, 'j', 'g'
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __bend
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Replacing instruction ldy #2 with TAY
Replacing label __bbegin with __b1
Removing instruction __bbegin:
Removing instruction __b1_from___bbegin:
@ -274,7 +263,7 @@ Removing instruction __b1:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
(const byte*) $0[(number) 2] = { (byte) 'j', (byte) 'g' }
(const struct Point) $0 = { x: (byte) 2, initials: { (byte) 'j', (byte) 'g' } }
(label) @1
(label) @begin
(label) @end
@ -282,6 +271,7 @@ FINAL SYMBOL TABLE
(const byte*) Point::initials[(number) 2] = { fill( 2, 0) }
(byte) Point::x
(const byte*) SCREEN = (byte*) 1024
(const byte) SIZEOF_STRUCT_POINT = (byte) 3
(void()) main()
(label) main::@return
(struct Point) main::point1 loadstore zp[3]:2
@ -290,7 +280,7 @@ zp[3]:2 [ main::point1 ]
FINAL ASSEMBLER
Score: 50
Score: 45
// File Comments
// Minimal struct with C-Standard behavior - member is array, copy assignment
@ -300,6 +290,7 @@ Score: 50
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 3
.const OFFSET_STRUCT_POINT_INITIALS = 1
// @begin
// [1] phi from @begin to @1 [phi:@begin->@1]
@ -311,33 +302,30 @@ Score: 50
main: {
.label point1 = 2
// point1 = { 2, { 'j', 'g' } }
// [4] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z point1
// [5] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 2) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3
tay
// [4] *(&(struct Point) main::point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta point1+OFFSET_STRUCT_POINT_INITIALS-1,y
sta point1-1,y
dey
bne !-
// SCREEN[0] = point1.x
// [6] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2
// [5] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point1) -- _deref_pbuc1=_deref_pbuc2
lda.z point1
sta SCREEN
// SCREEN[1] = point1.initials[0]
// [7] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2
// [6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2
lda point1+OFFSET_STRUCT_POINT_INITIALS
sta SCREEN+1
// SCREEN[2] = point1.initials[1]
// [8] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2
// [7] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2
lda point1+OFFSET_STRUCT_POINT_INITIALS+1
sta SCREEN+2
// main::@return
// }
// [9] return
// [8] return
rts
}
// File Data
__0: .byte 'j', 'g'
__0: .byte 2, 'j', 'g'

View File

@ -1,4 +1,4 @@
(const byte*) $0[(number) 2] = { (byte) 'j', (byte) 'g' }
(const struct Point) $0 = { x: (byte) 2, initials: { (byte) 'j', (byte) 'g' } }
(label) @1
(label) @begin
(label) @end
@ -6,6 +6,7 @@
(const byte*) Point::initials[(number) 2] = { fill( 2, 0) }
(byte) Point::x
(const byte*) SCREEN = (byte*) 1024
(const byte) SIZEOF_STRUCT_POINT = (byte) 3
(void()) main()
(label) main::@return
(struct Point) main::point1 loadstore zp[3]:2

View File

@ -3,14 +3,13 @@
:BasicUpstart(__bbegin)
.pc = $80d "Program"
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 3
.const OFFSET_STRUCT_POINT_INITIALS = 1
__bbegin:
lda #2
sta point1
tay
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta point1+OFFSET_STRUCT_POINT_INITIALS-1,y
sta point1-1,y
dey
bne !-
jsr main
@ -24,5 +23,5 @@ main: {
sta SCREEN+2
rts
}
__0: .byte 'j', 'g'
point1: .byte 0
__0: .byte 2, 'j', 'g'
point1: .fill SIZEOF_STRUCT_POINT, 0

View File

@ -1,20 +1,19 @@
@begin: scope:[] from
[0] *((byte*)&(struct Point) point1) ← (byte) 2
[1] *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 2)
[0] *(&(struct Point) point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
to:@1
@1: scope:[] from @begin
[2] phi()
[3] call main
[1] phi()
[2] call main
to:@end
@end: scope:[] from @1
[4] phi()
[3] phi()
(void()) main()
main: scope:[main] from @1
[5] *((const byte*) SCREEN) ← *((byte*)&(struct Point) point1)
[6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS)
[7] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1)
[4] *((const byte*) SCREEN) ← *((byte*)&(struct Point) point1)
[5] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS)
[6] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1)
to:main::@return
main::@return: scope:[main] from main
[8] return
[7] return
to:@return

View File

@ -1,17 +1,14 @@
Fixing struct type size struct Point to 3
Fixing struct type SIZE_OF struct Point to 3
Fixing struct type SIZE_OF struct Point to 3
Adding struct value member variable copy *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
Adding struct value member variable copy *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 2)
Adding struct value member variable copy *(&(struct Point) point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
Replacing struct member reference (struct Point) point1.x with member unwinding reference *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_X)
Replacing struct member reference (struct Point) point1.initials with member unwinding reference (byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS
Replacing struct member reference (struct Point) point1.initials with member unwinding reference (byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS
CONTROL FLOW GRAPH SSA
@begin: scope:[] from
*((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
*((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 2)
(struct Point) point1 ← struct-unwound {*((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS)}
*(&(struct Point) point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
to:@1
(void()) main()
@ -31,7 +28,7 @@ main::@return: scope:[main] from main
@end: scope:[] from @2
SYMBOL TABLE SSA
(const byte*) $0[(number) 2] = { (byte) 'j', (byte) 'g' }
(const struct Point) $0 = { x: (byte) 2, initials: { (byte) 'j', (byte) 'g' } }
(label) @1
(label) @2
(label) @begin
@ -41,6 +38,7 @@ SYMBOL TABLE SSA
(const byte*) Point::initials[(number) 2] = { fill( 2, 0) }
(byte) Point::x
(const byte*) SCREEN = (byte*)(number) $400
(const byte) SIZEOF_STRUCT_POINT = (byte) 3
(void()) main()
(label) main::@return
(struct Point) point1 loadstore
@ -64,11 +62,9 @@ Finalized unsigned number type (byte) 1
Finalized unsigned number type (byte) 1
Finalized unsigned number type (byte) 2
Successful SSA optimization PassNFinalizeNumberTypeConversions
Removing C-classic struct-unwound assignment [2] (struct Point) point1 ← struct-unwound {*((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS)}
Simplifying expression containing zero (byte*)&point1 in [0] *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
Simplifying expression containing zero (byte*)&point1 in [3] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero SCREEN in [3] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) point1)
Simplifying expression containing zero (byte*)&point1+OFFSET_STRUCT_POINT_INITIALS in [4] *((const byte*) SCREEN + (byte) 1) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (byte) 0)
Simplifying expression containing zero (byte*)&point1 in [1] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero SCREEN in [1] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) point1)
Simplifying expression containing zero (byte*)&point1+OFFSET_STRUCT_POINT_INITIALS in [2] *((const byte*) SCREEN + (byte) 1) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (byte) 0)
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant (const byte) OFFSET_STRUCT_POINT_X
Successful SSA optimization PassNEliminateUnusedVars
@ -80,7 +76,7 @@ Adding NOP phi() at start of @1
Adding NOP phi() at start of @2
Adding NOP phi() at start of @end
CALL GRAPH
Calls in [] to main:3
Calls in [] to main:2
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
@ -90,24 +86,23 @@ Adding NOP phi() at start of @end
FINAL CONTROL FLOW GRAPH
@begin: scope:[] from
[0] *((byte*)&(struct Point) point1) ← (byte) 2
[1] *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 2)
[0] *(&(struct Point) point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
to:@1
@1: scope:[] from @begin
[2] phi()
[3] call main
[1] phi()
[2] call main
to:@end
@end: scope:[] from @1
[4] phi()
[3] phi()
(void()) main()
main: scope:[main] from @1
[5] *((const byte*) SCREEN) ← *((byte*)&(struct Point) point1)
[6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS)
[7] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1)
[4] *((const byte*) SCREEN) ← *((byte*)&(struct Point) point1)
[5] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS)
[6] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1)
to:main::@return
main::@return: scope:[main] from main
[8] return
[7] return
to:@return
@ -132,58 +127,55 @@ Target platform is c64basic / MOS6502X
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 3
.const OFFSET_STRUCT_POINT_INITIALS = 1
// @begin
__bbegin:
// [0] *((byte*)&(struct Point) point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta point1
// [1] *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 2) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3
ldy #2
// [0] *(&(struct Point) point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta point1+OFFSET_STRUCT_POINT_INITIALS-1,y
sta point1-1,y
dey
bne !-
// [2] phi from @begin to @1 [phi:@begin->@1]
// [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin:
jmp __b1
// @1
__b1:
// [3] call main
// [2] call main
jsr main
// [4] phi from @1 to @end [phi:@1->@end]
// [3] phi from @1 to @end [phi:@1->@end]
__bend_from___b1:
jmp __bend
// @end
__bend:
// main
main: {
// [5] *((const byte*) SCREEN) ← *((byte*)&(struct Point) point1) -- _deref_pbuc1=_deref_pbuc2
// [4] *((const byte*) SCREEN) ← *((byte*)&(struct Point) point1) -- _deref_pbuc1=_deref_pbuc2
lda point1
sta SCREEN
// [6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2
// [5] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2
lda point1+OFFSET_STRUCT_POINT_INITIALS
sta SCREEN+1
// [7] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2
// [6] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2
lda point1+OFFSET_STRUCT_POINT_INITIALS+1
sta SCREEN+2
jmp __breturn
// main::@return
__breturn:
// [8] return
// [7] return
rts
}
// File Data
__0: .byte 'j', 'g'
point1: .byte 0
__0: .byte 2, 'j', 'g'
point1: .fill SIZEOF_STRUCT_POINT, 0
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] *((byte*)&(struct Point) point1) ← (byte) 2 [ point1 ] ( [ point1 ] ) always clobbers reg byte a
Statement [1] *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 2) [ point1 ] ( [ point1 ] ) always clobbers reg byte a reg byte y
Statement [5] *((const byte*) SCREEN) ← *((byte*)&(struct Point) point1) [ point1 ] ( main:3 [ point1 ] ) always clobbers reg byte a
Statement [6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) [ point1 ] ( main:3 [ point1 ] ) always clobbers reg byte a
Statement [7] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) [ ] ( main:3 [ ] ) always clobbers reg byte a
Statement [0] *(&(struct Point) point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) [ point1 ] ( [ point1 ] ) always clobbers reg byte a reg byte y
Statement [4] *((const byte*) SCREEN) ← *((byte*)&(struct Point) point1) [ point1 ] ( main:2 [ point1 ] ) always clobbers reg byte a
Statement [5] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) [ point1 ] ( main:2 [ point1 ] ) always clobbers reg byte a
Statement [6] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) [ ] ( main:2 [ ] ) always clobbers reg byte a
Potential registers mem[3] [ point1 ] : mem[3] ,
REGISTER UPLIFT SCOPES
@ -191,9 +183,9 @@ Uplift Scope [Point]
Uplift Scope [main]
Uplift Scope [] 0: mem[3] [ point1 ]
Uplifting [Point] best 67 combination
Uplifting [main] best 67 combination
Uplifting [] best 67 combination mem[3] [ point1 ]
Uplifting [Point] best 61 combination
Uplifting [main] best 61 combination
Uplifting [] best 61 combination mem[3] [ point1 ]
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
@ -204,58 +196,55 @@ ASSEMBLER BEFORE OPTIMIZATION
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 3
.const OFFSET_STRUCT_POINT_INITIALS = 1
// @begin
__bbegin:
// [0] *((byte*)&(struct Point) point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta point1
// [1] *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 2) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3
ldy #2
// [0] *(&(struct Point) point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta point1+OFFSET_STRUCT_POINT_INITIALS-1,y
sta point1-1,y
dey
bne !-
// [2] phi from @begin to @1 [phi:@begin->@1]
// [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin:
jmp __b1
// @1
__b1:
// [3] call main
// [2] call main
jsr main
// [4] phi from @1 to @end [phi:@1->@end]
// [3] phi from @1 to @end [phi:@1->@end]
__bend_from___b1:
jmp __bend
// @end
__bend:
// main
main: {
// [5] *((const byte*) SCREEN) ← *((byte*)&(struct Point) point1) -- _deref_pbuc1=_deref_pbuc2
// [4] *((const byte*) SCREEN) ← *((byte*)&(struct Point) point1) -- _deref_pbuc1=_deref_pbuc2
lda point1
sta SCREEN
// [6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2
// [5] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2
lda point1+OFFSET_STRUCT_POINT_INITIALS
sta SCREEN+1
// [7] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2
// [6] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2
lda point1+OFFSET_STRUCT_POINT_INITIALS+1
sta SCREEN+2
jmp __breturn
// main::@return
__breturn:
// [8] return
// [7] return
rts
}
// File Data
__0: .byte 'j', 'g'
point1: .byte 0
__0: .byte 2, 'j', 'g'
point1: .fill SIZEOF_STRUCT_POINT, 0
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __bend
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Replacing instruction ldy #2 with TAY
Removing instruction __b1_from___bbegin:
Removing instruction __bend_from___b1:
Succesful ASM optimization Pass5RedundantLabelElimination
@ -267,7 +256,7 @@ Adding RTS to root block
Succesful ASM optimization Pass5AddMainRts
FINAL SYMBOL TABLE
(const byte*) $0[(number) 2] = { (byte) 'j', (byte) 'g' }
(const struct Point) $0 = { x: (byte) 2, initials: { (byte) 'j', (byte) 'g' } }
(label) @1
(label) @begin
(label) @end
@ -275,6 +264,7 @@ FINAL SYMBOL TABLE
(const byte*) Point::initials[(number) 2] = { fill( 2, 0) }
(byte) Point::x
(const byte*) SCREEN = (byte*) 1024
(const byte) SIZEOF_STRUCT_POINT = (byte) 3
(void()) main()
(label) main::@return
(struct Point) point1 loadstore mem[3]
@ -283,7 +273,7 @@ mem[3] [ point1 ]
FINAL ASSEMBLER
Score: 64
Score: 58
// File Comments
// Minimal struct with C-Standard behavior - global main-mem struct should be initialized in data, not code
@ -293,47 +283,45 @@ Score: 64
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 3
.const OFFSET_STRUCT_POINT_INITIALS = 1
// @begin
__bbegin:
// point1 = { 2, { 'j', 'g' } }
// [0] *((byte*)&(struct Point) point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta point1
// [1] *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) ← memcpy(*((const byte*) $0), (number) 2) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3
tay
// [0] *(&(struct Point) point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta point1+OFFSET_STRUCT_POINT_INITIALS-1,y
sta point1-1,y
dey
bne !-
// [2] phi from @begin to @1 [phi:@begin->@1]
// [1] phi from @begin to @1 [phi:@begin->@1]
// @1
// [3] call main
// [2] call main
jsr main
rts
// [4] phi from @1 to @end [phi:@1->@end]
// [3] phi from @1 to @end [phi:@1->@end]
// @end
// main
main: {
// SCREEN[0] = point1.x
// [5] *((const byte*) SCREEN) ← *((byte*)&(struct Point) point1) -- _deref_pbuc1=_deref_pbuc2
// [4] *((const byte*) SCREEN) ← *((byte*)&(struct Point) point1) -- _deref_pbuc1=_deref_pbuc2
lda point1
sta SCREEN
// SCREEN[1] = point1.initials[0]
// [6] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2
// [5] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) -- _deref_pbuc1=_deref_pbuc2
lda point1+OFFSET_STRUCT_POINT_INITIALS
sta SCREEN+1
// SCREEN[2] = point1.initials[1]
// [7] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2
// [6] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) -- _deref_pbuc1=_deref_pbuc2
lda point1+OFFSET_STRUCT_POINT_INITIALS+1
sta SCREEN+2
// main::@return
// }
// [8] return
// [7] return
rts
}
// File Data
__0: .byte 'j', 'g'
point1: .byte 0
__0: .byte 2, 'j', 'g'
point1: .fill SIZEOF_STRUCT_POINT, 0

View File

@ -1,4 +1,4 @@
(const byte*) $0[(number) 2] = { (byte) 'j', (byte) 'g' }
(const struct Point) $0 = { x: (byte) 2, initials: { (byte) 'j', (byte) 'g' } }
(label) @1
(label) @begin
(label) @end
@ -6,6 +6,7 @@
(const byte*) Point::initials[(number) 2] = { fill( 2, 0) }
(byte) Point::x
(const byte*) SCREEN = (byte*) 1024
(const byte) SIZEOF_STRUCT_POINT = (byte) 3
(void()) main()
(label) main::@return
(struct Point) point1 loadstore mem[3]

View File

@ -10,7 +10,7 @@
(void()) main()
main: scope:[main] from @1
[4] *((const byte*) main::point1_initials) ← memcpy(*((const byte*) $0), (number) 3)
[4] *((const byte*) main::point1_initials) ← memcpy(*(&(const byte*) $0), byte, (number) 3)
[5] *((const byte*) SCREEN) ← (const byte) main::point1_x
[6] *((const byte*) SCREEN+(byte) 1) ← *((const byte*) main::point1_initials)
[7] *((const byte*) SCREEN+(byte) 2) ← *((const byte*) main::point1_initials+(byte) 1)

View File

@ -5,7 +5,7 @@ Created struct value member variable (byte) main::point1_x
Created struct value member variable (const byte*) main::point1_initials
Converted struct value to member variables (struct Point) main::point1
Adding struct value member variable copy (byte) main::point1_x ← (byte) 2
Adding struct value member variable copy *((const byte*) main::point1_initials) ← memcpy(*((const byte*) $0), (number) 3)
Adding struct value member variable copy *((const byte*) main::point1_initials) ← memcpy(*(&(const byte*) $0), byte, (number) 3)
Replacing struct member reference (struct Point) main::point1.x with member unwinding reference (byte) main::point1_x
Replacing struct member reference (struct Point) main::point1.initials with member unwinding reference (const byte*) main::point1_initials
Replacing struct member reference (struct Point) main::point1.initials with member unwinding reference (const byte*) main::point1_initials
@ -17,7 +17,7 @@ CONTROL FLOW GRAPH SSA
(void()) main()
main: scope:[main] from @1
*((const byte*) main::point1_initials) ← memcpy(*((const byte*) $0), (number) 3)
*((const byte*) main::point1_initials) ← memcpy(*(&(const byte*) $0), byte, (number) 3)
*((const byte*) SCREEN + (number) 0) ← (const byte) main::point1_x
*((const byte*) SCREEN + (number) 1) ← *((const byte*) main::point1_initials + (number) 0)
*((const byte*) SCREEN + (number) 2) ← *((const byte*) main::point1_initials + (number) 1)
@ -99,7 +99,7 @@ FINAL CONTROL FLOW GRAPH
(void()) main()
main: scope:[main] from @1
[4] *((const byte*) main::point1_initials) ← memcpy(*((const byte*) $0), (number) 3)
[4] *((const byte*) main::point1_initials) ← memcpy(*(&(const byte*) $0), byte, (number) 3)
[5] *((const byte*) SCREEN) ← (const byte) main::point1_x
[6] *((const byte*) SCREEN+(byte) 1) ← *((const byte*) main::point1_initials)
[7] *((const byte*) SCREEN+(byte) 2) ← *((const byte*) main::point1_initials+(byte) 1)
@ -143,7 +143,7 @@ __bend:
// main
main: {
.const point1_x = 2
// [4] *((const byte*) main::point1_initials) ← memcpy(*((const byte*) $0), (number) 3) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3
// [4] *((const byte*) main::point1_initials) ← memcpy(*(&(const byte*) $0), byte, (number) 3) -- _deref_pbuc1=_deref_pptc2_memcpy_vbuc3
ldy #3
!:
lda __0-1,y
@ -171,7 +171,7 @@ main: {
.byte 0
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] *((const byte*) main::point1_initials) ← memcpy(*((const byte*) $0), (number) 3) [ ] ( main:2 [ ] ) always clobbers reg byte a reg byte y
Statement [4] *((const byte*) main::point1_initials) ← memcpy(*(&(const byte*) $0), byte, (number) 3) [ ] ( main:2 [ ] ) always clobbers reg byte a reg byte y
Statement [5] *((const byte*) SCREEN) ← (const byte) main::point1_x [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [6] *((const byte*) SCREEN+(byte) 1) ← *((const byte*) main::point1_initials) [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [7] *((const byte*) SCREEN+(byte) 2) ← *((const byte*) main::point1_initials+(byte) 1) [ ] ( main:2 [ ] ) always clobbers reg byte a
@ -211,7 +211,7 @@ __bend:
// main
main: {
.const point1_x = 2
// [4] *((const byte*) main::point1_initials) ← memcpy(*((const byte*) $0), (number) 3) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3
// [4] *((const byte*) main::point1_initials) ← memcpy(*(&(const byte*) $0), byte, (number) 3) -- _deref_pbuc1=_deref_pptc2_memcpy_vbuc3
ldy #3
!:
lda __0-1,y
@ -293,7 +293,7 @@ Score: 44
main: {
.const point1_x = 2
// point1 = { 2, "jg" }
// [4] *((const byte*) main::point1_initials) ← memcpy(*((const byte*) $0), (number) 3) -- _deref_pbuc1=_deref_pbuc2_memcpy_vbuc3
// [4] *((const byte*) main::point1_initials) ← memcpy(*(&(const byte*) $0), byte, (number) 3) -- _deref_pbuc1=_deref_pptc2_memcpy_vbuc3
ldy #3
!:
lda __0-1,y

View File

@ -0,0 +1,32 @@
// Minimal struct with C-Standard behavior - member is array, copy assignment
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1
main: {
.label point1 = 2
.label point2 = 4
ldy #SIZEOF_STRUCT_POINT
lda #0
!:
dey
sta point1,y
bne !-
lda #2
sta.z point1
lda #3
sta point1+OFFSET_STRUCT_POINT_Y
ldy #SIZEOF_STRUCT_POINT
!:
lda point1-1,y
sta point2-1,y
dey
bne !-
lda.z point2
sta SCREEN
lda point2+OFFSET_STRUCT_POINT_Y
sta SCREEN+1
rts
}

View File

@ -0,0 +1,22 @@
@begin: scope:[] from
[0] phi()
to:@1
@1: scope:[] from @begin
[1] phi()
[2] call main
to:@end
@end: scope:[] from @1
[3] phi()
(void()) main()
main: scope:[main] from @1
[4] *(&(struct Point) main::point1) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT)
[5] *((byte*)&(struct Point) main::point1) ← (byte) 2
[6] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
[7] *(&(struct Point) main::point2) ← memcpy(*(&(struct Point) main::point1), struct Point, (const byte) SIZEOF_STRUCT_POINT)
[8] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2)
[9] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y)
to:main::@return
main::@return: scope:[main] from main
[10] return
to:@return

373
src/test/ref/struct-32.log Normal file
View File

@ -0,0 +1,373 @@
Adding struct value member variable copy *(&(struct Point) main::point1) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT)
Adding struct value member variable copy *(&(struct Point) main::point2) ← memcpy(*(&(struct Point) main::point1), struct Point, (const byte) SIZEOF_STRUCT_POINT)
Replacing struct member reference (struct Point) main::point1.x with member unwinding reference *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X)
Replacing struct member reference (struct Point) main::point1.y with member unwinding reference *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y)
Replacing struct member reference (struct Point) main::point2.x with member unwinding reference *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X)
Replacing struct member reference (struct Point) main::point2.y with member unwinding reference *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y)
CONTROL FLOW GRAPH SSA
@begin: scope:[] from
to:@1
(void()) main()
main: scope:[main] from @1
*(&(struct Point) main::point1) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT)
*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (number) 2
*((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (number) 3
*(&(struct Point) main::point2) ← memcpy(*(&(struct Point) main::point1), struct Point, (const byte) SIZEOF_STRUCT_POINT)
*((const byte*) SCREEN + (number) 0) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X)
*((const byte*) SCREEN + (number) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y)
to:main::@return
main::@return: scope:[main] from main
return
to:@return
@1: scope:[] from @begin
call main
to:@2
@2: scope:[] from @1
to:@end
@end: scope:[] from @2
SYMBOL TABLE SSA
(label) @1
(label) @2
(label) @begin
(label) @end
(const byte) OFFSET_STRUCT_POINT_X = (byte) 0
(const byte) OFFSET_STRUCT_POINT_Y = (byte) 1
(byte) Point::x
(byte) Point::y
(const byte*) SCREEN = (byte*)(number) $400
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(void()) main()
(label) main::@return
(struct Point) main::point1 loadstore
(struct Point) main::point2 loadstore
Adding number conversion cast (unumber) 2 in *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (number) 2
Adding number conversion cast (unumber) 3 in *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (number) 3
Adding number conversion cast (unumber) 0 in *((const byte*) SCREEN + (number) 0) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X)
Adding number conversion cast (unumber) 1 in *((const byte*) SCREEN + (number) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y)
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (unumber)(number) 2
Inlining cast *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (unumber)(number) 3
Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (byte*) 1024
Simplifying constant integer cast 2
Simplifying constant integer cast 3
Simplifying constant integer cast 0
Simplifying constant integer cast 1
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) 2
Finalized unsigned number type (byte) 3
Finalized unsigned number type (byte) 0
Finalized unsigned number type (byte) 1
Successful SSA optimization PassNFinalizeNumberTypeConversions
Simplifying expression containing zero (byte*)&main::point1 in [1] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
Simplifying expression containing zero (byte*)&main::point2 in [4] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero SCREEN in [4] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) main::point2)
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant (const byte) OFFSET_STRUCT_POINT_X
Successful SSA optimization PassNEliminateUnusedVars
Consolidated array index constant in *(SCREEN+1)
Successful SSA optimization Pass2ConstantAdditionElimination
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1
Adding NOP phi() at start of @2
Adding NOP phi() at start of @end
CALL GRAPH
Calls in [] to main:2
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
Culled Empty Block (label) @2
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1
Adding NOP phi() at start of @end
FINAL CONTROL FLOW GRAPH
@begin: scope:[] from
[0] phi()
to:@1
@1: scope:[] from @begin
[1] phi()
[2] call main
to:@end
@end: scope:[] from @1
[3] phi()
(void()) main()
main: scope:[main] from @1
[4] *(&(struct Point) main::point1) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT)
[5] *((byte*)&(struct Point) main::point1) ← (byte) 2
[6] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
[7] *(&(struct Point) main::point2) ← memcpy(*(&(struct Point) main::point1), struct Point, (const byte) SIZEOF_STRUCT_POINT)
[8] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2)
[9] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y)
to:main::@return
main::@return: scope:[main] from main
[10] return
to:@return
VARIABLE REGISTER WEIGHTS
(byte) Point::x
(byte) Point::y
(void()) main()
(struct Point) main::point1 loadstore
(struct Point) main::point2 loadstore
Initial phi equivalence classes
Added variable main::point1 to live range equivalence class [ main::point1 ]
Added variable main::point2 to live range equivalence class [ main::point2 ]
Complete equivalence classes
[ main::point1 ]
[ main::point2 ]
Allocated zp[2]:2 [ main::point1 ]
Allocated zp[2]:4 [ main::point2 ]
INITIAL ASM
Target platform is c64basic / MOS6502X
// File Comments
// Minimal struct with C-Standard behavior - member is array, copy assignment
// Upstart
.pc = $801 "Basic"
:BasicUpstart(__bbegin)
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1
// @begin
__bbegin:
// [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin:
jmp __b1
// @1
__b1:
// [2] call main
jsr main
// [3] phi from @1 to @end [phi:@1->@end]
__bend_from___b1:
jmp __bend
// @end
__bend:
// main
main: {
.label point1 = 2
.label point2 = 4
// [4] *(&(struct Point) main::point1) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_memset_vbuc2
ldy #SIZEOF_STRUCT_POINT
lda #0
!:
dey
sta point1,y
bne !-
// [5] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z point1
// [6] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta point1+OFFSET_STRUCT_POINT_Y
// [7] *(&(struct Point) main::point2) ← memcpy(*(&(struct Point) main::point1), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda point1-1,y
sta point2-1,y
dey
bne !-
// [8] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2) -- _deref_pbuc1=_deref_pbuc2
lda.z point2
sta SCREEN
// [9] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda point2+OFFSET_STRUCT_POINT_Y
sta SCREEN+1
jmp __breturn
// main::@return
__breturn:
// [10] return
rts
}
// File Data
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] *(&(struct Point) main::point1) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT) [ main::point1 main::point2 ] ( main:2 [ main::point1 main::point2 ] ) always clobbers reg byte a reg byte y
Statement [5] *((byte*)&(struct Point) main::point1) ← (byte) 2 [ main::point1 main::point2 ] ( main:2 [ main::point1 main::point2 ] ) always clobbers reg byte a
Statement [6] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 [ main::point1 main::point2 ] ( main:2 [ main::point1 main::point2 ] ) always clobbers reg byte a
Statement [7] *(&(struct Point) main::point2) ← memcpy(*(&(struct Point) main::point1), struct Point, (const byte) SIZEOF_STRUCT_POINT) [ main::point2 ] ( main:2 [ main::point2 ] ) always clobbers reg byte a reg byte y
Statement [8] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2) [ main::point2 ] ( main:2 [ main::point2 ] ) always clobbers reg byte a
Statement [9] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) [ ] ( main:2 [ ] ) always clobbers reg byte a
Potential registers zp[2]:2 [ main::point1 ] : zp[2]:2 ,
Potential registers zp[2]:4 [ main::point2 ] : zp[2]:4 ,
REGISTER UPLIFT SCOPES
Uplift Scope [Point]
Uplift Scope [main] 0: zp[2]:2 [ main::point1 ] 0: zp[2]:4 [ main::point2 ]
Uplift Scope []
Uplifting [Point] best 76 combination
Uplifting [main] best 76 combination zp[2]:2 [ main::point1 ] zp[2]:4 [ main::point2 ]
Uplifting [] best 76 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Minimal struct with C-Standard behavior - member is array, copy assignment
// Upstart
.pc = $801 "Basic"
:BasicUpstart(__bbegin)
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1
// @begin
__bbegin:
// [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin:
jmp __b1
// @1
__b1:
// [2] call main
jsr main
// [3] phi from @1 to @end [phi:@1->@end]
__bend_from___b1:
jmp __bend
// @end
__bend:
// main
main: {
.label point1 = 2
.label point2 = 4
// [4] *(&(struct Point) main::point1) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_memset_vbuc2
ldy #SIZEOF_STRUCT_POINT
lda #0
!:
dey
sta point1,y
bne !-
// [5] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z point1
// [6] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta point1+OFFSET_STRUCT_POINT_Y
// [7] *(&(struct Point) main::point2) ← memcpy(*(&(struct Point) main::point1), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda point1-1,y
sta point2-1,y
dey
bne !-
// [8] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2) -- _deref_pbuc1=_deref_pbuc2
lda.z point2
sta SCREEN
// [9] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda point2+OFFSET_STRUCT_POINT_Y
sta SCREEN+1
jmp __breturn
// main::@return
__breturn:
// [10] return
rts
}
// File Data
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __bend
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Replacing label __bbegin with __b1
Removing instruction __bbegin:
Removing instruction __b1_from___bbegin:
Removing instruction __bend_from___b1:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __bend:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
Updating BasicUpstart to call main directly
Removing instruction jsr main
Succesful ASM optimization Pass5SkipBegin
Removing instruction __b1:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
(label) @1
(label) @begin
(label) @end
(const byte) OFFSET_STRUCT_POINT_Y = (byte) 1
(byte) Point::x
(byte) Point::y
(const byte*) SCREEN = (byte*) 1024
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(void()) main()
(label) main::@return
(struct Point) main::point1 loadstore zp[2]:2
(struct Point) main::point2 loadstore zp[2]:4
zp[2]:2 [ main::point1 ]
zp[2]:4 [ main::point2 ]
FINAL ASSEMBLER
Score: 61
// File Comments
// Minimal struct with C-Standard behavior - member is array, copy assignment
// Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1
// @begin
// [1] phi from @begin to @1 [phi:@begin->@1]
// @1
// [2] call main
// [3] phi from @1 to @end [phi:@1->@end]
// @end
// main
main: {
.label point1 = 2
.label point2 = 4
// point1
// [4] *(&(struct Point) main::point1) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_memset_vbuc2
ldy #SIZEOF_STRUCT_POINT
lda #0
!:
dey
sta point1,y
bne !-
// point1.x = 2
// [5] *((byte*)&(struct Point) main::point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta.z point1
// point1.y = 3
// [6] *((byte*)&(struct Point) main::point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta point1+OFFSET_STRUCT_POINT_Y
// point2 = point1
// [7] *(&(struct Point) main::point2) ← memcpy(*(&(struct Point) main::point1), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda point1-1,y
sta point2-1,y
dey
bne !-
// SCREEN[0] = point2.x
// [8] *((const byte*) SCREEN) ← *((byte*)&(struct Point) main::point2) -- _deref_pbuc1=_deref_pbuc2
lda.z point2
sta SCREEN
// SCREEN[1] = point2.y
// [9] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) main::point2+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda point2+OFFSET_STRUCT_POINT_Y
sta SCREEN+1
// main::@return
// }
// [10] return
rts
}
// File Data

Some files were not shown because too many files have changed in this diff Show More