1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-08-09 04:25:12 +00:00

Global struct values are not per default load/store, main-memory.

This commit is contained in:
jespergravgaard
2020-01-12 22:53:57 +01:00
parent ffdc590b90
commit a32f783b74
32 changed files with 1248 additions and 1016 deletions

View File

@@ -222,6 +222,10 @@ public class VariableBuilder {
* @return true if the variable is single-static-assignment * @return true if the variable is single-static-assignment
*/ */
public boolean isSingleStaticAssignment() { public boolean isSingleStaticAssignment() {
if(hasDirective(Directive.FormSsa.class))
// the __ssa directive forces single-static-assignment
//TODO: FAIL if combined with __ma, __address() or volatile!
return true;
if(hasDirective(Directive.FormMa.class)) if(hasDirective(Directive.FormMa.class))
// the __ma directive forces multiple-assignment // the __ma directive forces multiple-assignment
return false; return false;
@@ -231,6 +235,9 @@ public class VariableBuilder {
else if(isVolatile()) else if(isVolatile())
// volatile variables must be load/store // volatile variables must be load/store
return false; return false;
else if(isTypeStruct() && isScopeGlobal())
// global struct variables must be load/store
return false;
else else
// All others are single-static-assignment (by default) // All others are single-static-assignment (by default)
return true; return true;
@@ -262,10 +269,6 @@ public class VariableBuilder {
public Variable.MemoryArea getMemoryArea() { public Variable.MemoryArea getMemoryArea() {
if(isConstant()) if(isConstant())
return Variable.MemoryArea.MAIN_MEMORY; return Variable.MemoryArea.MAIN_MEMORY;
else if(!isConstant() && isOptimize())
return Variable.MemoryArea.ZEROPAGE_MEMORY;
else if(isArray())
return Variable.MemoryArea.MAIN_MEMORY;
else if(hasDirective(Directive.MemZp.class)) else if(hasDirective(Directive.MemZp.class))
return Variable.MemoryArea.ZEROPAGE_MEMORY; return Variable.MemoryArea.ZEROPAGE_MEMORY;
else if(hasDirective(Directive.MemMain.class)) else if(hasDirective(Directive.MemMain.class))
@@ -273,6 +276,12 @@ public class VariableBuilder {
Directive.Address addressDirective = findDirective(Directive.Address.class); Directive.Address addressDirective = findDirective(Directive.Address.class);
if(addressDirective != null) if(addressDirective != null)
return (addressDirective.address < 0x100) ? Variable.MemoryArea.ZEROPAGE_MEMORY : Variable.MemoryArea.MAIN_MEMORY; return (addressDirective.address < 0x100) ? Variable.MemoryArea.ZEROPAGE_MEMORY : Variable.MemoryArea.MAIN_MEMORY;
else if(!isConstant() && isOptimize())
return Variable.MemoryArea.ZEROPAGE_MEMORY;
else if(isArray())
return Variable.MemoryArea.MAIN_MEMORY;
else if(isTypeStruct() && isScopeGlobal())
return Variable.MemoryArea.MAIN_MEMORY;
else else
return Variable.MemoryArea.ZEROPAGE_MEMORY; return Variable.MemoryArea.ZEROPAGE_MEMORY;
} }

View File

@@ -1127,9 +1127,14 @@ public class TestPrograms {
assertError("struct-err-0", "Unknown struct type"); assertError("struct-err-0", "Unknown struct type");
} }
@Test
public void testStruct34() throws IOException, URISyntaxException {
compileAndCompare("struct-34");
}
@Test @Test
public void testStruct33() throws IOException, URISyntaxException { public void testStruct33() throws IOException, URISyntaxException {
compileAndCompare("struct-33", log()); compileAndCompare("struct-33");
} }
@Test @Test

View File

@@ -1,5 +1,4 @@
// Example of a struct containing an array // Example of a struct containing an array
// Works because the struct is only handled as a value
struct Person { struct Person {
char id; char id;

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

@@ -0,0 +1,17 @@
// Struct - forced __ssa
struct Point {
char x;
char y;
};
__mem __ssa struct Point point;
const char* SCREEN = 0x0400;
void main() {
point.x = 2;
point.y = 3;
SCREEN[0] = point.x;
SCREEN[1] = point.y;
}

View File

@@ -1,19 +1,13 @@
// Test parsing a negated struct reference - which causes problems with the ASMREL labels !a++ // Test parsing a negated struct reference - which causes problems with the ASMREL labels !a++
// https://gitlab.com/camelot/kickc/issues/266 // https://gitlab.com/camelot/kickc/issues/266
.pc = $801 "Basic" .pc = $801 "Basic"
:BasicUpstart(__bbegin) :BasicUpstart(main)
.pc = $80d "Program" .pc = $80d "Program"
.label aa_b = 2
__bbegin:
lda #1
sta.z aa_b
jsr main
rts
main: { main: {
.label SCREEN = $400 .label SCREEN = $400
.label a = aa_b .label a = aa
lda #0 lda #0
cmp.z a cmp a
bne !a+ bne !a+
lda #'a' lda #'a'
sta SCREEN sta SCREEN
@@ -22,3 +16,4 @@ main: {
!a: !a:
rts rts
} }
aa: .byte 1

View File

@@ -1,5 +1,5 @@
@begin: scope:[] from @begin: scope:[] from
[0] (byte) aa_b#0 ← (byte) 1 [0] phi()
to:@1 to:@1
@1: scope:[] from @begin @1: scope:[] from @begin
[1] phi() [1] phi()

View File

@@ -1,15 +1,10 @@
Setting inferred volatile on symbol affected by address-of (struct A*) main::a ← &(struct A) aa Setting inferred volatile on symbol affected by address-of (struct A*) main::a ← &(struct A) aa
Created struct value member variable (byte) aa_b
Converted struct value to member variables (struct A) aa
Adding struct value member variable copy (byte) aa_b ← (byte) 1
Rewriting struct pointer member access *((struct A*) main::a).b Rewriting struct pointer member access *((struct A*) main::a).b
Warning! Adding boolean cast to non-boolean sub-expression *((byte*~) main::$2) Warning! Adding boolean cast to non-boolean sub-expression *((byte*~) main::$2)
Identified constant variable (struct A*) main::a Identified constant variable (struct A*) main::a
CONTROL FLOW GRAPH SSA CONTROL FLOW GRAPH SSA
@begin: scope:[] from @begin: scope:[] from
(byte) aa_b#0 ← (byte) 1
(struct A) aa#0 ← struct-unwound {(byte) aa_b#0}
to:@1 to:@1
(void()) main() (void()) main()
@@ -43,10 +38,7 @@ SYMBOL TABLE SSA
(label) @end (label) @end
(byte) A::b (byte) A::b
(const byte) OFFSET_STRUCT_A_B = (byte) 0 (const byte) OFFSET_STRUCT_A_B = (byte) 0
(struct A) aa (struct A) aa loadstore = { b: (byte) 1 }
(struct A) aa#0
(byte) aa_b
(byte) aa_b#0
(void()) main() (void()) main()
(bool~) main::$0 (bool~) main::$0
(bool~) main::$1 (bool~) main::$1
@@ -65,24 +57,22 @@ Simplifying constant integer cast 0
Successful SSA optimization PassNCastSimplification Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) 0 Finalized unsigned number type (byte) 0
Successful SSA optimization PassNFinalizeNumberTypeConversions Successful SSA optimization PassNFinalizeNumberTypeConversions
Inversing boolean not [4] (bool~) main::$0 ← (byte) 0 == *((byte*~) main::$2) from [3] (bool~) main::$3 ← (byte) 0 != *((byte*~) main::$2) Inversing boolean not [2] (bool~) main::$0 ← (byte) 0 == *((byte*~) main::$2) from [1] (bool~) main::$3 ← (byte) 0 != *((byte*~) main::$2)
Inversing boolean not [5] (bool~) main::$1 ← (byte) 0 != *((byte*~) main::$2) from [4] (bool~) main::$0 ← (byte) 0 == *((byte*~) main::$2) Inversing boolean not [3] (bool~) main::$1 ← (byte) 0 != *((byte*~) main::$2) from [2] (bool~) main::$0 ← (byte) 0 == *((byte*~) main::$2)
Successful SSA optimization Pass2UnaryNotSimplification Successful SSA optimization Pass2UnaryNotSimplification
Simple Condition (bool~) main::$1 [6] if((byte) 0!=*((byte*~) main::$2)) goto main::@1 Simple Condition (bool~) main::$1 [4] if((byte) 0!=*((byte*~) main::$2)) goto main::@1
Successful SSA optimization Pass2ConditionalJumpSimplification Successful SSA optimization Pass2ConditionalJumpSimplification
Rewriting struct address-of to first member &(struct A) aa Constant right-side identified [0] (byte*~) main::$2 ← (byte*)(const struct A*) main::a + (const byte) OFFSET_STRUCT_A_B
Successful SSA optimization PassNStructAddressOfRewriting
Constant right-side identified [2] (byte*~) main::$2 ← (byte*)(const struct A*) main::a + (const byte) OFFSET_STRUCT_A_B
Successful SSA optimization Pass2ConstantRValueConsolidation Successful SSA optimization Pass2ConstantRValueConsolidation
Constant (const byte*) main::$2 = (byte*)main::a+OFFSET_STRUCT_A_B Constant (const byte*) main::$2 = (byte*)main::a+OFFSET_STRUCT_A_B
Successful SSA optimization Pass2ConstantIdentification Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero (byte*)main::a in Simplifying expression containing zero (byte*)main::a in
Successful SSA optimization PassNSimplifyExpressionWithZero Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused variable (struct A) aa#0 and assignment [1] (struct A) aa#0 ← struct-unwound {(byte) aa_b#0}
Eliminating unused constant (const byte) OFFSET_STRUCT_A_B Eliminating unused constant (const byte) OFFSET_STRUCT_A_B
Successful SSA optimization PassNEliminateUnusedVars Successful SSA optimization PassNEliminateUnusedVars
Constant inlined main::$2 = (byte*)(const struct A*) main::a Constant inlined main::$2 = (byte*)(const struct A*) main::a
Successful SSA optimization Pass2ConstantInlining Successful SSA optimization Pass2ConstantInlining
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1 Adding NOP phi() at start of @1
Adding NOP phi() at start of @2 Adding NOP phi() at start of @2
Adding NOP phi() at start of @end Adding NOP phi() at start of @end
@@ -92,12 +82,13 @@ Calls in [] to main:2
Created 0 initial phi equivalence classes Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes Coalesced down to 0 phi equivalence classes
Culled Empty Block (label) @2 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 @1
Adding NOP phi() at start of @end Adding NOP phi() at start of @end
FINAL CONTROL FLOW GRAPH FINAL CONTROL FLOW GRAPH
@begin: scope:[] from @begin: scope:[] from
[0] (byte) aa_b#0 ← (byte) 1 [0] phi()
to:@1 to:@1
@1: scope:[] from @begin @1: scope:[] from @begin
[1] phi() [1] phi()
@@ -123,15 +114,14 @@ main::@return: scope:[main] from main::@1
VARIABLE REGISTER WEIGHTS VARIABLE REGISTER WEIGHTS
(byte) A::b (byte) A::b
(struct A) aa (struct A) aa loadstore = { b: (byte) 1 }
(byte) aa_b
(byte) aa_b#0 20.0
(void()) main() (void()) main()
Initial phi equivalence classes Initial phi equivalence classes
Added variable aa to live range equivalence class [ aa ]
Complete equivalence classes Complete equivalence classes
[ aa_b#0 ] [ aa ]
Allocated zp[1]:2 [ aa_b#0 ] Allocated mem[1] [ aa ]
INITIAL ASM INITIAL ASM
Target platform is c64basic / MOS6502X Target platform is c64basic / MOS6502X
@@ -143,12 +133,8 @@ Target platform is c64basic / MOS6502X
:BasicUpstart(__bbegin) :BasicUpstart(__bbegin)
.pc = $80d "Program" .pc = $80d "Program"
// Global Constants & labels // Global Constants & labels
.label aa_b = 2
// @begin // @begin
__bbegin: __bbegin:
// [0] (byte) aa_b#0 ← (byte) 1 -- vbuz1=vbuc1
lda #1
sta.z aa_b
// [1] phi from @begin to @1 [phi:@begin->@1] // [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin: __b1_from___bbegin:
jmp __b1 jmp __b1
@@ -164,10 +150,10 @@ __bend:
// main // main
main: { main: {
.label SCREEN = $400 .label SCREEN = $400
.label a = aa_b .label a = aa
// [4] if((byte) 0!=*((byte*)(const struct A*) main::a)) goto main::@1 -- vbuc1_neq__deref_pbuc2_then_la1 // [4] if((byte) 0!=*((byte*)(const struct A*) main::a)) goto main::@1 -- vbuc1_neq__deref_pbuc2_then_la1
lda #0 lda #0
cmp.z a cmp a
bne __b1 bne __b1
jmp __b2 jmp __b2
// main::@2 // main::@2
@@ -189,23 +175,23 @@ main: {
rts rts
} }
// File Data // File Data
aa: .byte 1
REGISTER UPLIFT POTENTIAL REGISTERS REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] (byte) aa_b#0 ← (byte) 1 [ ] ( [ ] ) always clobbers reg byte a
Statement [4] if((byte) 0!=*((byte*)(const struct A*) main::a)) goto main::@1 [ ] ( main:2 [ ] ) always clobbers reg byte a Statement [4] if((byte) 0!=*((byte*)(const struct A*) main::a)) goto main::@1 [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [5] *((const byte*) main::SCREEN) ← (byte) 'a' [ ] ( main:2 [ ] ) always clobbers reg byte a Statement [5] *((const byte*) main::SCREEN) ← (byte) 'a' [ ] ( main:2 [ ] ) always clobbers reg byte a
Potential registers zp[1]:2 [ aa_b#0 ] : zp[1]:2 , Potential registers mem[1] [ aa ] : mem[1] ,
REGISTER UPLIFT SCOPES REGISTER UPLIFT SCOPES
Uplift Scope [] 20: zp[1]:2 [ aa_b#0 ]
Uplift Scope [A] Uplift Scope [A]
Uplift Scope [main] Uplift Scope [main]
Uplift Scope [] 0: mem[1] [ aa ]
Uplifting [] best 48 combination zp[1]:2 [ aa_b#0 ] Uplifting [A] best 44 combination
Uplifting [A] best 48 combination Uplifting [main] best 44 combination
Uplifting [main] best 48 combination Uplifting [] best 44 combination mem[1] [ aa ]
Attempting to uplift remaining variables inzp[1]:2 [ aa_b#0 ] Attempting to uplift remaining variables inmem[1] [ aa ]
Uplifting [] best 48 combination zp[1]:2 [ aa_b#0 ] Uplifting [] best 44 combination mem[1] [ aa ]
ASSEMBLER BEFORE OPTIMIZATION ASSEMBLER BEFORE OPTIMIZATION
// File Comments // File Comments
@@ -216,12 +202,8 @@ ASSEMBLER BEFORE OPTIMIZATION
:BasicUpstart(__bbegin) :BasicUpstart(__bbegin)
.pc = $80d "Program" .pc = $80d "Program"
// Global Constants & labels // Global Constants & labels
.label aa_b = 2
// @begin // @begin
__bbegin: __bbegin:
// [0] (byte) aa_b#0 ← (byte) 1 -- vbuz1=vbuc1
lda #1
sta.z aa_b
// [1] phi from @begin to @1 [phi:@begin->@1] // [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin: __b1_from___bbegin:
jmp __b1 jmp __b1
@@ -237,10 +219,10 @@ __bend:
// main // main
main: { main: {
.label SCREEN = $400 .label SCREEN = $400
.label a = aa_b .label a = aa
// [4] if((byte) 0!=*((byte*)(const struct A*) main::a)) goto main::@1 -- vbuc1_neq__deref_pbuc2_then_la1 // [4] if((byte) 0!=*((byte*)(const struct A*) main::a)) goto main::@1 -- vbuc1_neq__deref_pbuc2_then_la1
lda #0 lda #0
cmp.z a cmp a
bne __b1 bne __b1
jmp __b2 jmp __b2
// main::@2 // main::@2
@@ -262,6 +244,7 @@ main: {
rts rts
} }
// File Data // File Data
aa: .byte 1
ASSEMBLER OPTIMIZATIONS ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1 Removing instruction jmp __b1
@@ -270,18 +253,21 @@ Removing instruction jmp __b2
Removing instruction jmp __b1 Removing instruction jmp __b1
Removing instruction jmp __breturn Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination Succesful ASM optimization Pass5NextJumpElimination
Replacing label __bbegin with __b1
Removing instruction __bbegin:
Removing instruction __b1_from___bbegin: Removing instruction __b1_from___bbegin:
Removing instruction __bend_from___b1: Removing instruction __bend_from___b1:
Succesful ASM optimization Pass5RedundantLabelElimination Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __b1:
Removing instruction __bend: Removing instruction __bend:
Removing instruction __b2: Removing instruction __b2:
Removing instruction __breturn: Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination Succesful ASM optimization Pass5UnusedLabelElimination
Updating BasicUpstart to call main directly
Removing instruction jsr main
Succesful ASM optimization Pass5SkipBegin
Skipping double jump to !a+ in bne __b1 Skipping double jump to !a+ in bne __b1
Succesful ASM optimization Pass5DoubleJumpElimination Succesful ASM optimization Pass5DoubleJumpElimination
Adding RTS to root block Removing instruction __b1:
Succesful ASM optimization Pass5AddMainRts
Removing instruction __b1: Removing instruction __b1:
Succesful ASM optimization Pass5UnusedLabelElimination Succesful ASM optimization Pass5UnusedLabelElimination
@@ -290,52 +276,42 @@ FINAL SYMBOL TABLE
(label) @begin (label) @begin
(label) @end (label) @end
(byte) A::b (byte) A::b
(struct A) aa (struct A) aa loadstore mem[1] = { b: (byte) 1 }
(byte) aa_b
(byte) aa_b#0 aa_b zp[1]:2 20.0
(void()) main() (void()) main()
(label) main::@1 (label) main::@1
(label) main::@2 (label) main::@2
(label) main::@return (label) main::@return
(const byte*) main::SCREEN = (byte*) 1024 (const byte*) main::SCREEN = (byte*) 1024
(const struct A*) main::a = (struct A*)&(byte) aa_b#0 (const struct A*) main::a = &(struct A) aa
zp[1]:2 [ aa_b#0 ] mem[1] [ aa ]
FINAL ASSEMBLER FINAL ASSEMBLER
Score: 39 Score: 23
// File Comments // File Comments
// Test parsing a negated struct reference - which causes problems with the ASMREL labels !a++ // Test parsing a negated struct reference - which causes problems with the ASMREL labels !a++
// https://gitlab.com/camelot/kickc/issues/266 // https://gitlab.com/camelot/kickc/issues/266
// Upstart // Upstart
.pc = $801 "Basic" .pc = $801 "Basic"
:BasicUpstart(__bbegin) :BasicUpstart(main)
.pc = $80d "Program" .pc = $80d "Program"
// Global Constants & labels // Global Constants & labels
.label aa_b = 2
// @begin // @begin
__bbegin:
// aa = { 1 }
// [0] (byte) aa_b#0 ← (byte) 1 -- vbuz1=vbuc1
lda #1
sta.z aa_b
// [1] phi from @begin to @1 [phi:@begin->@1] // [1] phi from @begin to @1 [phi:@begin->@1]
// @1 // @1
// [2] call main // [2] call main
jsr main
rts
// [3] phi from @1 to @end [phi:@1->@end] // [3] phi from @1 to @end [phi:@1->@end]
// @end // @end
// main // main
main: { main: {
.label SCREEN = $400 .label SCREEN = $400
.label a = aa_b .label a = aa
// if(!a->b) // if(!a->b)
// [4] if((byte) 0!=*((byte*)(const struct A*) main::a)) goto main::@1 -- vbuc1_neq__deref_pbuc2_then_la1 // [4] if((byte) 0!=*((byte*)(const struct A*) main::a)) goto main::@1 -- vbuc1_neq__deref_pbuc2_then_la1
lda #0 lda #0
cmp.z a cmp a
bne !a+ bne !a+
// main::@2 // main::@2
// *SCREEN = 'a' // *SCREEN = 'a'
@@ -354,4 +330,5 @@ main: {
rts rts
} }
// File Data // File Data
aa: .byte 1

View File

@@ -2,14 +2,12 @@
(label) @begin (label) @begin
(label) @end (label) @end
(byte) A::b (byte) A::b
(struct A) aa (struct A) aa loadstore mem[1] = { b: (byte) 1 }
(byte) aa_b
(byte) aa_b#0 aa_b zp[1]:2 20.0
(void()) main() (void()) main()
(label) main::@1 (label) main::@1
(label) main::@2 (label) main::@2
(label) main::@return (label) main::@return
(const byte*) main::SCREEN = (byte*) 1024 (const byte*) main::SCREEN = (byte*) 1024
(const struct A*) main::a = (struct A*)&(byte) aa_b#0 (const struct A*) main::a = &(struct A) aa
zp[1]:2 [ aa_b#0 ] mem[1] [ aa ]

View File

@@ -2,13 +2,18 @@
.pc = $801 "Basic" .pc = $801 "Basic"
:BasicUpstart(main) :BasicUpstart(main)
.pc = $80d "Program" .pc = $80d "Program"
.const point_x = 2 .const OFFSET_STRUCT_POINT_Y = 1
.const point_y = 3 .const SIZEOF_STRUCT_POINT = 2
main: { main: {
.label SCREEN = $400 .label SCREEN = $400
lda #point_x lda #2
sta point
lda #3
sta point+OFFSET_STRUCT_POINT_Y
lda point
sta SCREEN sta SCREEN
lda #point_y lda point+OFFSET_STRUCT_POINT_Y
sta SCREEN+1 sta SCREEN+1
rts rts
} }
point: .fill SIZEOF_STRUCT_POINT, 0

View File

@@ -10,9 +10,11 @@
(void()) main() (void()) main()
main: scope:[main] from @1 main: scope:[main] from @1
[4] *((const byte*) main::SCREEN) ← (const byte) point_x#1 [4] *((byte*)&(struct Point) point) ← (byte) 2
[5] *((const byte*) main::SCREEN+(byte) 1) ← (const byte) point_y#1 [5] *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
[6] *((const byte*) main::SCREEN) ← *((byte*)&(struct Point) point)
[7] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y)
to:main::@return to:main::@return
main::@return: scope:[main] from main main::@return: scope:[main] from main
[6] return [8] return
to:@return to:@return

View File

@@ -1,43 +1,26 @@
Created struct value member variable (byte) point_x Replacing struct member reference (struct Point) point.x with member unwinding reference *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_X)
Created struct value member variable (byte) point_y Replacing struct member reference (struct Point) point.y with member unwinding reference *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y)
Converted struct value to member variables (struct Point) point Replacing struct member reference (struct Point) point.x with member unwinding reference *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_X)
Adding struct value member variable copy (byte) point_x ← (byte) 0 Replacing struct member reference (struct Point) point.y with member unwinding reference *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y)
Adding struct value member variable copy (byte) point_y ← (byte) 0
Replacing struct member reference (struct Point) point.x with member unwinding reference (byte) point_x
Replacing struct member reference (struct Point) point.y with member unwinding reference (byte) point_y
Replacing struct member reference (struct Point) point.x with member unwinding reference (byte) point_x
Replacing struct member reference (struct Point) point.y with member unwinding reference (byte) point_y
CONTROL FLOW GRAPH SSA CONTROL FLOW GRAPH SSA
@begin: scope:[] from @begin: scope:[] from
(byte) point_x#0 ← (byte) 0
(byte) point_y#0 ← (byte) 0
to:@1 to:@1
(void()) main() (void()) main()
main: scope:[main] from @1 main: scope:[main] from @1
(byte) point_x#1 ← (number) 2 *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_X) ← (number) 2
(byte) point_y#1 ← (number) 3 *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) ← (number) 3
*((const byte*) main::SCREEN + (number) 0) ← (byte) point_x#1 *((const byte*) main::SCREEN + (number) 0) ← *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_X)
*((const byte*) main::SCREEN + (number) 1) ← (byte) point_y#1 *((const byte*) main::SCREEN + (number) 1) ← *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y)
to:main::@return to:main::@return
main::@return: scope:[main] from main main::@return: scope:[main] from main
(byte) point_y#4 ← phi( main/(byte) point_y#1 )
(byte) point_x#4 ← phi( main/(byte) point_x#1 )
(byte) point_x#2 ← (byte) point_x#4
(byte) point_y#2 ← (byte) point_y#4
return return
to:@return to:@return
@1: scope:[] from @begin @1: scope:[] from @begin
(byte) point_y#6 ← phi( @begin/(byte) point_y#0 )
(byte) point_x#6 ← phi( @begin/(byte) point_x#0 )
call main call main
to:@2 to:@2
@2: scope:[] from @1 @2: scope:[] from @1
(byte) point_y#5 ← phi( @1/(byte) point_y#2 )
(byte) point_x#5 ← phi( @1/(byte) point_x#2 )
(byte) point_x#3 ← (byte) point_x#5
(byte) point_y#3 ← (byte) point_y#5
to:@end to:@end
@end: scope:[] from @2 @end: scope:[] from @2
@@ -46,35 +29,22 @@ SYMBOL TABLE SSA
(label) @2 (label) @2
(label) @begin (label) @begin
(label) @end (label) @end
(const byte) OFFSET_STRUCT_POINT_X = (byte) 0
(const byte) OFFSET_STRUCT_POINT_Y = (byte) 1
(byte) Point::x (byte) Point::x
(byte) Point::y (byte) Point::y
(void()) main() (void()) main()
(label) main::@return (label) main::@return
(const byte*) main::SCREEN = (byte*)(number) $400 (const byte*) main::SCREEN = (byte*)(number) $400
(byte) point_x (struct Point) point loadstore = {}
(byte) point_x#0
(byte) point_x#1
(byte) point_x#2
(byte) point_x#3
(byte) point_x#4
(byte) point_x#5
(byte) point_x#6
(byte) point_y
(byte) point_y#0
(byte) point_y#1
(byte) point_y#2
(byte) point_y#3
(byte) point_y#4
(byte) point_y#5
(byte) point_y#6
Adding number conversion cast (unumber) 2 in (byte) point_x#1 ← (number) 2 Adding number conversion cast (unumber) 2 in *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_X) ← (number) 2
Adding number conversion cast (unumber) 3 in (byte) point_y#1 ← (number) 3 Adding number conversion cast (unumber) 3 in *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) ← (number) 3
Adding number conversion cast (unumber) 0 in *((const byte*) main::SCREEN + (number) 0) ← (byte) point_x#1 Adding number conversion cast (unumber) 0 in *((const byte*) main::SCREEN + (number) 0) ← *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_X)
Adding number conversion cast (unumber) 1 in *((const byte*) main::SCREEN + (number) 1) ← (byte) point_y#1 Adding number conversion cast (unumber) 1 in *((const byte*) main::SCREEN + (number) 1) ← *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y)
Successful SSA optimization PassNAddNumberTypeConversions Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast (byte) point_x#1 ← (unumber)(number) 2 Inlining cast *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_X) ← (unumber)(number) 2
Inlining cast (byte) point_y#1 ← (unumber)(number) 3 Inlining cast *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) ← (unumber)(number) 3
Successful SSA optimization Pass2InlineCast Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (byte*) 1024 Simplifying constant pointer cast (byte*) 1024
Simplifying constant integer cast 2 Simplifying constant integer cast 2
@@ -87,25 +57,11 @@ Finalized unsigned number type (byte) 3
Finalized unsigned number type (byte) 0 Finalized unsigned number type (byte) 0
Finalized unsigned number type (byte) 1 Finalized unsigned number type (byte) 1
Successful SSA optimization PassNFinalizeNumberTypeConversions Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias (byte) point_x#1 = (byte) point_x#4 (byte) point_x#2 Simplifying expression containing zero (byte*)&point in [0] *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
Alias (byte) point_y#1 = (byte) point_y#4 (byte) point_y#2 Simplifying expression containing zero (byte*)&point in [2] *((const byte*) main::SCREEN + (byte) 0) ← *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_X)
Alias (byte) point_x#0 = (byte) point_x#6 Simplifying expression containing zero main::SCREEN in [2] *((const byte*) main::SCREEN + (byte) 0) ← *((byte*)&(struct Point) point)
Alias (byte) point_y#0 = (byte) point_y#6
Alias (byte) point_x#3 = (byte) point_x#5
Alias (byte) point_y#3 = (byte) point_y#5
Successful SSA optimization Pass2AliasElimination
Identical Phi Values (byte) point_x#3 (byte) point_x#1
Identical Phi Values (byte) point_y#3 (byte) point_y#1
Successful SSA optimization Pass2IdenticalPhiElimination
Constant (const byte) point_x#0 = 0
Constant (const byte) point_y#0 = 0
Constant (const byte) point_x#1 = 2
Constant (const byte) point_y#1 = 3
Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero main::SCREEN in [4] *((const byte*) main::SCREEN + (byte) 0) ← (const byte) point_x#1
Successful SSA optimization PassNSimplifyExpressionWithZero Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant (const byte) point_x#0 Eliminating unused constant (const byte) OFFSET_STRUCT_POINT_X
Eliminating unused constant (const byte) point_y#0
Successful SSA optimization PassNEliminateUnusedVars Successful SSA optimization PassNEliminateUnusedVars
Consolidated array index constant in *(main::SCREEN+1) Consolidated array index constant in *(main::SCREEN+1)
Successful SSA optimization Pass2ConstantAdditionElimination Successful SSA optimization Pass2ConstantAdditionElimination
@@ -136,11 +92,13 @@ FINAL CONTROL FLOW GRAPH
(void()) main() (void()) main()
main: scope:[main] from @1 main: scope:[main] from @1
[4] *((const byte*) main::SCREEN) ← (const byte) point_x#1 [4] *((byte*)&(struct Point) point) ← (byte) 2
[5] *((const byte*) main::SCREEN+(byte) 1) ← (const byte) point_y#1 [5] *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
[6] *((const byte*) main::SCREEN) ← *((byte*)&(struct Point) point)
[7] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y)
to:main::@return to:main::@return
main::@return: scope:[main] from main main::@return: scope:[main] from main
[6] return [8] return
to:@return to:@return
@@ -148,11 +106,13 @@ VARIABLE REGISTER WEIGHTS
(byte) Point::x (byte) Point::x
(byte) Point::y (byte) Point::y
(void()) main() (void()) main()
(byte) point_x (struct Point) point loadstore = {}
(byte) point_y
Initial phi equivalence classes Initial phi equivalence classes
Added variable point to live range equivalence class [ point ]
Complete equivalence classes Complete equivalence classes
[ point ]
Allocated mem[2] [ point ]
INITIAL ASM INITIAL ASM
Target platform is c64basic / MOS6502X Target platform is c64basic / MOS6502X
@@ -163,8 +123,7 @@ Target platform is c64basic / MOS6502X
:BasicUpstart(__bbegin) :BasicUpstart(__bbegin)
.pc = $80d "Program" .pc = $80d "Program"
// Global Constants & labels // Global Constants & labels
.const point_x = 2 .const OFFSET_STRUCT_POINT_Y = 1
.const point_y = 3
// @begin // @begin
__bbegin: __bbegin:
// [1] phi from @begin to @1 [phi:@begin->@1] // [1] phi from @begin to @1 [phi:@begin->@1]
@@ -182,32 +141,42 @@ __bend:
// main // main
main: { main: {
.label SCREEN = $400 .label SCREEN = $400
// [4] *((const byte*) main::SCREEN) ← (const byte) point_x#1 -- _deref_pbuc1=vbuc2 // [4] *((byte*)&(struct Point) point) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #point_x lda #2
sta point
// [5] *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta point+OFFSET_STRUCT_POINT_Y
// [6] *((const byte*) main::SCREEN) ← *((byte*)&(struct Point) point) -- _deref_pbuc1=_deref_pbuc2
lda point
sta SCREEN sta SCREEN
// [5] *((const byte*) main::SCREEN+(byte) 1) ← (const byte) point_y#1 -- _deref_pbuc1=vbuc2 // [7] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda #point_y lda point+OFFSET_STRUCT_POINT_Y
sta SCREEN+1 sta SCREEN+1
jmp __breturn jmp __breturn
// main::@return // main::@return
__breturn: __breturn:
// [6] return // [8] return
rts rts
} }
// File Data // File Data
point: .fill SIZEOF_STRUCT_POINT, 0
REGISTER UPLIFT POTENTIAL REGISTERS REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] *((const byte*) main::SCREEN) ← (const byte) point_x#1 [ ] ( main:2 [ ] ) always clobbers reg byte a Statement [4] *((byte*)&(struct Point) point) ← (byte) 2 [ point ] ( main:2 [ point ] ) always clobbers reg byte a
Statement [5] *((const byte*) main::SCREEN+(byte) 1) ← (const byte) point_y#1 [ ] ( main:2 [ ] ) 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*) main::SCREEN) ← *((byte*)&(struct Point) point) [ point ] ( main:2 [ point ] ) always clobbers reg byte a
Statement [7] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) [ ] ( main:2 [ ] ) always clobbers reg byte a
Potential registers mem[2] [ point ] : mem[2] ,
REGISTER UPLIFT SCOPES REGISTER UPLIFT SCOPES
Uplift Scope [Point] Uplift Scope [Point]
Uplift Scope [main] Uplift Scope [main]
Uplift Scope [] Uplift Scope [] 0: mem[2] [ point ]
Uplifting [Point] best 33 combination Uplifting [Point] best 49 combination
Uplifting [main] best 33 combination Uplifting [main] best 49 combination
Uplifting [] best 33 combination Uplifting [] best 49 combination mem[2] [ point ]
ASSEMBLER BEFORE OPTIMIZATION ASSEMBLER BEFORE OPTIMIZATION
// File Comments // File Comments
@@ -217,8 +186,8 @@ ASSEMBLER BEFORE OPTIMIZATION
:BasicUpstart(__bbegin) :BasicUpstart(__bbegin)
.pc = $80d "Program" .pc = $80d "Program"
// Global Constants & labels // Global Constants & labels
.const point_x = 2 .const OFFSET_STRUCT_POINT_Y = 1
.const point_y = 3 .const SIZEOF_STRUCT_POINT = 2
// @begin // @begin
__bbegin: __bbegin:
// [1] phi from @begin to @1 [phi:@begin->@1] // [1] phi from @begin to @1 [phi:@begin->@1]
@@ -236,19 +205,26 @@ __bend:
// main // main
main: { main: {
.label SCREEN = $400 .label SCREEN = $400
// [4] *((const byte*) main::SCREEN) ← (const byte) point_x#1 -- _deref_pbuc1=vbuc2 // [4] *((byte*)&(struct Point) point) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #point_x lda #2
sta point
// [5] *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta point+OFFSET_STRUCT_POINT_Y
// [6] *((const byte*) main::SCREEN) ← *((byte*)&(struct Point) point) -- _deref_pbuc1=_deref_pbuc2
lda point
sta SCREEN sta SCREEN
// [5] *((const byte*) main::SCREEN+(byte) 1) ← (const byte) point_y#1 -- _deref_pbuc1=vbuc2 // [7] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda #point_y lda point+OFFSET_STRUCT_POINT_Y
sta SCREEN+1 sta SCREEN+1
jmp __breturn jmp __breturn
// main::@return // main::@return
__breturn: __breturn:
// [6] return // [8] return
rts rts
} }
// File Data // File Data
point: .fill SIZEOF_STRUCT_POINT, 0
ASSEMBLER OPTIMIZATIONS ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1 Removing instruction jmp __b1
@@ -273,20 +249,20 @@ FINAL SYMBOL TABLE
(label) @1 (label) @1
(label) @begin (label) @begin
(label) @end (label) @end
(const byte) OFFSET_STRUCT_POINT_Y = (byte) 1
(byte) Point::x (byte) Point::x
(byte) Point::y (byte) Point::y
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(void()) main() (void()) main()
(label) main::@return (label) main::@return
(const byte*) main::SCREEN = (byte*) 1024 (const byte*) main::SCREEN = (byte*) 1024
(byte) point_x (struct Point) point loadstore mem[2] = {}
(const byte) point_x#1 point_x = (byte) 2
(byte) point_y
(const byte) point_y#1 point_y = (byte) 3
mem[2] [ point ]
FINAL ASSEMBLER FINAL ASSEMBLER
Score: 18 Score: 34
// File Comments // File Comments
// Minimal struct - declaration, instantiation and usage // Minimal struct - declaration, instantiation and usage
@@ -295,8 +271,8 @@ Score: 18
:BasicUpstart(main) :BasicUpstart(main)
.pc = $80d "Program" .pc = $80d "Program"
// Global Constants & labels // Global Constants & labels
.const point_x = 2 .const OFFSET_STRUCT_POINT_Y = 1
.const point_y = 3 .const SIZEOF_STRUCT_POINT = 2
// @begin // @begin
// [1] phi from @begin to @1 [phi:@begin->@1] // [1] phi from @begin to @1 [phi:@begin->@1]
// @1 // @1
@@ -306,18 +282,27 @@ Score: 18
// main // main
main: { main: {
.label SCREEN = $400 .label SCREEN = $400
// point.x = 2
// [4] *((byte*)&(struct Point) point) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta point
// point.y = 3
// [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 // SCREEN[0] = point.x
// [4] *((const byte*) main::SCREEN) ← (const byte) point_x#1 -- _deref_pbuc1=vbuc2 // [6] *((const byte*) main::SCREEN) ← *((byte*)&(struct Point) point) -- _deref_pbuc1=_deref_pbuc2
lda #point_x lda point
sta SCREEN sta SCREEN
// SCREEN[1] = point.y // SCREEN[1] = point.y
// [5] *((const byte*) main::SCREEN+(byte) 1) ← (const byte) point_y#1 -- _deref_pbuc1=vbuc2 // [7] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda #point_y lda point+OFFSET_STRUCT_POINT_Y
sta SCREEN+1 sta SCREEN+1
// main::@return // main::@return
// } // }
// [6] return // [8] return
rts rts
} }
// File Data // File Data
point: .fill SIZEOF_STRUCT_POINT, 0

View File

@@ -1,13 +1,13 @@
(label) @1 (label) @1
(label) @begin (label) @begin
(label) @end (label) @end
(const byte) OFFSET_STRUCT_POINT_Y = (byte) 1
(byte) Point::x (byte) Point::x
(byte) Point::y (byte) Point::y
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(void()) main() (void()) main()
(label) main::@return (label) main::@return
(const byte*) main::SCREEN = (byte*) 1024 (const byte*) main::SCREEN = (byte*) 1024
(byte) point_x (struct Point) point loadstore mem[2] = {}
(const byte) point_x#1 point_x = (byte) 2
(byte) point_y
(const byte) point_y#1 point_y = (byte) 3
mem[2] [ point ]

View File

@@ -2,13 +2,22 @@
.pc = $801 "Basic" .pc = $801 "Basic"
:BasicUpstart(main) :BasicUpstart(main)
.pc = $80d "Program" .pc = $80d "Program"
.const point1_x = 2 .const OFFSET_STRUCT_POINT_Y = 1
.const point1_y = 3 .const SIZEOF_STRUCT_POINT = 2
main: { main: {
.label SCREEN = $400 .label SCREEN = $400
lda #point1_y lda #2
sta point1
lda #3
sta point1+OFFSET_STRUCT_POINT_Y
sta point2
lda point1
sta point2+OFFSET_STRUCT_POINT_Y
lda point2
sta SCREEN sta SCREEN
lda #point1_x lda point2+OFFSET_STRUCT_POINT_Y
sta SCREEN+1 sta SCREEN+1
rts rts
} }
point1: .fill SIZEOF_STRUCT_POINT, 0
point2: .fill SIZEOF_STRUCT_POINT, 0

View File

@@ -10,9 +10,13 @@
(void()) main() (void()) main()
main: scope:[main] from @1 main: scope:[main] from @1
[4] *((const byte*) main::SCREEN) ← (const byte) point1_y#1 [4] *((byte*)&(struct Point) point1) ← (byte) 2
[5] *((const byte*) main::SCREEN+(byte) 1) ← (const byte) point1_x#1 [5] *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
[6] *((byte*)&(struct Point) point2) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y)
[7] *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) point1)
[8] *((const byte*) main::SCREEN) ← *((byte*)&(struct Point) point2)
[9] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_Y)
to:main::@return to:main::@return
main::@return: scope:[main] from main main::@return: scope:[main] from main
[6] return [10] return
to:@return to:@return

View File

@@ -1,66 +1,32 @@
Created struct value member variable (byte) point1_x Replacing struct member reference (struct Point) point1.x with member unwinding reference *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_X)
Created struct value member variable (byte) point1_y Replacing struct member reference (struct Point) point1.y with member unwinding reference *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y)
Converted struct value to member variables (struct Point) point1 Replacing struct member reference (struct Point) point1.y with member unwinding reference *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y)
Created struct value member variable (byte) point2_x Replacing struct member reference (struct Point) point2.x with member unwinding reference *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_X)
Created struct value member variable (byte) point2_y Replacing struct member reference (struct Point) point1.x with member unwinding reference *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_X)
Converted struct value to member variables (struct Point) point2 Replacing struct member reference (struct Point) point2.y with member unwinding reference *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_Y)
Adding struct value member variable copy (byte) point1_x ← (byte) 0 Replacing struct member reference (struct Point) point2.x with member unwinding reference *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_X)
Adding struct value member variable copy (byte) point1_y ← (byte) 0 Replacing struct member reference (struct Point) point2.y with member unwinding reference *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_Y)
Adding struct value member variable copy (byte) point2_x ← (byte) 0
Adding struct value member variable copy (byte) point2_y ← (byte) 0
Replacing struct member reference (struct Point) point1.x with member unwinding reference (byte) point1_x
Replacing struct member reference (struct Point) point1.y with member unwinding reference (byte) point1_y
Replacing struct member reference (struct Point) point1.y with member unwinding reference (byte) point1_y
Replacing struct member reference (struct Point) point2.x with member unwinding reference (byte) point2_x
Replacing struct member reference (struct Point) point1.x with member unwinding reference (byte) point1_x
Replacing struct member reference (struct Point) point2.y with member unwinding reference (byte) point2_y
Replacing struct member reference (struct Point) point2.x with member unwinding reference (byte) point2_x
Replacing struct member reference (struct Point) point2.y with member unwinding reference (byte) point2_y
CONTROL FLOW GRAPH SSA CONTROL FLOW GRAPH SSA
@begin: scope:[] from @begin: scope:[] from
(byte) point1_x#0 ← (byte) 0
(byte) point1_y#0 ← (byte) 0
(byte) point2_x#0 ← (byte) 0
(byte) point2_y#0 ← (byte) 0
to:@1 to:@1
(void()) main() (void()) main()
main: scope:[main] from @1 main: scope:[main] from @1
(byte) point1_x#1 ← (number) 2 *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_X) ← (number) 2
(byte) point1_y#1 ← (number) 3 *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (number) 3
(byte) point2_x#1 ← (byte) point1_y#1 *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_X)*((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y)
(byte) point2_y#1 ← (byte) point1_x#1 *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_Y)*((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_X)
*((const byte*) main::SCREEN + (number) 0) ← (byte) point2_x#1 *((const byte*) main::SCREEN + (number) 0) ← *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_X)
*((const byte*) main::SCREEN + (number) 1) ← (byte) point2_y#1 *((const byte*) main::SCREEN + (number) 1) ← *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_Y)
to:main::@return to:main::@return
main::@return: scope:[main] from main main::@return: scope:[main] from main
(byte) point2_y#4 ← phi( main/(byte) point2_y#1 )
(byte) point2_x#4 ← phi( main/(byte) point2_x#1 )
(byte) point1_y#4 ← phi( main/(byte) point1_y#1 )
(byte) point1_x#4 ← phi( main/(byte) point1_x#1 )
(byte) point1_x#2 ← (byte) point1_x#4
(byte) point1_y#2 ← (byte) point1_y#4
(byte) point2_x#2 ← (byte) point2_x#4
(byte) point2_y#2 ← (byte) point2_y#4
return return
to:@return to:@return
@1: scope:[] from @begin @1: scope:[] from @begin
(byte) point2_y#6 ← phi( @begin/(byte) point2_y#0 )
(byte) point2_x#6 ← phi( @begin/(byte) point2_x#0 )
(byte) point1_y#6 ← phi( @begin/(byte) point1_y#0 )
(byte) point1_x#6 ← phi( @begin/(byte) point1_x#0 )
call main call main
to:@2 to:@2
@2: scope:[] from @1 @2: scope:[] from @1
(byte) point2_y#5 ← phi( @1/(byte) point2_y#2 )
(byte) point2_x#5 ← phi( @1/(byte) point2_x#2 )
(byte) point1_y#5 ← phi( @1/(byte) point1_y#2 )
(byte) point1_x#5 ← phi( @1/(byte) point1_x#2 )
(byte) point1_x#3 ← (byte) point1_x#5
(byte) point1_y#3 ← (byte) point1_y#5
(byte) point2_x#3 ← (byte) point2_x#5
(byte) point2_y#3 ← (byte) point2_y#5
to:@end to:@end
@end: scope:[] from @2 @end: scope:[] from @2
@@ -69,51 +35,23 @@ SYMBOL TABLE SSA
(label) @2 (label) @2
(label) @begin (label) @begin
(label) @end (label) @end
(const byte) OFFSET_STRUCT_POINT_X = (byte) 0
(const byte) OFFSET_STRUCT_POINT_Y = (byte) 1
(byte) Point::x (byte) Point::x
(byte) Point::y (byte) Point::y
(void()) main() (void()) main()
(label) main::@return (label) main::@return
(const byte*) main::SCREEN = (byte*)(number) $400 (const byte*) main::SCREEN = (byte*)(number) $400
(byte) point1_x (struct Point) point1 loadstore = {}
(byte) point1_x#0 (struct Point) point2 loadstore = {}
(byte) point1_x#1
(byte) point1_x#2
(byte) point1_x#3
(byte) point1_x#4
(byte) point1_x#5
(byte) point1_x#6
(byte) point1_y
(byte) point1_y#0
(byte) point1_y#1
(byte) point1_y#2
(byte) point1_y#3
(byte) point1_y#4
(byte) point1_y#5
(byte) point1_y#6
(byte) point2_x
(byte) point2_x#0
(byte) point2_x#1
(byte) point2_x#2
(byte) point2_x#3
(byte) point2_x#4
(byte) point2_x#5
(byte) point2_x#6
(byte) point2_y
(byte) point2_y#0
(byte) point2_y#1
(byte) point2_y#2
(byte) point2_y#3
(byte) point2_y#4
(byte) point2_y#5
(byte) point2_y#6
Adding number conversion cast (unumber) 2 in (byte) point1_x#1 ← (number) 2 Adding number conversion cast (unumber) 2 in *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_X) ← (number) 2
Adding number conversion cast (unumber) 3 in (byte) point1_y#1 ← (number) 3 Adding number conversion cast (unumber) 3 in *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (number) 3
Adding number conversion cast (unumber) 0 in *((const byte*) main::SCREEN + (number) 0) ← (byte) point2_x#1 Adding number conversion cast (unumber) 0 in *((const byte*) main::SCREEN + (number) 0) ← *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_X)
Adding number conversion cast (unumber) 1 in *((const byte*) main::SCREEN + (number) 1) ← (byte) point2_y#1 Adding number conversion cast (unumber) 1 in *((const byte*) main::SCREEN + (number) 1) ← *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_Y)
Successful SSA optimization PassNAddNumberTypeConversions Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast (byte) point1_x#1 ← (unumber)(number) 2 Inlining cast *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_X) ← (unumber)(number) 2
Inlining cast (byte) point1_y#1 ← (unumber)(number) 3 Inlining cast *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (unumber)(number) 3
Successful SSA optimization Pass2InlineCast Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (byte*) 1024 Simplifying constant pointer cast (byte*) 1024
Simplifying constant integer cast 2 Simplifying constant integer cast 2
@@ -126,35 +64,13 @@ Finalized unsigned number type (byte) 3
Finalized unsigned number type (byte) 0 Finalized unsigned number type (byte) 0
Finalized unsigned number type (byte) 1 Finalized unsigned number type (byte) 1
Successful SSA optimization PassNFinalizeNumberTypeConversions Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias (byte) point1_y#1 = (byte) point2_x#1 (byte) point1_y#4 (byte) point2_x#4 (byte) point1_y#2 (byte) point2_x#2 Simplifying expression containing zero (byte*)&point1 in [0] *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
Alias (byte) point1_x#1 = (byte) point2_y#1 (byte) point1_x#4 (byte) point2_y#4 (byte) point1_x#2 (byte) point2_y#2 Simplifying expression containing zero (byte*)&point2 in [2] *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_X) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y)
Alias (byte) point1_x#0 = (byte) point1_x#6 Simplifying expression containing zero (byte*)&point1 in [3] *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_X)
Alias (byte) point1_y#0 = (byte) point1_y#6 Simplifying expression containing zero (byte*)&point2 in [4] *((const byte*) main::SCREEN + (byte) 0) ← *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_X)
Alias (byte) point2_x#0 = (byte) point2_x#6 Simplifying expression containing zero main::SCREEN in [4] *((const byte*) main::SCREEN + (byte) 0) ← *((byte*)&(struct Point) point2)
Alias (byte) point2_y#0 = (byte) point2_y#6
Alias (byte) point1_x#3 = (byte) point1_x#5
Alias (byte) point1_y#3 = (byte) point1_y#5
Alias (byte) point2_x#3 = (byte) point2_x#5
Alias (byte) point2_y#3 = (byte) point2_y#5
Successful SSA optimization Pass2AliasElimination
Identical Phi Values (byte) point1_x#3 (byte) point1_x#1
Identical Phi Values (byte) point1_y#3 (byte) point1_y#1
Identical Phi Values (byte) point2_x#3 (byte) point1_y#1
Identical Phi Values (byte) point2_y#3 (byte) point1_x#1
Successful SSA optimization Pass2IdenticalPhiElimination
Constant (const byte) point1_x#0 = 0
Constant (const byte) point1_y#0 = 0
Constant (const byte) point2_x#0 = 0
Constant (const byte) point2_y#0 = 0
Constant (const byte) point1_x#1 = 2
Constant (const byte) point1_y#1 = 3
Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero main::SCREEN in [8] *((const byte*) main::SCREEN + (byte) 0) ← (const byte) point1_y#1
Successful SSA optimization PassNSimplifyExpressionWithZero Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant (const byte) point1_x#0 Eliminating unused constant (const byte) OFFSET_STRUCT_POINT_X
Eliminating unused constant (const byte) point1_y#0
Eliminating unused constant (const byte) point2_x#0
Eliminating unused constant (const byte) point2_y#0
Successful SSA optimization PassNEliminateUnusedVars Successful SSA optimization PassNEliminateUnusedVars
Consolidated array index constant in *(main::SCREEN+1) Consolidated array index constant in *(main::SCREEN+1)
Successful SSA optimization Pass2ConstantAdditionElimination Successful SSA optimization Pass2ConstantAdditionElimination
@@ -185,11 +101,15 @@ FINAL CONTROL FLOW GRAPH
(void()) main() (void()) main()
main: scope:[main] from @1 main: scope:[main] from @1
[4] *((const byte*) main::SCREEN) ← (const byte) point1_y#1 [4] *((byte*)&(struct Point) point1) ← (byte) 2
[5] *((const byte*) main::SCREEN+(byte) 1) ← (const byte) point1_x#1 [5] *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
[6] *((byte*)&(struct Point) point2) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y)
[7] *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) point1)
[8] *((const byte*) main::SCREEN) ← *((byte*)&(struct Point) point2)
[9] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_Y)
to:main::@return to:main::@return
main::@return: scope:[main] from main main::@return: scope:[main] from main
[6] return [10] return
to:@return to:@return
@@ -197,13 +117,17 @@ VARIABLE REGISTER WEIGHTS
(byte) Point::x (byte) Point::x
(byte) Point::y (byte) Point::y
(void()) main() (void()) main()
(byte) point1_x (struct Point) point1 loadstore = {}
(byte) point1_y (struct Point) point2 loadstore = {}
(byte) point2_x
(byte) point2_y
Initial phi equivalence classes Initial phi equivalence classes
Added variable point1 to live range equivalence class [ point1 ]
Added variable point2 to live range equivalence class [ point2 ]
Complete equivalence classes Complete equivalence classes
[ point1 ]
[ point2 ]
Allocated mem[2] [ point1 ]
Allocated mem[2] [ point2 ]
INITIAL ASM INITIAL ASM
Target platform is c64basic / MOS6502X Target platform is c64basic / MOS6502X
@@ -214,8 +138,7 @@ Target platform is c64basic / MOS6502X
:BasicUpstart(__bbegin) :BasicUpstart(__bbegin)
.pc = $80d "Program" .pc = $80d "Program"
// Global Constants & labels // Global Constants & labels
.const point1_x = 2 .const OFFSET_STRUCT_POINT_Y = 1
.const point1_y = 3
// @begin // @begin
__bbegin: __bbegin:
// [1] phi from @begin to @1 [phi:@begin->@1] // [1] phi from @begin to @1 [phi:@begin->@1]
@@ -233,32 +156,52 @@ __bend:
// main // main
main: { main: {
.label SCREEN = $400 .label SCREEN = $400
// [4] *((const byte*) main::SCREEN) ← (const byte) point1_y#1 -- _deref_pbuc1=vbuc2 // [4] *((byte*)&(struct Point) point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #point1_y lda #2
sta point1
// [5] *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta point1+OFFSET_STRUCT_POINT_Y
// [6] *((byte*)&(struct Point) point2) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda point1+OFFSET_STRUCT_POINT_Y
sta point2
// [7] *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) point1) -- _deref_pbuc1=_deref_pbuc2
lda point1
sta point2+OFFSET_STRUCT_POINT_Y
// [8] *((const byte*) main::SCREEN) ← *((byte*)&(struct Point) point2) -- _deref_pbuc1=_deref_pbuc2
lda point2
sta SCREEN sta SCREEN
// [5] *((const byte*) main::SCREEN+(byte) 1) ← (const byte) point1_x#1 -- _deref_pbuc1=vbuc2 // [9] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda #point1_x lda point2+OFFSET_STRUCT_POINT_Y
sta SCREEN+1 sta SCREEN+1
jmp __breturn jmp __breturn
// main::@return // main::@return
__breturn: __breturn:
// [6] return // [10] return
rts rts
} }
// File Data // File Data
point1: .fill SIZEOF_STRUCT_POINT, 0
point2: .fill SIZEOF_STRUCT_POINT, 0
REGISTER UPLIFT POTENTIAL REGISTERS REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] *((const byte*) main::SCREEN) ← (const byte) point1_y#1 [ ] ( main:2 [ ] ) always clobbers reg byte a Statement [4] *((byte*)&(struct Point) point1) ← (byte) 2 [ point1 point2 ] ( main:2 [ point1 point2 ] ) always clobbers reg byte a
Statement [5] *((const byte*) main::SCREEN+(byte) 1) ← (const byte) point1_x#1 [ ] ( main:2 [ ] ) always clobbers reg byte a Statement [5] *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 [ point1 point2 ] ( main:2 [ point1 point2 ] ) always clobbers reg byte a
Statement [6] *((byte*)&(struct Point) point2) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y) [ point1 point2 ] ( main:2 [ point1 point2 ] ) always clobbers reg byte a
Statement [7] *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) point1) [ point2 ] ( main:2 [ point2 ] ) always clobbers reg byte a
Statement [8] *((const byte*) main::SCREEN) ← *((byte*)&(struct Point) point2) [ point2 ] ( main:2 [ point2 ] ) always clobbers reg byte a
Statement [9] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_Y) [ ] ( main:2 [ ] ) always clobbers reg byte a
Potential registers mem[2] [ point1 ] : mem[2] ,
Potential registers mem[2] [ point2 ] : mem[2] ,
REGISTER UPLIFT SCOPES REGISTER UPLIFT SCOPES
Uplift Scope [Point] Uplift Scope [Point]
Uplift Scope [main] Uplift Scope [main]
Uplift Scope [] Uplift Scope [] 0: mem[2] [ point1 ] 0: mem[2] [ point2 ]
Uplifting [Point] best 33 combination Uplifting [Point] best 65 combination
Uplifting [main] best 33 combination Uplifting [main] best 65 combination
Uplifting [] best 33 combination Uplifting [] best 65 combination mem[2] [ point1 ] mem[2] [ point2 ]
ASSEMBLER BEFORE OPTIMIZATION ASSEMBLER BEFORE OPTIMIZATION
// File Comments // File Comments
@@ -268,8 +211,8 @@ ASSEMBLER BEFORE OPTIMIZATION
:BasicUpstart(__bbegin) :BasicUpstart(__bbegin)
.pc = $80d "Program" .pc = $80d "Program"
// Global Constants & labels // Global Constants & labels
.const point1_x = 2 .const OFFSET_STRUCT_POINT_Y = 1
.const point1_y = 3 .const SIZEOF_STRUCT_POINT = 2
// @begin // @begin
__bbegin: __bbegin:
// [1] phi from @begin to @1 [phi:@begin->@1] // [1] phi from @begin to @1 [phi:@begin->@1]
@@ -287,25 +230,41 @@ __bend:
// main // main
main: { main: {
.label SCREEN = $400 .label SCREEN = $400
// [4] *((const byte*) main::SCREEN) ← (const byte) point1_y#1 -- _deref_pbuc1=vbuc2 // [4] *((byte*)&(struct Point) point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #point1_y lda #2
sta point1
// [5] *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta point1+OFFSET_STRUCT_POINT_Y
// [6] *((byte*)&(struct Point) point2) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda point1+OFFSET_STRUCT_POINT_Y
sta point2
// [7] *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) point1) -- _deref_pbuc1=_deref_pbuc2
lda point1
sta point2+OFFSET_STRUCT_POINT_Y
// [8] *((const byte*) main::SCREEN) ← *((byte*)&(struct Point) point2) -- _deref_pbuc1=_deref_pbuc2
lda point2
sta SCREEN sta SCREEN
// [5] *((const byte*) main::SCREEN+(byte) 1) ← (const byte) point1_x#1 -- _deref_pbuc1=vbuc2 // [9] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda #point1_x lda point2+OFFSET_STRUCT_POINT_Y
sta SCREEN+1 sta SCREEN+1
jmp __breturn jmp __breturn
// main::@return // main::@return
__breturn: __breturn:
// [6] return // [10] return
rts rts
} }
// File Data // File Data
point1: .fill SIZEOF_STRUCT_POINT, 0
point2: .fill SIZEOF_STRUCT_POINT, 0
ASSEMBLER OPTIMIZATIONS ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1 Removing instruction jmp __b1
Removing instruction jmp __bend Removing instruction jmp __bend
Removing instruction jmp __breturn Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination Succesful ASM optimization Pass5NextJumpElimination
Removing instruction lda point1+OFFSET_STRUCT_POINT_Y
Succesful ASM optimization Pass5UnnecesaryLoadElimination
Replacing label __bbegin with __b1 Replacing label __bbegin with __b1
Removing instruction __bbegin: Removing instruction __bbegin:
Removing instruction __b1_from___bbegin: Removing instruction __b1_from___bbegin:
@@ -324,22 +283,22 @@ FINAL SYMBOL TABLE
(label) @1 (label) @1
(label) @begin (label) @begin
(label) @end (label) @end
(const byte) OFFSET_STRUCT_POINT_Y = (byte) 1
(byte) Point::x (byte) Point::x
(byte) Point::y (byte) Point::y
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(void()) main() (void()) main()
(label) main::@return (label) main::@return
(const byte*) main::SCREEN = (byte*) 1024 (const byte*) main::SCREEN = (byte*) 1024
(byte) point1_x (struct Point) point1 loadstore mem[2] = {}
(const byte) point1_x#1 point1_x = (byte) 2 (struct Point) point2 loadstore mem[2] = {}
(byte) point1_y
(const byte) point1_y#1 point1_y = (byte) 3
(byte) point2_x
(byte) point2_y
mem[2] [ point1 ]
mem[2] [ point2 ]
FINAL ASSEMBLER FINAL ASSEMBLER
Score: 18 Score: 46
// File Comments // File Comments
// Minimal struct - two instances being used. // Minimal struct - two instances being used.
@@ -348,8 +307,8 @@ Score: 18
:BasicUpstart(main) :BasicUpstart(main)
.pc = $80d "Program" .pc = $80d "Program"
// Global Constants & labels // Global Constants & labels
.const point1_x = 2 .const OFFSET_STRUCT_POINT_Y = 1
.const point1_y = 3 .const SIZEOF_STRUCT_POINT = 2
// @begin // @begin
// [1] phi from @begin to @1 [phi:@begin->@1] // [1] phi from @begin to @1 [phi:@begin->@1]
// @1 // @1
@@ -359,18 +318,35 @@ Score: 18
// main // main
main: { main: {
.label SCREEN = $400 .label SCREEN = $400
// point1.x = 2
// [4] *((byte*)&(struct Point) point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta point1
// point1.y = 3
// [5] *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta point1+OFFSET_STRUCT_POINT_Y
// point2.x = point1.y
// [6] *((byte*)&(struct Point) point2) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
sta point2
// point2.y = point1.x
// [7] *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_Y) ← *((byte*)&(struct Point) point1) -- _deref_pbuc1=_deref_pbuc2
lda point1
sta point2+OFFSET_STRUCT_POINT_Y
// SCREEN[0] = point2.x // SCREEN[0] = point2.x
// [4] *((const byte*) main::SCREEN) ← (const byte) point1_y#1 -- _deref_pbuc1=vbuc2 // [8] *((const byte*) main::SCREEN) ← *((byte*)&(struct Point) point2) -- _deref_pbuc1=_deref_pbuc2
lda #point1_y lda point2
sta SCREEN sta SCREEN
// SCREEN[1] = point2.y // SCREEN[1] = point2.y
// [5] *((const byte*) main::SCREEN+(byte) 1) ← (const byte) point1_x#1 -- _deref_pbuc1=vbuc2 // [9] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda #point1_x lda point2+OFFSET_STRUCT_POINT_Y
sta SCREEN+1 sta SCREEN+1
// main::@return // main::@return
// } // }
// [6] return // [10] return
rts rts
} }
// File Data // File Data
point1: .fill SIZEOF_STRUCT_POINT, 0
point2: .fill SIZEOF_STRUCT_POINT, 0

View File

@@ -1,15 +1,15 @@
(label) @1 (label) @1
(label) @begin (label) @begin
(label) @end (label) @end
(const byte) OFFSET_STRUCT_POINT_Y = (byte) 1
(byte) Point::x (byte) Point::x
(byte) Point::y (byte) Point::y
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(void()) main() (void()) main()
(label) main::@return (label) main::@return
(const byte*) main::SCREEN = (byte*) 1024 (const byte*) main::SCREEN = (byte*) 1024
(byte) point1_x (struct Point) point1 loadstore mem[2] = {}
(const byte) point1_x#1 point1_x = (byte) 2 (struct Point) point2 loadstore mem[2] = {}
(byte) point1_y
(const byte) point1_y#1 point1_y = (byte) 3
(byte) point2_x
(byte) point2_y
mem[2] [ point1 ]
mem[2] [ point2 ]

View File

@@ -1,39 +1,22 @@
// Example of a struct containing an array // Example of a struct containing an array
// Works because the struct is only handled as a value
.pc = $801 "Basic" .pc = $801 "Basic"
:BasicUpstart(__bbegin) :BasicUpstart(main)
.pc = $80d "Program" .pc = $80d "Program"
.label SCREEN = $400 .label SCREEN = $400
.const jesper_id = 4 .const OFFSET_STRUCT_PERSON_NAME = 1
.const henriette_id = 7
__bbegin:
ldy #$40
!:
lda __0-1,y
sta jesper_name-1,y
dey
bne !-
ldy #$40
!:
lda __1-1,y
sta henriette_name-1,y
dey
bne !-
jsr main
rts
main: { main: {
lda #<jesper_name ldx jesper
lda #<jesper+OFFSET_STRUCT_PERSON_NAME
sta.z print_person.person_name sta.z print_person.person_name
lda #>jesper_name lda #>jesper+OFFSET_STRUCT_PERSON_NAME
sta.z print_person.person_name+1 sta.z print_person.person_name+1
ldy #0 ldy #0
ldx #jesper_id
jsr print_person jsr print_person
lda #<henriette_name ldx henriette
lda #<henriette+OFFSET_STRUCT_PERSON_NAME
sta.z print_person.person_name sta.z print_person.person_name
lda #>henriette_name lda #>henriette+OFFSET_STRUCT_PERSON_NAME
sta.z print_person.person_name+1 sta.z print_person.person_name+1
ldx #henriette_id
jsr print_person jsr print_person
rts rts
} }
@@ -68,11 +51,11 @@ print_person: {
} }
DIGIT: .text "0123456789" DIGIT: .text "0123456789"
.byte 0 .byte 0
jesper_name: .fill $40, 0 jesper: .byte 4
henriette_name: .fill $40, 0 .text "jesper"
__0: .text "jesper"
.byte 0 .byte 0
.fill $39, 0 .fill $39, 0
__1: .text "henriette" henriette: .byte 7
.text "henriette"
.byte 0 .byte 0
.fill $36, 0 .fill $36, 0

View File

@@ -1,51 +1,50 @@
@begin: scope:[] from @begin: scope:[] from
[0] *((const byte*) jesper_name) ← memcpy(*(&(const byte*) $0), byte, (number) $40) [0] phi()
[1] *((const byte*) henriette_name) ← memcpy(*(&(const byte*) $1), byte, (number) $40)
to:@1 to:@1
@1: scope:[] from @begin @1: scope:[] from @begin
[2] phi() [1] phi()
[3] call main [2] call main
to:@end to:@end
@end: scope:[] from @1 @end: scope:[] from @1
[4] phi() [3] phi()
(void()) main() (void()) main()
main: scope:[main] from @1 main: scope:[main] from @1
[5] phi() [4] (byte) print_person::person_id#0 ← *((byte*)&(struct Person) jesper)
[6] call print_person [5] call print_person
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
[7] phi() [6] (byte) print_person::person_id#1 ← *((byte*)&(struct Person) henriette)
[8] call print_person [7] call print_person
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@1
[9] return [8] return
to:@return to:@return
(void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name) (void()) print_person((byte) print_person::person_id , (byte*) print_person::person_name)
print_person: scope:[print_person] from main main::@1 print_person: scope:[print_person] from main main::@1
[10] (byte*) print_person::person_name#4 ← phi( main/(const byte*) jesper_name main::@1/(const byte*) henriette_name ) [9] (byte*) print_person::person_name#4 ← phi( main/(byte*)&(struct Person) jesper+(const byte) OFFSET_STRUCT_PERSON_NAME main::@1/(byte*)&(struct Person) henriette+(const byte) OFFSET_STRUCT_PERSON_NAME )
[10] (byte) idx#13 ← phi( main/(byte) 0 main::@1/(byte) idx#16 ) [9] (byte) idx#13 ← phi( main/(byte) 0 main::@1/(byte) idx#16 )
[10] (byte) print_person::person_id#2 ← phi( main/(const byte) jesper_id main::@1/(const byte) henriette_id ) [9] (byte) print_person::person_id#2 ← phi( main/(byte) print_person::person_id#0 main::@1/(byte) print_person::person_id#1 )
[11] *((const byte*) SCREEN + (byte) idx#13) ← *((const byte*) DIGIT + (byte) print_person::person_id#2) [10] *((const byte*) SCREEN + (byte) idx#13) ← *((const byte*) DIGIT + (byte) print_person::person_id#2)
[12] (byte) idx#4 ← ++ (byte) idx#13 [11] (byte) idx#4 ← ++ (byte) idx#13
[13] *((const byte*) SCREEN + (byte) idx#4) ← (byte) ' ' [12] *((const byte*) SCREEN + (byte) idx#4) ← (byte) ' '
[14] (byte) idx#5 ← ++ (byte) idx#4 [13] (byte) idx#5 ← ++ (byte) idx#4
to:print_person::@1 to:print_person::@1
print_person::@1: scope:[print_person] from print_person print_person::@2 print_person::@1: scope:[print_person] from print_person print_person::@2
[15] (byte) idx#14 ← phi( print_person/(byte) idx#5 print_person::@2/(byte) idx#6 ) [14] (byte) idx#14 ← phi( print_person/(byte) idx#5 print_person::@2/(byte) idx#6 )
[15] (byte) print_person::i#2 ← phi( print_person/(byte) 0 print_person::@2/(byte) print_person::i#1 ) [14] (byte) print_person::i#2 ← phi( print_person/(byte) 0 print_person::@2/(byte) print_person::i#1 )
[16] if((byte) 0!=*((byte*) print_person::person_name#4 + (byte) print_person::i#2)) goto print_person::@2 [15] if((byte) 0!=*((byte*) print_person::person_name#4 + (byte) print_person::i#2)) goto print_person::@2
to:print_person::@3 to:print_person::@3
print_person::@3: scope:[print_person] from print_person::@1 print_person::@3: scope:[print_person] from print_person::@1
[17] *((const byte*) SCREEN + (byte) idx#14) ← (byte) ' ' [16] *((const byte*) SCREEN + (byte) idx#14) ← (byte) ' '
[18] (byte) idx#16 ← ++ (byte) idx#14 [17] (byte) idx#16 ← ++ (byte) idx#14
to:print_person::@return to:print_person::@return
print_person::@return: scope:[print_person] from print_person::@3 print_person::@return: scope:[print_person] from print_person::@3
[19] return [18] return
to:@return to:@return
print_person::@2: scope:[print_person] from print_person::@1 print_person::@2: scope:[print_person] from print_person::@1
[20] *((const byte*) SCREEN + (byte) idx#14) ← *((byte*) print_person::person_name#4 + (byte) print_person::i#2) [19] *((const byte*) SCREEN + (byte) idx#14) ← *((byte*) print_person::person_name#4 + (byte) print_person::i#2)
[21] (byte) idx#6 ← ++ (byte) idx#14 [20] (byte) idx#6 ← ++ (byte) idx#14
[22] (byte) print_person::i#1 ← ++ (byte) print_person::i#2 [21] (byte) print_person::i#1 ← ++ (byte) print_person::i#2
to:print_person::@1 to:print_person::@1

File diff suppressed because it is too large Load Diff

View File

@@ -1,14 +1,12 @@
(const byte*) $0[(number) $40] = (string) "jesper"
(const byte*) $1[(number) $40] = (string) "henriette"
(label) @1 (label) @1
(label) @begin (label) @begin
(label) @end (label) @end
(const byte*) DIGIT[] = (string) "0123456789" (const byte*) DIGIT[] = (string) "0123456789"
(const byte) OFFSET_STRUCT_PERSON_NAME = (byte) 1
(byte) Person::id (byte) Person::id
(const byte*) Person::name[(number) $40] = { fill( $40, 0) } (const byte*) Person::name[(number) $40] = { fill( $40, 0) }
(const byte*) SCREEN = (byte*) 1024 (const byte*) SCREEN = (byte*) 1024
(const byte) henriette_id = (byte) 7 (struct Person) henriette loadstore mem[65] = { id: (byte) 7, name: (string) "henriette" }
(const byte*) henriette_name[(number) $40] = { fill( $40, 0) }
(byte) idx (byte) idx
(byte) idx#13 reg byte y 3.0 (byte) idx#13 reg byte y 3.0
(byte) idx#14 reg byte x 9.75 (byte) idx#14 reg byte x 9.75
@@ -16,8 +14,7 @@
(byte) idx#4 reg byte x 3.0 (byte) idx#4 reg byte x 3.0
(byte) idx#5 reg byte x 4.0 (byte) idx#5 reg byte x 4.0
(byte) idx#6 reg byte x 11.0 (byte) idx#6 reg byte x 11.0
(const byte) jesper_id = (byte) 4 (struct Person) jesper loadstore mem[65] = { id: (byte) 4, name: (string) "jesper" }
(const byte*) jesper_name[(number) $40] = { fill( $40, 0) }
(void()) main() (void()) main()
(label) main::@1 (label) main::@1
(label) main::@return (label) main::@return
@@ -31,13 +28,17 @@
(byte) print_person::i#2 reg byte y 11.0 (byte) print_person::i#2 reg byte y 11.0
(struct Person) print_person::person (struct Person) print_person::person
(byte) print_person::person_id (byte) print_person::person_id
(byte) print_person::person_id#2 reg byte x 2.0 (byte) print_person::person_id#0 reg byte x 4.0
(byte) print_person::person_id#1 reg byte x 4.0
(byte) print_person::person_id#2 reg byte x 6.0
(byte*) print_person::person_name (byte*) print_person::person_name
(byte*) print_person::person_name#4 person_name zp[2]:2 2.2 (byte*) print_person::person_name#4 person_name zp[2]:2 2.2
reg byte x [ print_person::person_id#2 ] reg byte x [ print_person::person_id#2 print_person::person_id#0 print_person::person_id#1 ]
reg byte y [ idx#13 idx#16 ] reg byte y [ idx#13 idx#16 ]
zp[2]:2 [ print_person::person_name#4 ] zp[2]:2 [ print_person::person_name#4 ]
reg byte y [ print_person::i#2 print_person::i#1 ] reg byte y [ print_person::i#2 print_person::i#1 ]
reg byte x [ idx#14 idx#5 idx#6 ] reg byte x [ idx#14 idx#5 idx#6 ]
reg byte x [ idx#4 ] reg byte x [ idx#4 ]
mem[65] [ jesper ]
mem[65] [ henriette ]

View File

@@ -1,28 +1,19 @@
// Minimal struct with C-Standard behavior - declaration, instantiation and usage // Minimal struct with C-Standard behavior - declaration, instantiation and usage
.pc = $801 "Basic" .pc = $801 "Basic"
:BasicUpstart(__bbegin) :BasicUpstart(main)
.pc = $80d "Program" .pc = $80d "Program"
.label SCREEN = $400 .label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1 .const OFFSET_STRUCT_POINT_Y = 1
.label point = 2 .const SIZEOF_STRUCT_POINT = 2
__bbegin:
ldy #SIZEOF_STRUCT_POINT
lda #0
!:
dey
sta point,y
bne !-
jsr main
rts
main: { main: {
lda #2 lda #2
sta.z point sta point
lda #3 lda #3
sta point+OFFSET_STRUCT_POINT_Y sta point+OFFSET_STRUCT_POINT_Y
lda.z point lda point
sta SCREEN sta SCREEN
lda point+OFFSET_STRUCT_POINT_Y lda point+OFFSET_STRUCT_POINT_Y
sta SCREEN+1 sta SCREEN+1
rts rts
} }
point: .fill SIZEOF_STRUCT_POINT, 0

View File

@@ -1,5 +1,5 @@
@begin: scope:[] from @begin: scope:[] from
[0] *(&(struct Point) point) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT) [0] phi()
to:@1 to:@1
@1: scope:[] from @begin @1: scope:[] from @begin
[1] phi() [1] phi()

View File

@@ -1,4 +1,3 @@
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.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.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) Replacing struct member reference (struct Point) point.x with member unwinding reference *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_X)
@@ -6,7 +5,6 @@ Replacing struct member reference (struct Point) point.y with member unwinding r
CONTROL FLOW GRAPH SSA CONTROL FLOW GRAPH SSA
@begin: scope:[] from @begin: scope:[] from
*(&(struct Point) point) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT)
to:@1 to:@1
(void()) main() (void()) main()
@@ -36,10 +34,9 @@ SYMBOL TABLE SSA
(byte) Point::x (byte) Point::x
(byte) Point::y (byte) Point::y
(const byte*) SCREEN = (byte*)(number) $400 (const byte*) SCREEN = (byte*)(number) $400
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(void()) main() (void()) main()
(label) main::@return (label) main::@return
(struct Point) point loadstore (struct Point) point loadstore = {}
Adding number conversion cast (unumber) 2 in *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_X) ← (number) 2 Adding number conversion cast (unumber) 2 in *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_X) ← (number) 2
Adding number conversion cast (unumber) 3 in *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) ← (number) 3 Adding number conversion cast (unumber) 3 in *((byte*)&(struct Point) point+(const byte) OFFSET_STRUCT_POINT_Y) ← (number) 3
@@ -60,14 +57,15 @@ Finalized unsigned number type (byte) 3
Finalized unsigned number type (byte) 0 Finalized unsigned number type (byte) 0
Finalized unsigned number type (byte) 1 Finalized unsigned number type (byte) 1
Successful SSA optimization PassNFinalizeNumberTypeConversions Successful SSA optimization PassNFinalizeNumberTypeConversions
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 [0] *((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 (byte*)&point in [2] *((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) Simplifying expression containing zero SCREEN in [2] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) point)
Successful SSA optimization PassNSimplifyExpressionWithZero Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant (const byte) OFFSET_STRUCT_POINT_X Eliminating unused constant (const byte) OFFSET_STRUCT_POINT_X
Successful SSA optimization PassNEliminateUnusedVars Successful SSA optimization PassNEliminateUnusedVars
Consolidated array index constant in *(SCREEN+1) Consolidated array index constant in *(SCREEN+1)
Successful SSA optimization Pass2ConstantAdditionElimination Successful SSA optimization Pass2ConstantAdditionElimination
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1 Adding NOP phi() at start of @1
Adding NOP phi() at start of @2 Adding NOP phi() at start of @2
Adding NOP phi() at start of @end Adding NOP phi() at start of @end
@@ -77,12 +75,13 @@ Calls in [] to main:2
Created 0 initial phi equivalence classes Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes Coalesced down to 0 phi equivalence classes
Culled Empty Block (label) @2 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 @1
Adding NOP phi() at start of @end Adding NOP phi() at start of @end
FINAL CONTROL FLOW GRAPH FINAL CONTROL FLOW GRAPH
@begin: scope:[] from @begin: scope:[] from
[0] *(&(struct Point) point) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT) [0] phi()
to:@1 to:@1
@1: scope:[] from @begin @1: scope:[] from @begin
[1] phi() [1] phi()
@@ -107,13 +106,13 @@ VARIABLE REGISTER WEIGHTS
(byte) Point::x (byte) Point::x
(byte) Point::y (byte) Point::y
(void()) main() (void()) main()
(struct Point) point loadstore (struct Point) point loadstore = {}
Initial phi equivalence classes Initial phi equivalence classes
Added variable point to live range equivalence class [ point ] Added variable point to live range equivalence class [ point ]
Complete equivalence classes Complete equivalence classes
[ point ] [ point ]
Allocated zp[2]:2 [ point ] Allocated mem[2] [ point ]
INITIAL ASM INITIAL ASM
Target platform is c64basic / MOS6502X Target platform is c64basic / MOS6502X
@@ -125,18 +124,9 @@ Target platform is c64basic / MOS6502X
.pc = $80d "Program" .pc = $80d "Program"
// Global Constants & labels // Global Constants & labels
.label SCREEN = $400 .label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1 .const OFFSET_STRUCT_POINT_Y = 1
.label point = 2
// @begin // @begin
__bbegin: __bbegin:
// [0] *(&(struct Point) point) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_memset_vbuc2
ldy #SIZEOF_STRUCT_POINT
lda #0
!:
dey
sta point,y
bne !-
// [1] phi from @begin to @1 [phi:@begin->@1] // [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin: __b1_from___bbegin:
jmp __b1 jmp __b1
@@ -153,12 +143,12 @@ __bend:
main: { main: {
// [4] *((byte*)&(struct Point) point) ← (byte) 2 -- _deref_pbuc1=vbuc2 // [4] *((byte*)&(struct Point) point) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2 lda #2
sta.z point sta point
// [5] *((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 lda #3
sta point+OFFSET_STRUCT_POINT_Y sta point+OFFSET_STRUCT_POINT_Y
// [6] *((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 lda point
sta SCREEN sta SCREEN
// [7] *((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 lda point+OFFSET_STRUCT_POINT_Y
@@ -170,23 +160,23 @@ main: {
rts rts
} }
// File Data // File Data
point: .fill SIZEOF_STRUCT_POINT, 0
REGISTER UPLIFT POTENTIAL REGISTERS REGISTER UPLIFT POTENTIAL REGISTERS
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 [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 [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 [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 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 , Potential registers mem[2] [ point ] : mem[2] ,
REGISTER UPLIFT SCOPES REGISTER UPLIFT SCOPES
Uplift Scope [Point] Uplift Scope [Point]
Uplift Scope [main] Uplift Scope [main]
Uplift Scope [] 0: zp[2]:2 [ point ] Uplift Scope [] 0: mem[2] [ point ]
Uplifting [Point] best 60 combination Uplifting [Point] best 49 combination
Uplifting [main] best 60 combination Uplifting [main] best 49 combination
Uplifting [] best 60 combination zp[2]:2 [ point ] Uplifting [] best 49 combination mem[2] [ point ]
ASSEMBLER BEFORE OPTIMIZATION ASSEMBLER BEFORE OPTIMIZATION
// File Comments // File Comments
@@ -197,18 +187,10 @@ ASSEMBLER BEFORE OPTIMIZATION
.pc = $80d "Program" .pc = $80d "Program"
// Global Constants & labels // Global Constants & labels
.label SCREEN = $400 .label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1 .const OFFSET_STRUCT_POINT_Y = 1
.label point = 2 .const SIZEOF_STRUCT_POINT = 2
// @begin // @begin
__bbegin: __bbegin:
// [0] *(&(struct Point) point) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_memset_vbuc2
ldy #SIZEOF_STRUCT_POINT
lda #0
!:
dey
sta point,y
bne !-
// [1] phi from @begin to @1 [phi:@begin->@1] // [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin: __b1_from___bbegin:
jmp __b1 jmp __b1
@@ -225,12 +207,12 @@ __bend:
main: { main: {
// [4] *((byte*)&(struct Point) point) ← (byte) 2 -- _deref_pbuc1=vbuc2 // [4] *((byte*)&(struct Point) point) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2 lda #2
sta.z point sta point
// [5] *((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 lda #3
sta point+OFFSET_STRUCT_POINT_Y sta point+OFFSET_STRUCT_POINT_Y
// [6] *((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 lda point
sta SCREEN sta SCREEN
// [7] *((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 lda point+OFFSET_STRUCT_POINT_Y
@@ -242,21 +224,26 @@ main: {
rts rts
} }
// File Data // File Data
point: .fill SIZEOF_STRUCT_POINT, 0
ASSEMBLER OPTIMIZATIONS ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1 Removing instruction jmp __b1
Removing instruction jmp __bend Removing instruction jmp __bend
Removing instruction jmp __breturn Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination Succesful ASM optimization Pass5NextJumpElimination
Replacing label __bbegin with __b1
Removing instruction __bbegin:
Removing instruction __b1_from___bbegin: Removing instruction __b1_from___bbegin:
Removing instruction __bend_from___b1: Removing instruction __bend_from___b1:
Succesful ASM optimization Pass5RedundantLabelElimination Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __b1:
Removing instruction __bend: Removing instruction __bend:
Removing instruction __breturn: Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination Succesful ASM optimization Pass5UnusedLabelElimination
Adding RTS to root block Updating BasicUpstart to call main directly
Succesful ASM optimization Pass5AddMainRts Removing instruction jsr main
Succesful ASM optimization Pass5SkipBegin
Removing instruction __b1:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE FINAL SYMBOL TABLE
(label) @1 (label) @1
@@ -269,40 +256,28 @@ FINAL SYMBOL TABLE
(const byte) SIZEOF_STRUCT_POINT = (byte) 2 (const byte) SIZEOF_STRUCT_POINT = (byte) 2
(void()) main() (void()) main()
(label) main::@return (label) main::@return
(struct Point) point loadstore zp[2]:2 (struct Point) point loadstore mem[2] = {}
zp[2]:2 [ point ] mem[2] [ point ]
FINAL ASSEMBLER FINAL ASSEMBLER
Score: 57 Score: 34
// File Comments // File Comments
// Minimal struct with C-Standard behavior - declaration, instantiation and usage // Minimal struct with C-Standard behavior - declaration, instantiation and usage
// Upstart // Upstart
.pc = $801 "Basic" .pc = $801 "Basic"
:BasicUpstart(__bbegin) :BasicUpstart(main)
.pc = $80d "Program" .pc = $80d "Program"
// Global Constants & labels // Global Constants & labels
.label SCREEN = $400 .label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 2
.const OFFSET_STRUCT_POINT_Y = 1 .const OFFSET_STRUCT_POINT_Y = 1
.label point = 2 .const SIZEOF_STRUCT_POINT = 2
// @begin // @begin
__bbegin:
// point
// [0] *(&(struct Point) point) ← memset(struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_memset_vbuc2
ldy #SIZEOF_STRUCT_POINT
lda #0
!:
dey
sta point,y
bne !-
// [1] phi from @begin to @1 [phi:@begin->@1] // [1] phi from @begin to @1 [phi:@begin->@1]
// @1 // @1
// [2] call main // [2] call main
jsr main
rts
// [3] phi from @1 to @end [phi:@1->@end] // [3] phi from @1 to @end [phi:@1->@end]
// @end // @end
// main // main
@@ -310,14 +285,14 @@ main: {
// point.x = 2 // point.x = 2
// [4] *((byte*)&(struct Point) point) ← (byte) 2 -- _deref_pbuc1=vbuc2 // [4] *((byte*)&(struct Point) point) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2 lda #2
sta.z point sta point
// point.y = 3 // point.y = 3
// [5] *((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 lda #3
sta point+OFFSET_STRUCT_POINT_Y sta point+OFFSET_STRUCT_POINT_Y
// SCREEN[0] = point.x // SCREEN[0] = point.x
// [6] *((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 lda point
sta SCREEN sta SCREEN
// SCREEN[1] = point.y // SCREEN[1] = point.y
// [7] *((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
@@ -329,4 +304,5 @@ main: {
rts rts
} }
// File Data // File Data
point: .fill SIZEOF_STRUCT_POINT, 0

View File

@@ -8,6 +8,6 @@
(const byte) SIZEOF_STRUCT_POINT = (byte) 2 (const byte) SIZEOF_STRUCT_POINT = (byte) 2
(void()) main() (void()) main()
(label) main::@return (label) main::@return
(struct Point) point loadstore zp[2]:2 (struct Point) point loadstore mem[2] = {}
zp[2]:2 [ point ] mem[2] [ point ]

View File

@@ -2,18 +2,31 @@
.pc = $801 "Basic" .pc = $801 "Basic"
:BasicUpstart(main) :BasicUpstart(main)
.pc = $80d "Program" .pc = $80d "Program"
.const point1_x = 2 .const SIZEOF_STRUCT_POINT = 2
.const point1_y = 3 .const OFFSET_STRUCT_POINT_Y = 1
.const point2_x = 4
main: { main: {
.label SCREEN = $400 .label SCREEN = $400
lda #point1_x lda #2
sta point1
lda #3
sta point1+OFFSET_STRUCT_POINT_Y
ldy #SIZEOF_STRUCT_POINT
!:
lda point1-1,y
sta point2-1,y
dey
bne !-
lda #4
sta point2
lda point1
sta SCREEN sta SCREEN
lda #point1_y lda point1+OFFSET_STRUCT_POINT_Y
sta SCREEN+1 sta SCREEN+1
lda #point2_x lda point2
sta SCREEN+2 sta SCREEN+2
lda #point1_y lda point2+OFFSET_STRUCT_POINT_Y
sta SCREEN+3 sta SCREEN+3
rts rts
} }
point1: .fill SIZEOF_STRUCT_POINT, 0
point2: .fill SIZEOF_STRUCT_POINT, 0

View File

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

View File

@@ -1,70 +1,34 @@
Created struct value member variable (byte) point1_x Adding struct value member variable copy *(&(struct Point) point2) ← memcpy(*(&(struct Point) point1), struct Point, (const byte) SIZEOF_STRUCT_POINT)
Created struct value member variable (byte) point1_y Replacing struct member reference (struct Point) point1.x with member unwinding reference *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_X)
Converted struct value to member variables (struct Point) point1 Replacing struct member reference (struct Point) point1.y with member unwinding reference *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y)
Created struct value member variable (byte) point2_x Replacing struct member reference (struct Point) point2.x with member unwinding reference *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_X)
Created struct value member variable (byte) point2_y Replacing struct member reference (struct Point) point1.x with member unwinding reference *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_X)
Converted struct value to member variables (struct Point) point2 Replacing struct member reference (struct Point) point1.y with member unwinding reference *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y)
Adding struct value member variable copy (byte) point1_x ← (byte) 0 Replacing struct member reference (struct Point) point2.x with member unwinding reference *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_X)
Adding struct value member variable copy (byte) point1_y ← (byte) 0 Replacing struct member reference (struct Point) point2.y with member unwinding reference *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_Y)
Adding struct value member variable copy (byte) point2_x ← (byte) 0
Adding struct value member variable copy (byte) point2_y ← (byte) 0
Adding struct value member variable copy (byte) point2_x ← (byte) point1_x
Adding struct value member variable copy (byte) point2_y ← (byte) point1_y
Replacing struct member reference (struct Point) point1.x with member unwinding reference (byte) point1_x
Replacing struct member reference (struct Point) point1.y with member unwinding reference (byte) point1_y
Replacing struct member reference (struct Point) point2.x with member unwinding reference (byte) point2_x
Replacing struct member reference (struct Point) point1.x with member unwinding reference (byte) point1_x
Replacing struct member reference (struct Point) point1.y with member unwinding reference (byte) point1_y
Replacing struct member reference (struct Point) point2.x with member unwinding reference (byte) point2_x
Replacing struct member reference (struct Point) point2.y with member unwinding reference (byte) point2_y
CONTROL FLOW GRAPH SSA CONTROL FLOW GRAPH SSA
@begin: scope:[] from @begin: scope:[] from
(byte) point1_x#0 ← (byte) 0
(byte) point1_y#0 ← (byte) 0
(byte) point2_x#0 ← (byte) 0
(byte) point2_y#0 ← (byte) 0
to:@1 to:@1
(void()) main() (void()) main()
main: scope:[main] from @1 main: scope:[main] from @1
(byte) point1_x#1 ← (number) 2 *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_X) ← (number) 2
(byte) point1_y#1 ← (number) 3 *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (number) 3
(byte) point2_x#1 ← (byte) point1_x#1 *(&(struct Point) point2) ← memcpy(*(&(struct Point) point1), struct Point, (const byte) SIZEOF_STRUCT_POINT)
(byte) point2_y#1 ← (byte) point1_y#1 *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_X) ← (number) 4
(byte) point2_x#2 ← (number) 4 *((const byte*) main::SCREEN + (number) 0) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_X)
*((const byte*) main::SCREEN + (number) 0) ← (byte) point1_x#1 *((const byte*) main::SCREEN + (number) 1) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y)
*((const byte*) main::SCREEN + (number) 1) ← (byte) point1_y#1 *((const byte*) main::SCREEN + (number) 2) ← *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_X)
*((const byte*) main::SCREEN + (number) 2) ← (byte) point2_x#2 *((const byte*) main::SCREEN + (number) 3) ← *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_Y)
*((const byte*) main::SCREEN + (number) 3) ← (byte) point2_y#1
to:main::@return to:main::@return
main::@return: scope:[main] from main main::@return: scope:[main] from main
(byte) point2_y#4 ← phi( main/(byte) point2_y#1 )
(byte) point2_x#5 ← phi( main/(byte) point2_x#2 )
(byte) point1_y#4 ← phi( main/(byte) point1_y#1 )
(byte) point1_x#4 ← phi( main/(byte) point1_x#1 )
(byte) point1_x#2 ← (byte) point1_x#4
(byte) point1_y#2 ← (byte) point1_y#4
(byte) point2_x#3 ← (byte) point2_x#5
(byte) point2_y#2 ← (byte) point2_y#4
return return
to:@return to:@return
@1: scope:[] from @begin @1: scope:[] from @begin
(byte) point2_y#6 ← phi( @begin/(byte) point2_y#0 )
(byte) point2_x#7 ← phi( @begin/(byte) point2_x#0 )
(byte) point1_y#6 ← phi( @begin/(byte) point1_y#0 )
(byte) point1_x#6 ← phi( @begin/(byte) point1_x#0 )
call main call main
to:@2 to:@2
@2: scope:[] from @1 @2: scope:[] from @1
(byte) point2_y#5 ← phi( @1/(byte) point2_y#2 )
(byte) point2_x#6 ← phi( @1/(byte) point2_x#3 )
(byte) point1_y#5 ← phi( @1/(byte) point1_y#2 )
(byte) point1_x#5 ← phi( @1/(byte) point1_x#2 )
(byte) point1_x#3 ← (byte) point1_x#5
(byte) point1_y#3 ← (byte) point1_y#5
(byte) point2_x#4 ← (byte) point2_x#6
(byte) point2_y#3 ← (byte) point2_y#5
to:@end to:@end
@end: scope:[] from @2 @end: scope:[] from @2
@@ -73,56 +37,28 @@ SYMBOL TABLE SSA
(label) @2 (label) @2
(label) @begin (label) @begin
(label) @end (label) @end
(const byte) OFFSET_STRUCT_POINT_X = (byte) 0
(const byte) OFFSET_STRUCT_POINT_Y = (byte) 1
(byte) Point::x (byte) Point::x
(byte) Point::y (byte) Point::y
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(void()) main() (void()) main()
(label) main::@return (label) main::@return
(const byte*) main::SCREEN = (byte*)(number) $400 (const byte*) main::SCREEN = (byte*)(number) $400
(byte) point1_x (struct Point) point1 loadstore = {}
(byte) point1_x#0 (struct Point) point2 loadstore = {}
(byte) point1_x#1
(byte) point1_x#2
(byte) point1_x#3
(byte) point1_x#4
(byte) point1_x#5
(byte) point1_x#6
(byte) point1_y
(byte) point1_y#0
(byte) point1_y#1
(byte) point1_y#2
(byte) point1_y#3
(byte) point1_y#4
(byte) point1_y#5
(byte) point1_y#6
(byte) point2_x
(byte) point2_x#0
(byte) point2_x#1
(byte) point2_x#2
(byte) point2_x#3
(byte) point2_x#4
(byte) point2_x#5
(byte) point2_x#6
(byte) point2_x#7
(byte) point2_y
(byte) point2_y#0
(byte) point2_y#1
(byte) point2_y#2
(byte) point2_y#3
(byte) point2_y#4
(byte) point2_y#5
(byte) point2_y#6
Adding number conversion cast (unumber) 2 in (byte) point1_x#1 ← (number) 2 Adding number conversion cast (unumber) 2 in *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_X) ← (number) 2
Adding number conversion cast (unumber) 3 in (byte) point1_y#1 ← (number) 3 Adding number conversion cast (unumber) 3 in *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (number) 3
Adding number conversion cast (unumber) 4 in (byte) point2_x#2 ← (number) 4 Adding number conversion cast (unumber) 4 in *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_X) ← (number) 4
Adding number conversion cast (unumber) 0 in *((const byte*) main::SCREEN + (number) 0) ← (byte) point1_x#1 Adding number conversion cast (unumber) 0 in *((const byte*) main::SCREEN + (number) 0) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_X)
Adding number conversion cast (unumber) 1 in *((const byte*) main::SCREEN + (number) 1) ← (byte) point1_y#1 Adding number conversion cast (unumber) 1 in *((const byte*) main::SCREEN + (number) 1) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y)
Adding number conversion cast (unumber) 2 in *((const byte*) main::SCREEN + (number) 2) ← (byte) point2_x#2 Adding number conversion cast (unumber) 2 in *((const byte*) main::SCREEN + (number) 2) ← *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_X)
Adding number conversion cast (unumber) 3 in *((const byte*) main::SCREEN + (number) 3) ← (byte) point2_y#1 Adding number conversion cast (unumber) 3 in *((const byte*) main::SCREEN + (number) 3) ← *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_Y)
Successful SSA optimization PassNAddNumberTypeConversions Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast (byte) point1_x#1 ← (unumber)(number) 2 Inlining cast *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_X) ← (unumber)(number) 2
Inlining cast (byte) point1_y#1 ← (unumber)(number) 3 Inlining cast *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (unumber)(number) 3
Inlining cast (byte) point2_x#2 ← (unumber)(number) 4 Inlining cast *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_X) ← (unumber)(number) 4
Successful SSA optimization Pass2InlineCast Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (byte*) 1024 Simplifying constant pointer cast (byte*) 1024
Simplifying constant integer cast 2 Simplifying constant integer cast 2
@@ -141,37 +77,13 @@ Finalized unsigned number type (byte) 1
Finalized unsigned number type (byte) 2 Finalized unsigned number type (byte) 2
Finalized unsigned number type (byte) 3 Finalized unsigned number type (byte) 3
Successful SSA optimization PassNFinalizeNumberTypeConversions Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias (byte) point1_x#1 = (byte) point2_x#1 (byte) point1_x#4 (byte) point1_x#2 Simplifying expression containing zero (byte*)&point1 in [0] *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 2
Alias (byte) point1_y#1 = (byte) point2_y#1 (byte) point1_y#4 (byte) point2_y#4 (byte) point1_y#2 (byte) point2_y#2 Simplifying expression containing zero (byte*)&point2 in [3] *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) 4
Alias (byte) point2_x#2 = (byte) point2_x#5 (byte) point2_x#3 Simplifying expression containing zero (byte*)&point1 in [4] *((const byte*) main::SCREEN + (byte) 0) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_X)
Alias (byte) point1_x#0 = (byte) point1_x#6 Simplifying expression containing zero main::SCREEN in [4] *((const byte*) main::SCREEN + (byte) 0) ← *((byte*)&(struct Point) point1)
Alias (byte) point1_y#0 = (byte) point1_y#6 Simplifying expression containing zero (byte*)&point2 in [6] *((const byte*) main::SCREEN + (byte) 2) ← *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_X)
Alias (byte) point2_x#0 = (byte) point2_x#7
Alias (byte) point2_y#0 = (byte) point2_y#6
Alias (byte) point1_x#3 = (byte) point1_x#5
Alias (byte) point1_y#3 = (byte) point1_y#5
Alias (byte) point2_x#4 = (byte) point2_x#6
Alias (byte) point2_y#3 = (byte) point2_y#5
Successful SSA optimization Pass2AliasElimination
Identical Phi Values (byte) point1_x#3 (byte) point1_x#1
Identical Phi Values (byte) point1_y#3 (byte) point1_y#1
Identical Phi Values (byte) point2_x#4 (byte) point2_x#2
Identical Phi Values (byte) point2_y#3 (byte) point1_y#1
Successful SSA optimization Pass2IdenticalPhiElimination
Constant (const byte) point1_x#0 = 0
Constant (const byte) point1_y#0 = 0
Constant (const byte) point2_x#0 = 0
Constant (const byte) point2_y#0 = 0
Constant (const byte) point1_x#1 = 2
Constant (const byte) point1_y#1 = 3
Constant (const byte) point2_x#2 = 4
Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero main::SCREEN in [9] *((const byte*) main::SCREEN + (byte) 0) ← (const byte) point1_x#1
Successful SSA optimization PassNSimplifyExpressionWithZero Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant (const byte) point1_x#0 Eliminating unused constant (const byte) OFFSET_STRUCT_POINT_X
Eliminating unused constant (const byte) point1_y#0
Eliminating unused constant (const byte) point2_x#0
Eliminating unused constant (const byte) point2_y#0
Successful SSA optimization PassNEliminateUnusedVars Successful SSA optimization PassNEliminateUnusedVars
Consolidated array index constant in *(main::SCREEN+1) Consolidated array index constant in *(main::SCREEN+1)
Consolidated array index constant in *(main::SCREEN+2) Consolidated array index constant in *(main::SCREEN+2)
@@ -204,13 +116,17 @@ FINAL CONTROL FLOW GRAPH
(void()) main() (void()) main()
main: scope:[main] from @1 main: scope:[main] from @1
[4] *((const byte*) main::SCREEN) ← (const byte) point1_x#1 [4] *((byte*)&(struct Point) point1) ← (byte) 2
[5] *((const byte*) main::SCREEN+(byte) 1) ← (const byte) point1_y#1 [5] *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3
[6] *((const byte*) main::SCREEN+(byte) 2) ← (const byte) point2_x#2 [6] *(&(struct Point) point2) ← memcpy(*(&(struct Point) point1), struct Point, (const byte) SIZEOF_STRUCT_POINT)
[7] *((const byte*) main::SCREEN+(byte) 3) ← (const byte) point1_y#1 [7] *((byte*)&(struct Point) point2) ← (byte) 4
[8] *((const byte*) main::SCREEN) ← *((byte*)&(struct Point) point1)
[9] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y)
[10] *((const byte*) main::SCREEN+(byte) 2) ← *((byte*)&(struct Point) point2)
[11] *((const byte*) main::SCREEN+(byte) 3) ← *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_Y)
to:main::@return to:main::@return
main::@return: scope:[main] from main main::@return: scope:[main] from main
[8] return [12] return
to:@return to:@return
@@ -218,13 +134,17 @@ VARIABLE REGISTER WEIGHTS
(byte) Point::x (byte) Point::x
(byte) Point::y (byte) Point::y
(void()) main() (void()) main()
(byte) point1_x (struct Point) point1 loadstore = {}
(byte) point1_y (struct Point) point2 loadstore = {}
(byte) point2_x
(byte) point2_y
Initial phi equivalence classes Initial phi equivalence classes
Added variable point1 to live range equivalence class [ point1 ]
Added variable point2 to live range equivalence class [ point2 ]
Complete equivalence classes Complete equivalence classes
[ point1 ]
[ point2 ]
Allocated mem[2] [ point1 ]
Allocated mem[2] [ point2 ]
INITIAL ASM INITIAL ASM
Target platform is c64basic / MOS6502X Target platform is c64basic / MOS6502X
@@ -235,9 +155,8 @@ Target platform is c64basic / MOS6502X
:BasicUpstart(__bbegin) :BasicUpstart(__bbegin)
.pc = $80d "Program" .pc = $80d "Program"
// Global Constants & labels // Global Constants & labels
.const point1_x = 2 .const SIZEOF_STRUCT_POINT = 2
.const point1_y = 3 .const OFFSET_STRUCT_POINT_Y = 1
.const point2_x = 4
// @begin // @begin
__bbegin: __bbegin:
// [1] phi from @begin to @1 [phi:@begin->@1] // [1] phi from @begin to @1 [phi:@begin->@1]
@@ -255,40 +174,64 @@ __bend:
// main // main
main: { main: {
.label SCREEN = $400 .label SCREEN = $400
// [4] *((const byte*) main::SCREEN) ← (const byte) point1_x#1 -- _deref_pbuc1=vbuc2 // [4] *((byte*)&(struct Point) point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #point1_x lda #2
sta point1
// [5] *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta point1+OFFSET_STRUCT_POINT_Y
// [6] *(&(struct Point) point2) ← memcpy(*(&(struct Point) 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 !-
// [7] *((byte*)&(struct Point) point2) ← (byte) 4 -- _deref_pbuc1=vbuc2
lda #4
sta point2
// [8] *((const byte*) main::SCREEN) ← *((byte*)&(struct Point) point1) -- _deref_pbuc1=_deref_pbuc2
lda point1
sta SCREEN sta SCREEN
// [5] *((const byte*) main::SCREEN+(byte) 1) ← (const byte) point1_y#1 -- _deref_pbuc1=vbuc2 // [9] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda #point1_y lda point1+OFFSET_STRUCT_POINT_Y
sta SCREEN+1 sta SCREEN+1
// [6] *((const byte*) main::SCREEN+(byte) 2) ← (const byte) point2_x#2 -- _deref_pbuc1=vbuc2 // [10] *((const byte*) main::SCREEN+(byte) 2) ← *((byte*)&(struct Point) point2) -- _deref_pbuc1=_deref_pbuc2
lda #point2_x lda point2
sta SCREEN+2 sta SCREEN+2
// [7] *((const byte*) main::SCREEN+(byte) 3) ← (const byte) point1_y#1 -- _deref_pbuc1=vbuc2 // [11] *((const byte*) main::SCREEN+(byte) 3) ← *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda #point1_y lda point2+OFFSET_STRUCT_POINT_Y
sta SCREEN+3 sta SCREEN+3
jmp __breturn jmp __breturn
// main::@return // main::@return
__breturn: __breturn:
// [8] return // [12] return
rts rts
} }
// File Data // File Data
point1: .fill SIZEOF_STRUCT_POINT, 0
point2: .fill SIZEOF_STRUCT_POINT, 0
REGISTER UPLIFT POTENTIAL REGISTERS REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] *((const byte*) main::SCREEN) ← (const byte) point1_x#1 [ ] ( main:2 [ ] ) always clobbers reg byte a Statement [4] *((byte*)&(struct Point) point1) ← (byte) 2 [ point1 point2 ] ( main:2 [ point1 point2 ] ) always clobbers reg byte a
Statement [5] *((const byte*) main::SCREEN+(byte) 1) ← (const byte) point1_y#1 [ ] ( main:2 [ ] ) always clobbers reg byte a Statement [5] *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 [ point1 point2 ] ( main:2 [ point1 point2 ] ) always clobbers reg byte a
Statement [6] *((const byte*) main::SCREEN+(byte) 2) ← (const byte) point2_x#2 [ ] ( main:2 [ ] ) always clobbers reg byte a Statement [6] *(&(struct Point) point2) ← memcpy(*(&(struct Point) point1), struct Point, (const byte) SIZEOF_STRUCT_POINT) [ point1 point2 ] ( main:2 [ point1 point2 ] ) always clobbers reg byte a reg byte y
Statement [7] *((const byte*) main::SCREEN+(byte) 3) ← (const byte) point1_y#1 [ ] ( main:2 [ ] ) always clobbers reg byte a Statement [7] *((byte*)&(struct Point) point2) ← (byte) 4 [ point1 point2 ] ( main:2 [ point1 point2 ] ) always clobbers reg byte a
Statement [8] *((const byte*) main::SCREEN) ← *((byte*)&(struct Point) point1) [ point1 point2 ] ( main:2 [ point1 point2 ] ) always clobbers reg byte a
Statement [9] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y) [ point2 ] ( main:2 [ point2 ] ) always clobbers reg byte a
Statement [10] *((const byte*) main::SCREEN+(byte) 2) ← *((byte*)&(struct Point) point2) [ point2 ] ( main:2 [ point2 ] ) always clobbers reg byte a
Statement [11] *((const byte*) main::SCREEN+(byte) 3) ← *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_Y) [ ] ( main:2 [ ] ) always clobbers reg byte a
Potential registers mem[2] [ point1 ] : mem[2] ,
Potential registers mem[2] [ point2 ] : mem[2] ,
REGISTER UPLIFT SCOPES REGISTER UPLIFT SCOPES
Uplift Scope [Point] Uplift Scope [Point]
Uplift Scope [main] Uplift Scope [main]
Uplift Scope [] Uplift Scope [] 0: mem[2] [ point1 ] 0: mem[2] [ point2 ]
Uplifting [Point] best 45 combination Uplifting [Point] best 87 combination
Uplifting [main] best 45 combination Uplifting [main] best 87 combination
Uplifting [] best 45 combination Uplifting [] best 87 combination mem[2] [ point1 ] mem[2] [ point2 ]
ASSEMBLER BEFORE OPTIMIZATION ASSEMBLER BEFORE OPTIMIZATION
// File Comments // File Comments
@@ -298,9 +241,8 @@ ASSEMBLER BEFORE OPTIMIZATION
:BasicUpstart(__bbegin) :BasicUpstart(__bbegin)
.pc = $80d "Program" .pc = $80d "Program"
// Global Constants & labels // Global Constants & labels
.const point1_x = 2 .const SIZEOF_STRUCT_POINT = 2
.const point1_y = 3 .const OFFSET_STRUCT_POINT_Y = 1
.const point2_x = 4
// @begin // @begin
__bbegin: __bbegin:
// [1] phi from @begin to @1 [phi:@begin->@1] // [1] phi from @begin to @1 [phi:@begin->@1]
@@ -318,25 +260,43 @@ __bend:
// main // main
main: { main: {
.label SCREEN = $400 .label SCREEN = $400
// [4] *((const byte*) main::SCREEN) ← (const byte) point1_x#1 -- _deref_pbuc1=vbuc2 // [4] *((byte*)&(struct Point) point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #point1_x lda #2
sta point1
// [5] *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta point1+OFFSET_STRUCT_POINT_Y
// [6] *(&(struct Point) point2) ← memcpy(*(&(struct Point) 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 !-
// [7] *((byte*)&(struct Point) point2) ← (byte) 4 -- _deref_pbuc1=vbuc2
lda #4
sta point2
// [8] *((const byte*) main::SCREEN) ← *((byte*)&(struct Point) point1) -- _deref_pbuc1=_deref_pbuc2
lda point1
sta SCREEN sta SCREEN
// [5] *((const byte*) main::SCREEN+(byte) 1) ← (const byte) point1_y#1 -- _deref_pbuc1=vbuc2 // [9] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda #point1_y lda point1+OFFSET_STRUCT_POINT_Y
sta SCREEN+1 sta SCREEN+1
// [6] *((const byte*) main::SCREEN+(byte) 2) ← (const byte) point2_x#2 -- _deref_pbuc1=vbuc2 // [10] *((const byte*) main::SCREEN+(byte) 2) ← *((byte*)&(struct Point) point2) -- _deref_pbuc1=_deref_pbuc2
lda #point2_x lda point2
sta SCREEN+2 sta SCREEN+2
// [7] *((const byte*) main::SCREEN+(byte) 3) ← (const byte) point1_y#1 -- _deref_pbuc1=vbuc2 // [11] *((const byte*) main::SCREEN+(byte) 3) ← *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda #point1_y lda point2+OFFSET_STRUCT_POINT_Y
sta SCREEN+3 sta SCREEN+3
jmp __breturn jmp __breturn
// main::@return // main::@return
__breturn: __breturn:
// [8] return // [12] return
rts rts
} }
// File Data // File Data
point1: .fill SIZEOF_STRUCT_POINT, 0
point2: .fill SIZEOF_STRUCT_POINT, 0
ASSEMBLER OPTIMIZATIONS ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1 Removing instruction jmp __b1
@@ -361,23 +321,22 @@ FINAL SYMBOL TABLE
(label) @1 (label) @1
(label) @begin (label) @begin
(label) @end (label) @end
(const byte) OFFSET_STRUCT_POINT_Y = (byte) 1
(byte) Point::x (byte) Point::x
(byte) Point::y (byte) Point::y
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(void()) main() (void()) main()
(label) main::@return (label) main::@return
(const byte*) main::SCREEN = (byte*) 1024 (const byte*) main::SCREEN = (byte*) 1024
(byte) point1_x (struct Point) point1 loadstore mem[2] = {}
(const byte) point1_x#1 point1_x = (byte) 2 (struct Point) point2 loadstore mem[2] = {}
(byte) point1_y
(const byte) point1_y#1 point1_y = (byte) 3
(byte) point2_x
(const byte) point2_x#2 point2_x = (byte) 4
(byte) point2_y
mem[2] [ point1 ]
mem[2] [ point2 ]
FINAL ASSEMBLER FINAL ASSEMBLER
Score: 30 Score: 72
// File Comments // File Comments
// Minimal struct - two instances being copied (using assignment) // Minimal struct - two instances being copied (using assignment)
@@ -386,9 +345,8 @@ Score: 30
:BasicUpstart(main) :BasicUpstart(main)
.pc = $80d "Program" .pc = $80d "Program"
// Global Constants & labels // Global Constants & labels
.const point1_x = 2 .const SIZEOF_STRUCT_POINT = 2
.const point1_y = 3 .const OFFSET_STRUCT_POINT_Y = 1
.const point2_x = 4
// @begin // @begin
// [1] phi from @begin to @1 [phi:@begin->@1] // [1] phi from @begin to @1 [phi:@begin->@1]
// @1 // @1
@@ -398,26 +356,48 @@ Score: 30
// main // main
main: { main: {
.label SCREEN = $400 .label SCREEN = $400
// point1.x = 2
// [4] *((byte*)&(struct Point) point1) ← (byte) 2 -- _deref_pbuc1=vbuc2
lda #2
sta point1
// point1.y = 3
// [5] *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) 3 -- _deref_pbuc1=vbuc2
lda #3
sta point1+OFFSET_STRUCT_POINT_Y
// point2 = point1
// [6] *(&(struct Point) point2) ← memcpy(*(&(struct Point) 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 !-
// point2.x = 4
// [7] *((byte*)&(struct Point) point2) ← (byte) 4 -- _deref_pbuc1=vbuc2
lda #4
sta point2
// SCREEN[0] = point1.x // SCREEN[0] = point1.x
// [4] *((const byte*) main::SCREEN) ← (const byte) point1_x#1 -- _deref_pbuc1=vbuc2 // [8] *((const byte*) main::SCREEN) ← *((byte*)&(struct Point) point1) -- _deref_pbuc1=_deref_pbuc2
lda #point1_x lda point1
sta SCREEN sta SCREEN
// SCREEN[1] = point1.y // SCREEN[1] = point1.y
// [5] *((const byte*) main::SCREEN+(byte) 1) ← (const byte) point1_y#1 -- _deref_pbuc1=vbuc2 // [9] *((const byte*) main::SCREEN+(byte) 1) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda #point1_y lda point1+OFFSET_STRUCT_POINT_Y
sta SCREEN+1 sta SCREEN+1
// SCREEN[2] = point2.x // SCREEN[2] = point2.x
// [6] *((const byte*) main::SCREEN+(byte) 2) ← (const byte) point2_x#2 -- _deref_pbuc1=vbuc2 // [10] *((const byte*) main::SCREEN+(byte) 2) ← *((byte*)&(struct Point) point2) -- _deref_pbuc1=_deref_pbuc2
lda #point2_x lda point2
sta SCREEN+2 sta SCREEN+2
// SCREEN[3] = point2.y // SCREEN[3] = point2.y
// [7] *((const byte*) main::SCREEN+(byte) 3) ← (const byte) point1_y#1 -- _deref_pbuc1=vbuc2 // [11] *((const byte*) main::SCREEN+(byte) 3) ← *((byte*)&(struct Point) point2+(const byte) OFFSET_STRUCT_POINT_Y) -- _deref_pbuc1=_deref_pbuc2
lda #point1_y lda point2+OFFSET_STRUCT_POINT_Y
sta SCREEN+3 sta SCREEN+3
// main::@return // main::@return
// } // }
// [8] return // [12] return
rts rts
} }
// File Data // File Data
point1: .fill SIZEOF_STRUCT_POINT, 0
point2: .fill SIZEOF_STRUCT_POINT, 0

View File

@@ -1,16 +1,15 @@
(label) @1 (label) @1
(label) @begin (label) @begin
(label) @end (label) @end
(const byte) OFFSET_STRUCT_POINT_Y = (byte) 1
(byte) Point::x (byte) Point::x
(byte) Point::y (byte) Point::y
(const byte) SIZEOF_STRUCT_POINT = (byte) 2
(void()) main() (void()) main()
(label) main::@return (label) main::@return
(const byte*) main::SCREEN = (byte*) 1024 (const byte*) main::SCREEN = (byte*) 1024
(byte) point1_x (struct Point) point1 loadstore mem[2] = {}
(const byte) point1_x#1 point1_x = (byte) 2 (struct Point) point2 loadstore mem[2] = {}
(byte) point1_y
(const byte) point1_y#1 point1_y = (byte) 3
(byte) point2_x
(const byte) point2_x#2 point2_x = (byte) 4
(byte) point2_y
mem[2] [ point1 ]
mem[2] [ point2 ]

View File

@@ -0,0 +1,14 @@
// Struct - forced __ssa
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
.label SCREEN = $400
.const point_x = 2
.const point_y = 3
main: {
lda #point_x
sta SCREEN
lda #point_y
sta SCREEN+1
rts
}

View File

@@ -0,0 +1,18 @@
@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] *((const byte*) SCREEN) ← (const byte) point_x#1
[5] *((const byte*) SCREEN+(byte) 1) ← (const byte) point_y#1
to:main::@return
main::@return: scope:[main] from main
[6] return
to:@return

323
src/test/ref/struct-34.log Normal file
View File

@@ -0,0 +1,323 @@
Created struct value member variable (byte) point_x
Created struct value member variable (byte) point_y
Converted struct value to member variables (struct Point) point
Adding struct value member variable copy (byte) point_x ← (byte) 0
Adding struct value member variable copy (byte) point_y ← (byte) 0
Replacing struct member reference (struct Point) point.x with member unwinding reference (byte) point_x
Replacing struct member reference (struct Point) point.y with member unwinding reference (byte) point_y
Replacing struct member reference (struct Point) point.x with member unwinding reference (byte) point_x
Replacing struct member reference (struct Point) point.y with member unwinding reference (byte) point_y
CONTROL FLOW GRAPH SSA
@begin: scope:[] from
(byte) point_x#0 ← (byte) 0
(byte) point_y#0 ← (byte) 0
to:@1
(void()) main()
main: scope:[main] from @1
(byte) point_x#1 ← (number) 2
(byte) point_y#1 ← (number) 3
*((const byte*) SCREEN + (number) 0) ← (byte) point_x#1
*((const byte*) SCREEN + (number) 1) ← (byte) point_y#1
to:main::@return
main::@return: scope:[main] from main
(byte) point_y#4 ← phi( main/(byte) point_y#1 )
(byte) point_x#4 ← phi( main/(byte) point_x#1 )
(byte) point_x#2 ← (byte) point_x#4
(byte) point_y#2 ← (byte) point_y#4
return
to:@return
@1: scope:[] from @begin
(byte) point_y#6 ← phi( @begin/(byte) point_y#0 )
(byte) point_x#6 ← phi( @begin/(byte) point_x#0 )
call main
to:@2
@2: scope:[] from @1
(byte) point_y#5 ← phi( @1/(byte) point_y#2 )
(byte) point_x#5 ← phi( @1/(byte) point_x#2 )
(byte) point_x#3 ← (byte) point_x#5
(byte) point_y#3 ← (byte) point_y#5
to:@end
@end: scope:[] from @2
SYMBOL TABLE SSA
(label) @1
(label) @2
(label) @begin
(label) @end
(byte) Point::x
(byte) Point::y
(const byte*) SCREEN = (byte*)(number) $400
(void()) main()
(label) main::@return
(byte) point_x
(byte) point_x#0
(byte) point_x#1
(byte) point_x#2
(byte) point_x#3
(byte) point_x#4
(byte) point_x#5
(byte) point_x#6
(byte) point_y
(byte) point_y#0
(byte) point_y#1
(byte) point_y#2
(byte) point_y#3
(byte) point_y#4
(byte) point_y#5
(byte) point_y#6
Adding number conversion cast (unumber) 2 in (byte) point_x#1 ← (number) 2
Adding number conversion cast (unumber) 3 in (byte) point_y#1 ← (number) 3
Adding number conversion cast (unumber) 0 in *((const byte*) SCREEN + (number) 0) ← (byte) point_x#1
Adding number conversion cast (unumber) 1 in *((const byte*) SCREEN + (number) 1) ← (byte) point_y#1
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast (byte) point_x#1 ← (unumber)(number) 2
Inlining cast (byte) point_y#1 ← (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
Alias (byte) point_x#1 = (byte) point_x#4 (byte) point_x#2
Alias (byte) point_y#1 = (byte) point_y#4 (byte) point_y#2
Alias (byte) point_x#0 = (byte) point_x#6
Alias (byte) point_y#0 = (byte) point_y#6
Alias (byte) point_x#3 = (byte) point_x#5
Alias (byte) point_y#3 = (byte) point_y#5
Successful SSA optimization Pass2AliasElimination
Identical Phi Values (byte) point_x#3 (byte) point_x#1
Identical Phi Values (byte) point_y#3 (byte) point_y#1
Successful SSA optimization Pass2IdenticalPhiElimination
Constant (const byte) point_x#0 = 0
Constant (const byte) point_y#0 = 0
Constant (const byte) point_x#1 = 2
Constant (const byte) point_y#1 = 3
Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero SCREEN in [4] *((const byte*) SCREEN + (byte) 0) ← (const byte) point_x#1
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant (const byte) point_x#0
Eliminating unused constant (const byte) point_y#0
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] *((const byte*) SCREEN) ← (const byte) point_x#1
[5] *((const byte*) SCREEN+(byte) 1) ← (const byte) point_y#1
to:main::@return
main::@return: scope:[main] from main
[6] return
to:@return
VARIABLE REGISTER WEIGHTS
(byte) Point::x
(byte) Point::y
(void()) main()
(byte) point_x
(byte) point_y
Initial phi equivalence classes
Complete equivalence classes
INITIAL ASM
Target platform is c64basic / MOS6502X
// File Comments
// Struct - forced __ssa
// Upstart
.pc = $801 "Basic"
:BasicUpstart(__bbegin)
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const point_x = 2
.const point_y = 3
// @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: {
// [4] *((const byte*) SCREEN) ← (const byte) point_x#1 -- _deref_pbuc1=vbuc2
lda #point_x
sta SCREEN
// [5] *((const byte*) SCREEN+(byte) 1) ← (const byte) point_y#1 -- _deref_pbuc1=vbuc2
lda #point_y
sta SCREEN+1
jmp __breturn
// main::@return
__breturn:
// [6] return
rts
}
// File Data
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] *((const byte*) SCREEN) ← (const byte) point_x#1 [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [5] *((const byte*) SCREEN+(byte) 1) ← (const byte) point_y#1 [ ] ( main:2 [ ] ) always clobbers reg byte a
REGISTER UPLIFT SCOPES
Uplift Scope [Point]
Uplift Scope [main]
Uplift Scope []
Uplifting [Point] best 33 combination
Uplifting [main] best 33 combination
Uplifting [] best 33 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Struct - forced __ssa
// Upstart
.pc = $801 "Basic"
:BasicUpstart(__bbegin)
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const point_x = 2
.const point_y = 3
// @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: {
// [4] *((const byte*) SCREEN) ← (const byte) point_x#1 -- _deref_pbuc1=vbuc2
lda #point_x
sta SCREEN
// [5] *((const byte*) SCREEN+(byte) 1) ← (const byte) point_y#1 -- _deref_pbuc1=vbuc2
lda #point_y
sta SCREEN+1
jmp __breturn
// main::@return
__breturn:
// [6] 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
(byte) Point::x
(byte) Point::y
(const byte*) SCREEN = (byte*) 1024
(void()) main()
(label) main::@return
(byte) point_x
(const byte) point_x#1 point_x = (byte) 2
(byte) point_y
(const byte) point_y#1 point_y = (byte) 3
FINAL ASSEMBLER
Score: 18
// File Comments
// Struct - forced __ssa
// Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.const point_x = 2
.const point_y = 3
// @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: {
// SCREEN[0] = point.x
// [4] *((const byte*) SCREEN) ← (const byte) point_x#1 -- _deref_pbuc1=vbuc2
lda #point_x
sta SCREEN
// SCREEN[1] = point.y
// [5] *((const byte*) SCREEN+(byte) 1) ← (const byte) point_y#1 -- _deref_pbuc1=vbuc2
lda #point_y
sta SCREEN+1
// main::@return
// }
// [6] return
rts
}
// File Data

View File

@@ -0,0 +1,13 @@
(label) @1
(label) @begin
(label) @end
(byte) Point::x
(byte) Point::y
(const byte*) SCREEN = (byte*) 1024
(void()) main()
(label) main::@return
(byte) point_x
(const byte) point_x#1 point_x = (byte) 2
(byte) point_y
(const byte) point_y#1 point_y = (byte) 3