2019-09-13 21:29:42 +00:00
Fixing struct type size struct Person to 17
Fixing struct type size struct Person to 17
Fixing struct type size struct Person to 17
Created struct value member variable (byte) main::jesper_id
Created struct value member variable (byte[$10]) main::jesper_name
Converted struct value to member variables (struct Person) main::jesper
Created struct value member variable (byte) main::henriette_id
Created struct value member variable (byte[$10]) main::henriette_name
Converted struct value to member variables (struct Person) main::henriette
Created struct value member variable (byte) print_person::person_id
Created struct value member variable (byte[$10]) print_person::person_name
Converted struct value to member variables (struct Person) print_person::person
Converted procedure struct value parameter to member unwinding (void()) print_person((byte) print_person::person_id , (byte[$10]) print_person::person_name)
Adding struct value list initializer (byte) main::jesper_id ← (number) 4
Adding struct value list initializer (byte[$10]) main::jesper_name ← (string) "jesper"
Converted procedure struct value parameter to member unwinding in call (void~) main::$0 ← call print_person (byte) main::jesper_id (byte[$10]) main::jesper_name
Adding struct value list initializer (byte) main::henriette_id ← (number) 7
Adding struct value list initializer (byte[$10]) main::henriette_name ← (string) "henriette"
Converted procedure struct value parameter to member unwinding in call (void~) main::$1 ← call print_person (byte) main::henriette_id (byte[$10]) main::henriette_name
Replacing struct member reference (struct Person) print_person::person.id with member unwinding reference (byte) print_person::person_id
Replacing struct member reference (struct Person) print_person::person.name with member unwinding reference (byte[$10]) print_person::person_name
Replacing struct member reference (struct Person) print_person::person.name with member unwinding reference (byte[$10]) print_person::person_name
Warning! Adding boolean cast to non-boolean condition *((byte[$10]) print_person::person_name + (byte) print_person::i)
Identified constant variable (byte) main::jesper_id
Identified constant variable (byte[$10]) main::jesper_name
Identified constant variable (byte) main::henriette_id
Identified constant variable (byte[$10]) main::henriette_name
Culled Empty Block (label) print_person::@4
Culled Empty Block (label) print_person::@5
Culled Empty Block (label) print_person::@6
CONTROL FLOW GRAPH SSA
@begin: scope:[] from
to:@1
2019-09-18 21:00:30 +00:00
(void()) main()
2019-09-13 21:29:42 +00:00
main: scope:[main] from @2
(byte) idx#18 ← phi( @2/(byte) idx#20 )
(byte) main::jesper_id#0 ← (number) 4
(byte[$10]) main::jesper_name#0 ← (const string) main::$2
(byte) print_person::person_id#0 ← (byte) main::jesper_id#0
(byte[$10]) print_person::person_name#0 ← (byte[$10]) main::jesper_name#0
call print_person
to:main::@1
main::@1: scope:[main] from main
(byte) idx#10 ← phi( main/(byte) idx#8 )
(byte) idx#0 ← (byte) idx#10
(byte) main::henriette_id#0 ← (number) 7
(byte[$10]) main::henriette_name#0 ← (const string) main::$3
(byte) print_person::person_id#1 ← (byte) main::henriette_id#0
(byte[$10]) print_person::person_name#1 ← (byte[$10]) main::henriette_name#0
call print_person
to:main::@2
main::@2: scope:[main] from main::@1
(byte) idx#11 ← phi( main::@1/(byte) idx#8 )
(byte) idx#1 ← (byte) idx#11
to:main::@return
main::@return: scope:[main] from main::@2
(byte) idx#12 ← phi( main::@2/(byte) idx#1 )
(byte) idx#2 ← (byte) idx#12
return
to:@return
@1: scope:[] from @begin
(byte*) SCREEN#0 ← ((byte*)) (number) $400
(byte) idx#3 ← (number) 0
(byte[]) DIGIT#0 ← (const string) $0
to:@2
2019-09-18 21:00:30 +00:00
(void()) print_person((byte) print_person::person_id , (byte[$10]) print_person::person_name)
2019-09-13 21:29:42 +00:00
print_person: scope:[print_person] from main main::@1
(byte[$10]) print_person::person_name#4 ← phi( main/(byte[$10]) print_person::person_name#0 main::@1/(byte[$10]) print_person::person_name#1 )
(byte) idx#13 ← phi( main/(byte) idx#18 main::@1/(byte) idx#0 )
(byte) print_person::person_id#2 ← phi( main/(byte) print_person::person_id#0 main::@1/(byte) print_person::person_id#1 )
*((byte*) SCREEN#0 + (byte) idx#13) ← *((byte[]) DIGIT#0 + (byte) print_person::person_id#2)
(byte) idx#4 ← ++ (byte) idx#13
*((byte*) SCREEN#0 + (byte) idx#4) ← (byte) ' '
(byte) idx#5 ← ++ (byte) idx#4
(byte) print_person::i#0 ← (number) 0
to:print_person::@1
print_person::@1: scope:[print_person] from print_person print_person::@2
(byte) idx#19 ← phi( print_person/(byte) idx#5 print_person::@2/(byte) idx#6 )
(byte) print_person::i#2 ← phi( print_person/(byte) print_person::i#0 print_person::@2/(byte) print_person::i#1 )
(byte[$10]) print_person::person_name#2 ← phi( print_person/(byte[$10]) print_person::person_name#4 print_person::@2/(byte[$10]) print_person::person_name#3 )
(bool~) print_person::$0 ← (number) 0 != *((byte[$10]) print_person::person_name#2 + (byte) print_person::i#2)
if((bool~) print_person::$0) goto print_person::@2
to:print_person::@3
print_person::@2: scope:[print_person] from print_person::@1
(byte) idx#14 ← phi( print_person::@1/(byte) idx#19 )
(byte) print_person::i#3 ← phi( print_person::@1/(byte) print_person::i#2 )
(byte[$10]) print_person::person_name#3 ← phi( print_person::@1/(byte[$10]) print_person::person_name#2 )
*((byte*) SCREEN#0 + (byte) idx#14) ← *((byte[$10]) print_person::person_name#3 + (byte) print_person::i#3)
(byte) idx#6 ← ++ (byte) idx#14
(byte) print_person::i#1 ← ++ (byte) print_person::i#3
to:print_person::@1
print_person::@3: scope:[print_person] from print_person::@1
(byte) idx#15 ← phi( print_person::@1/(byte) idx#19 )
*((byte*) SCREEN#0 + (byte) idx#15) ← (byte) ' '
(byte) idx#7 ← ++ (byte) idx#15
to:print_person::@return
print_person::@return: scope:[print_person] from print_person::@3
(byte) idx#16 ← phi( print_person::@3/(byte) idx#7 )
(byte) idx#8 ← (byte) idx#16
return
to:@return
@2: scope:[] from @1
(byte) idx#20 ← phi( @1/(byte) idx#3 )
call main
to:@3
@3: scope:[] from @2
(byte) idx#17 ← phi( @2/(byte) idx#2 )
(byte) idx#9 ← (byte) idx#17
to:@end
@end: scope:[] from @3
SYMBOL TABLE SSA
(const string) $0 = (string) "0123456789"
(label) @1
(label) @2
(label) @3
(label) @begin
(label) @end
(byte[]) DIGIT
(byte[]) DIGIT#0
(byte) Person::id
(byte[$10]) Person::name
(byte*) SCREEN
(byte*) SCREEN#0
(byte) idx
(byte) idx#0
(byte) idx#1
(byte) idx#10
(byte) idx#11
(byte) idx#12
(byte) idx#13
(byte) idx#14
(byte) idx#15
(byte) idx#16
(byte) idx#17
(byte) idx#18
(byte) idx#19
(byte) idx#2
(byte) idx#20
(byte) idx#3
(byte) idx#4
(byte) idx#5
(byte) idx#6
(byte) idx#7
(byte) idx#8
(byte) idx#9
(void()) main()
(const string) main::$2 = (string) "jesper"
(const string) main::$3 = (string) "henriette"
(label) main::@1
(label) main::@2
(label) main::@return
(byte) main::henriette_id
(byte) main::henriette_id#0
(byte[$10]) main::henriette_name
(byte[$10]) main::henriette_name#0
(byte) main::jesper_id
(byte) main::jesper_id#0
(byte[$10]) main::jesper_name
(byte[$10]) main::jesper_name#0
(void()) print_person((byte) print_person::person_id , (byte[$10]) print_person::person_name)
(bool~) print_person::$0
(label) print_person::@1
(label) print_person::@2
(label) print_person::@3
(label) print_person::@return
(byte) print_person::i
(byte) print_person::i#0
(byte) print_person::i#1
(byte) print_person::i#2
(byte) print_person::i#3
(struct Person) print_person::person
(byte) print_person::person_id
(byte) print_person::person_id#0
(byte) print_person::person_id#1
(byte) print_person::person_id#2
(byte[$10]) print_person::person_name
(byte[$10]) print_person::person_name#0
(byte[$10]) print_person::person_name#1
(byte[$10]) print_person::person_name#2
(byte[$10]) print_person::person_name#3
(byte[$10]) print_person::person_name#4
Adding number conversion cast (unumber) 4 in (byte) main::jesper_id#0 ← (number) 4
Adding number conversion cast (unumber) 7 in (byte) main::henriette_id#0 ← (number) 7
Adding number conversion cast (unumber) 0 in (byte) idx#3 ← (number) 0
Adding number conversion cast (unumber) 0 in (byte) print_person::i#0 ← (number) 0
Adding number conversion cast (unumber) 0 in (bool~) print_person::$0 ← (number) 0 != *((byte[$10]) print_person::person_name#2 + (byte) print_person::i#2)
Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast (byte) main::jesper_id#0 ← (unumber)(number) 4
Inlining cast (byte) main::henriette_id#0 ← (unumber)(number) 7
Inlining cast (byte*) SCREEN#0 ← (byte*)(number) $400
Inlining cast (byte) idx#3 ← (unumber)(number) 0
Inlining cast (byte) print_person::i#0 ← (unumber)(number) 0
Successful SSA optimization Pass2InlineCast
Simplifying constant integer cast 4
Simplifying constant integer cast 7
Simplifying constant pointer cast (byte*) 1024
Simplifying constant integer cast 0
Simplifying constant integer cast 0
Simplifying constant integer cast 0
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) 4
Finalized unsigned number type (byte) 7
Finalized unsigned number type (byte) 0
Finalized unsigned number type (byte) 0
Finalized unsigned number type (byte) 0
Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias (byte) idx#0 = (byte) idx#10
Alias (byte) idx#1 = (byte) idx#11 (byte) idx#12 (byte) idx#2
Alias (byte[$10]) print_person::person_name#2 = (byte[$10]) print_person::person_name#3
Alias (byte) print_person::i#2 = (byte) print_person::i#3
Alias (byte) idx#14 = (byte) idx#19 (byte) idx#15
Alias (byte) idx#16 = (byte) idx#7 (byte) idx#8
Alias (byte) idx#20 = (byte) idx#3
Alias (byte) idx#17 = (byte) idx#9
Successful SSA optimization Pass2AliasElimination
Identical Phi Values (byte) idx#18 (byte) idx#20
Identical Phi Values (byte) idx#0 (byte) idx#16
Identical Phi Values (byte) idx#1 (byte) idx#16
Identical Phi Values (byte[$10]) print_person::person_name#2 (byte[$10]) print_person::person_name#4
Identical Phi Values (byte) idx#17 (byte) idx#1
Successful SSA optimization Pass2IdenticalPhiElimination
Simple Condition (bool~) print_person::$0 [29] if((byte) 0!=*((byte[$10]) print_person::person_name#4 + (byte) print_person::i#2)) goto print_person::@2
Successful SSA optimization Pass2ConditionalJumpSimplification
Constant (const byte) main::jesper_id#0 = 4
Constant (const byte[$10]) main::jesper_name#0 = main::$2
Constant (const byte) main::henriette_id#0 = 7
Constant (const byte[$10]) main::henriette_name#0 = main::$3
Constant (const byte*) SCREEN#0 = (byte*) 1024
Constant (const byte) idx#20 = 0
Constant (const byte[]) DIGIT#0 = $0
Constant (const byte) print_person::i#0 = 0
Successful SSA optimization Pass2ConstantIdentification
Constant (const byte) print_person::person_id#0 = main::jesper_id#0
Constant (const byte[$10]) print_person::person_name#0 = main::jesper_name#0
Constant (const byte) print_person::person_id#1 = main::henriette_id#0
Constant (const byte[$10]) print_person::person_name#1 = main::henriette_name#0
Successful SSA optimization Pass2ConstantIdentification
Inlining constant with var siblings (const byte) print_person::i#0
Inlining constant with var siblings (const byte) print_person::person_id#0
Inlining constant with var siblings (const byte[$10]) print_person::person_name#0
Inlining constant with var siblings (const byte) print_person::person_id#1
Inlining constant with var siblings (const byte[$10]) print_person::person_name#1
Inlining constant with var siblings (const byte) idx#20
Constant inlined idx#20 = (byte) 0
Constant inlined print_person::person_id#1 = (const byte) main::henriette_id#0
Constant inlined print_person::person_id#0 = (const byte) main::jesper_id#0
Constant inlined main::$2 = (const byte[$10]) main::jesper_name#0
Constant inlined print_person::i#0 = (byte) 0
Constant inlined print_person::person_name#1 = (const byte[$10]) main::henriette_name#0
Constant inlined main::$3 = (const byte[$10]) main::henriette_name#0
Constant inlined $0 = (const byte[]) DIGIT#0
Constant inlined print_person::person_name#0 = (const byte[$10]) main::jesper_name#0
Successful SSA optimization Pass2ConstantInlining
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 @3
Adding NOP phi() at start of @end
Adding NOP phi() at start of main
Adding NOP phi() at start of main::@2
CALL GRAPH
Calls in [] to main:3
Calls in [main] to print_person:7 print_person:9
Created 5 initial phi equivalence classes
Coalesced [8] idx#21 ← idx#16
Coalesced [17] idx#22 ← idx#5
Coalesced [26] print_person::i#4 ← print_person::i#1
Coalesced [27] idx#23 ← idx#6
Coalesced down to 5 phi equivalence classes
Culled Empty Block (label) @1
Culled Empty Block (label) @3
Culled Empty Block (label) main::@2
Renumbering block @2 to @1
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1
Adding NOP phi() at start of @end
Adding NOP phi() at start of main
Adding NOP phi() at start of main::@1
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()
2019-09-18 21:00:30 +00:00
(void()) main()
2019-09-13 21:29:42 +00:00
main: scope:[main] from @1
[4] phi()
[5] call print_person
to:main::@1
main::@1: scope:[main] from main
[6] phi()
[7] call print_person
to:main::@return
main::@return: scope:[main] from main::@1
[8] return
to:@return
2019-09-18 21:00:30 +00:00
(void()) print_person((byte) print_person::person_id , (byte[$10]) print_person::person_name)
2019-09-13 21:29:42 +00:00
print_person: scope:[print_person] from main main::@1
[9] (byte[$10]) print_person::person_name#4 ← phi( main/(const byte[$10]) main::jesper_name#0 main::@1/(const byte[$10]) main::henriette_name#0 )
[9] (byte) idx#13 ← phi( main/(byte) 0 main::@1/(byte) idx#16 )
[9] (byte) print_person::person_id#2 ← phi( main/(const byte) main::jesper_id#0 main::@1/(const byte) main::henriette_id#0 )
[10] *((const byte*) SCREEN#0 + (byte) idx#13) ← *((const byte[]) DIGIT#0 + (byte) print_person::person_id#2)
[11] (byte) idx#4 ← ++ (byte) idx#13
[12] *((const byte*) SCREEN#0 + (byte) idx#4) ← (byte) ' '
[13] (byte) idx#5 ← ++ (byte) idx#4
to:print_person::@1
print_person::@1: scope:[print_person] from print_person print_person::@2
[14] (byte) idx#14 ← phi( print_person/(byte) idx#5 print_person::@2/(byte) idx#6 )
[14] (byte) print_person::i#2 ← phi( print_person/(byte) 0 print_person::@2/(byte) print_person::i#1 )
[15] if((byte) 0!=*((byte[$10]) print_person::person_name#4 + (byte) print_person::i#2)) goto print_person::@2
to:print_person::@3
print_person::@3: scope:[print_person] from print_person::@1
[16] *((const byte*) SCREEN#0 + (byte) idx#14) ← (byte) ' '
[17] (byte) idx#16 ← ++ (byte) idx#14
to:print_person::@return
print_person::@return: scope:[print_person] from print_person::@3
[18] return
to:@return
print_person::@2: scope:[print_person] from print_person::@1
[19] *((const byte*) SCREEN#0 + (byte) idx#14) ← *((byte[$10]) print_person::person_name#4 + (byte) print_person::i#2)
[20] (byte) idx#6 ← ++ (byte) idx#14
[21] (byte) print_person::i#1 ← ++ (byte) print_person::i#2
to:print_person::@1
VARIABLE REGISTER WEIGHTS
(byte[]) DIGIT
(byte) Person::id
(byte[$10]) Person::name
(byte*) SCREEN
(byte) idx
(byte) idx#13 3.0
(byte) idx#14 9.75
(byte) idx#16 1.0
(byte) idx#4 3.0
(byte) idx#5 4.0
(byte) idx#6 11.0
(void()) main()
(byte) main::henriette_id
(byte[$10]) main::henriette_name
(byte) main::jesper_id
(byte[$10]) main::jesper_name
(void()) print_person((byte) print_person::person_id , (byte[$10]) print_person::person_name)
(byte) print_person::i
(byte) print_person::i#1 22.0
(byte) print_person::i#2 11.0
(struct Person) print_person::person
(byte) print_person::person_id
(byte) print_person::person_id#2 2.0
(byte[$10]) print_person::person_name
(byte[$10]) print_person::person_name#4 2.2
Initial phi equivalence classes
[ print_person::person_id#2 ]
[ idx#13 idx#16 ]
[ print_person::person_name#4 ]
[ print_person::i#2 print_person::i#1 ]
[ idx#14 idx#5 idx#6 ]
Added variable idx#4 to zero page equivalence class [ idx#4 ]
Complete equivalence classes
[ print_person::person_id#2 ]
[ idx#13 idx#16 ]
[ print_person::person_name#4 ]
[ print_person::i#2 print_person::i#1 ]
[ idx#14 idx#5 idx#6 ]
[ idx#4 ]
Allocated zp ZP_BYTE:2 [ print_person::person_id#2 ]
Allocated zp ZP_BYTE:3 [ idx#13 idx#16 ]
Allocated zp ZP_WORD:4 [ print_person::person_name#4 ]
Allocated zp ZP_BYTE:6 [ print_person::i#2 print_person::i#1 ]
Allocated zp ZP_BYTE:7 [ idx#14 idx#5 idx#6 ]
Allocated zp ZP_BYTE:8 [ idx#4 ]
INITIAL ASM
Target platform is c64basic / MOS6502X
// File Comments
// Example of a struct containing an array
// Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
.label idx = 8
.label idx_5 = 7
.label idx_6 = 7
.label idx_13 = 3
.label idx_14 = 7
.label idx_16 = 3
// @begin
bbegin:
// [1] phi from @begin to @1 [phi:@begin->@1]
b1_from_bbegin:
jmp b1
// @1
b1:
// [2] call main
// [4] phi from @1 to main [phi:@1->main]
main_from_b1:
jsr main
// [3] phi from @1 to @end [phi:@1->@end]
bend_from_b1:
jmp bend
// @end
bend:
// main
main: {
.const jesper_id = 4
.const henriette_id = 7
// [5] call print_person
// [9] phi from main to print_person [phi:main->print_person]
print_person_from_main:
// [9] phi (byte[$10]) print_person::person_name#4 = (const byte[$10]) main::jesper_name#0 [phi:main->print_person#0] -- pbuz1=pbuc1
lda #<jesper_name
sta.z print_person.person_name
lda #>jesper_name
sta.z print_person.person_name+1
// [9] phi (byte) idx#13 = (byte) 0 [phi:main->print_person#1] -- vbuz1=vbuc1
lda #0
sta.z idx_13
// [9] phi (byte) print_person::person_id#2 = (const byte) main::jesper_id#0 [phi:main->print_person#2] -- vbuz1=vbuc1
lda #jesper_id
sta.z print_person.person_id
jsr print_person
// [6] phi from main to main::@1 [phi:main->main::@1]
b1_from_main:
jmp b1
// main::@1
b1:
// [7] call print_person
// [9] phi from main::@1 to print_person [phi:main::@1->print_person]
print_person_from_b1:
// [9] phi (byte[$10]) print_person::person_name#4 = (const byte[$10]) main::henriette_name#0 [phi:main::@1->print_person#0] -- pbuz1=pbuc1
lda #<henriette_name
sta.z print_person.person_name
lda #>henriette_name
sta.z print_person.person_name+1
// [9] phi (byte) idx#13 = (byte) idx#16 [phi:main::@1->print_person#1] -- register_copy
// [9] phi (byte) print_person::person_id#2 = (const byte) main::henriette_id#0 [phi:main::@1->print_person#2] -- vbuz1=vbuc1
lda #henriette_id
sta.z print_person.person_id
jsr print_person
jmp breturn
// main::@return
breturn:
// [8] return
rts
jesper_name: .text "jesper"
.byte 0
.fill 9, 0
henriette_name: .text "henriette"
.byte 0
.fill 6, 0
}
// print_person
// print_person(byte zeropage(2) person_id, byte[$10] zeropage(4) person_name)
print_person: {
.label i = 6
.label person_id = 2
.label person_name = 4
// [10] *((const byte*) SCREEN#0 + (byte) idx#13) ← *((const byte[]) DIGIT#0 + (byte) print_person::person_id#2) -- pbuc1_derefidx_vbuz1=pbuc2_derefidx_vbuz2
ldy.z person_id
lda DIGIT,y
ldy.z idx_13
sta SCREEN,y
// [11] (byte) idx#4 ← ++ (byte) idx#13 -- vbuz1=_inc_vbuz2
ldy.z idx_13
iny
sty.z idx
// [12] *((const byte*) SCREEN#0 + (byte) idx#4) ← (byte) ' ' -- pbuc1_derefidx_vbuz1=vbuc2
lda #' '
ldy.z idx
sta SCREEN,y
// [13] (byte) idx#5 ← ++ (byte) idx#4 -- vbuz1=_inc_vbuz2
ldy.z idx
iny
sty.z idx_5
// [14] phi from print_person to print_person::@1 [phi:print_person->print_person::@1]
b1_from_print_person:
// [14] phi (byte) idx#14 = (byte) idx#5 [phi:print_person->print_person::@1#0] -- register_copy
// [14] phi (byte) print_person::i#2 = (byte) 0 [phi:print_person->print_person::@1#1] -- vbuz1=vbuc1
lda #0
sta.z i
jmp b1
// print_person::@1
b1:
// [15] if((byte) 0!=*((byte[$10]) print_person::person_name#4 + (byte) print_person::i#2)) goto print_person::@2 -- vbuc1_neq_pbuz1_derefidx_vbuz2_then_la1
ldy.z i
lda (person_name),y
cmp #0
bne b2
jmp b3
// print_person::@3
b3:
// [16] *((const byte*) SCREEN#0 + (byte) idx#14) ← (byte) ' ' -- pbuc1_derefidx_vbuz1=vbuc2
lda #' '
ldy.z idx_14
sta SCREEN,y
// [17] (byte) idx#16 ← ++ (byte) idx#14 -- vbuz1=_inc_vbuz2
ldy.z idx_14
iny
sty.z idx_16
jmp breturn
// print_person::@return
breturn:
// [18] return
rts
// print_person::@2
b2:
// [19] *((const byte*) SCREEN#0 + (byte) idx#14) ← *((byte[$10]) print_person::person_name#4 + (byte) print_person::i#2) -- pbuc1_derefidx_vbuz1=pbuz2_derefidx_vbuz3
ldx.z idx_14
ldy.z i
lda (person_name),y
sta SCREEN,x
// [20] (byte) idx#6 ← ++ (byte) idx#14 -- vbuz1=_inc_vbuz1
inc.z idx_6
// [21] (byte) print_person::i#1 ← ++ (byte) print_person::i#2 -- vbuz1=_inc_vbuz1
inc.z i
// [14] phi from print_person::@2 to print_person::@1 [phi:print_person::@2->print_person::@1]
b1_from_b2:
// [14] phi (byte) idx#14 = (byte) idx#6 [phi:print_person::@2->print_person::@1#0] -- register_copy
// [14] phi (byte) print_person::i#2 = (byte) print_person::i#1 [phi:print_person::@2->print_person::@1#1] -- register_copy
jmp b1
}
// File Data
DIGIT: .text "0123456789"
.byte 0
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [10] *((const byte*) SCREEN#0 + (byte) idx#13) ← *((const byte[]) DIGIT#0 + (byte) print_person::person_id#2) [ idx#13 print_person::person_name#4 ] ( main:2::print_person:5 [ idx#13 print_person::person_name#4 ] main:2::print_person:7 [ idx#13 print_person::person_name#4 ] ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:3 [ idx#13 idx#16 ]
Statement [12] *((const byte*) SCREEN#0 + (byte) idx#4) ← (byte) ' ' [ print_person::person_name#4 idx#4 ] ( main:2::print_person:5 [ print_person::person_name#4 idx#4 ] main:2::print_person:7 [ print_person::person_name#4 idx#4 ] ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:8 [ idx#4 ]
Statement [15] if((byte) 0!=*((byte[$10]) print_person::person_name#4 + (byte) print_person::i#2)) goto print_person::@2 [ print_person::person_name#4 print_person::i#2 idx#14 ] ( main:2::print_person:5 [ print_person::person_name#4 print_person::i#2 idx#14 ] main:2::print_person:7 [ print_person::person_name#4 print_person::i#2 idx#14 ] ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:6 [ print_person::i#2 print_person::i#1 ]
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:7 [ idx#14 idx#5 idx#6 ]
Statement [16] *((const byte*) SCREEN#0 + (byte) idx#14) ← (byte) ' ' [ idx#14 ] ( main:2::print_person:5 [ idx#14 ] main:2::print_person:7 [ idx#14 ] ) always clobbers reg byte a
Statement [19] *((const byte*) SCREEN#0 + (byte) idx#14) ← *((byte[$10]) print_person::person_name#4 + (byte) print_person::i#2) [ print_person::person_name#4 print_person::i#2 idx#14 ] ( main:2::print_person:5 [ print_person::person_name#4 print_person::i#2 idx#14 ] main:2::print_person:7 [ print_person::person_name#4 print_person::i#2 idx#14 ] ) always clobbers reg byte a
Statement [10] *((const byte*) SCREEN#0 + (byte) idx#13) ← *((const byte[]) DIGIT#0 + (byte) print_person::person_id#2) [ idx#13 print_person::person_name#4 ] ( main:2::print_person:5 [ idx#13 print_person::person_name#4 ] main:2::print_person:7 [ idx#13 print_person::person_name#4 ] ) always clobbers reg byte a
Statement [12] *((const byte*) SCREEN#0 + (byte) idx#4) ← (byte) ' ' [ print_person::person_name#4 idx#4 ] ( main:2::print_person:5 [ print_person::person_name#4 idx#4 ] main:2::print_person:7 [ print_person::person_name#4 idx#4 ] ) always clobbers reg byte a
Statement [15] if((byte) 0!=*((byte[$10]) print_person::person_name#4 + (byte) print_person::i#2)) goto print_person::@2 [ print_person::person_name#4 print_person::i#2 idx#14 ] ( main:2::print_person:5 [ print_person::person_name#4 print_person::i#2 idx#14 ] main:2::print_person:7 [ print_person::person_name#4 print_person::i#2 idx#14 ] ) always clobbers reg byte a
Statement [16] *((const byte*) SCREEN#0 + (byte) idx#14) ← (byte) ' ' [ idx#14 ] ( main:2::print_person:5 [ idx#14 ] main:2::print_person:7 [ idx#14 ] ) always clobbers reg byte a
Statement [19] *((const byte*) SCREEN#0 + (byte) idx#14) ← *((byte[$10]) print_person::person_name#4 + (byte) print_person::i#2) [ print_person::person_name#4 print_person::i#2 idx#14 ] ( main:2::print_person:5 [ print_person::person_name#4 print_person::i#2 idx#14 ] main:2::print_person:7 [ print_person::person_name#4 print_person::i#2 idx#14 ] ) always clobbers reg byte a
Potential registers zp ZP_BYTE:2 [ print_person::person_id#2 ] : zp ZP_BYTE:2 , reg byte a , reg byte x , reg byte y ,
Potential registers zp ZP_BYTE:3 [ idx#13 idx#16 ] : zp ZP_BYTE:3 , reg byte x , reg byte y ,
Potential registers zp ZP_WORD:4 [ print_person::person_name#4 ] : zp ZP_WORD:4 ,
Potential registers zp ZP_BYTE:6 [ print_person::i#2 print_person::i#1 ] : zp ZP_BYTE:6 , reg byte x , reg byte y ,
Potential registers zp ZP_BYTE:7 [ idx#14 idx#5 idx#6 ] : zp ZP_BYTE:7 , reg byte x , reg byte y ,
Potential registers zp ZP_BYTE:8 [ idx#4 ] : zp ZP_BYTE:8 , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES
Uplift Scope [print_person] 33: zp ZP_BYTE:6 [ print_person::i#2 print_person::i#1 ] 2.2: zp ZP_WORD:4 [ print_person::person_name#4 ] 2: zp ZP_BYTE:2 [ print_person::person_id#2 ]
Uplift Scope [] 24.75: zp ZP_BYTE:7 [ idx#14 idx#5 idx#6 ] 4: zp ZP_BYTE:3 [ idx#13 idx#16 ] 3: zp ZP_BYTE:8 [ idx#4 ]
Uplift Scope [Person]
Uplift Scope [main]
Uplifting [print_person] best 545 combination reg byte y [ print_person::i#2 print_person::i#1 ] zp ZP_WORD:4 [ print_person::person_name#4 ] reg byte x [ print_person::person_id#2 ]
Uplifting [] best 463 combination reg byte x [ idx#14 idx#5 idx#6 ] reg byte y [ idx#13 idx#16 ] reg byte x [ idx#4 ]
Uplifting [Person] best 463 combination
Uplifting [main] best 463 combination
Allocated (was zp ZP_WORD:4) zp ZP_WORD:2 [ print_person::person_name#4 ]
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Example of a struct containing an array
// Upstart
.pc = $801 "Basic"
:BasicUpstart(bbegin)
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
// @begin
bbegin:
// [1] phi from @begin to @1 [phi:@begin->@1]
b1_from_bbegin:
jmp b1
// @1
b1:
// [2] call main
// [4] phi from @1 to main [phi:@1->main]
main_from_b1:
jsr main
// [3] phi from @1 to @end [phi:@1->@end]
bend_from_b1:
jmp bend
// @end
bend:
// main
main: {
.const jesper_id = 4
.const henriette_id = 7
// [5] call print_person
// [9] phi from main to print_person [phi:main->print_person]
print_person_from_main:
// [9] phi (byte[$10]) print_person::person_name#4 = (const byte[$10]) main::jesper_name#0 [phi:main->print_person#0] -- pbuz1=pbuc1
lda #<jesper_name
sta.z print_person.person_name
lda #>jesper_name
sta.z print_person.person_name+1
// [9] phi (byte) idx#13 = (byte) 0 [phi:main->print_person#1] -- vbuyy=vbuc1
ldy #0
// [9] phi (byte) print_person::person_id#2 = (const byte) main::jesper_id#0 [phi:main->print_person#2] -- vbuxx=vbuc1
ldx #jesper_id
jsr print_person
// [6] phi from main to main::@1 [phi:main->main::@1]
b1_from_main:
jmp b1
// main::@1
b1:
// [7] call print_person
// [9] phi from main::@1 to print_person [phi:main::@1->print_person]
print_person_from_b1:
// [9] phi (byte[$10]) print_person::person_name#4 = (const byte[$10]) main::henriette_name#0 [phi:main::@1->print_person#0] -- pbuz1=pbuc1
lda #<henriette_name
sta.z print_person.person_name
lda #>henriette_name
sta.z print_person.person_name+1
// [9] phi (byte) idx#13 = (byte) idx#16 [phi:main::@1->print_person#1] -- register_copy
// [9] phi (byte) print_person::person_id#2 = (const byte) main::henriette_id#0 [phi:main::@1->print_person#2] -- vbuxx=vbuc1
ldx #henriette_id
jsr print_person
jmp breturn
// main::@return
breturn:
// [8] return
rts
jesper_name: .text "jesper"
.byte 0
.fill 9, 0
henriette_name: .text "henriette"
.byte 0
.fill 6, 0
}
// print_person
// print_person(byte register(X) person_id, byte[$10] zeropage(2) person_name)
print_person: {
.label person_name = 2
// [10] *((const byte*) SCREEN#0 + (byte) idx#13) ← *((const byte[]) DIGIT#0 + (byte) print_person::person_id#2) -- pbuc1_derefidx_vbuyy=pbuc2_derefidx_vbuxx
lda DIGIT,x
sta SCREEN,y
// [11] (byte) idx#4 ← ++ (byte) idx#13 -- vbuxx=_inc_vbuyy
tya
tax
inx
// [12] *((const byte*) SCREEN#0 + (byte) idx#4) ← (byte) ' ' -- pbuc1_derefidx_vbuxx=vbuc2
lda #' '
sta SCREEN,x
// [13] (byte) idx#5 ← ++ (byte) idx#4 -- vbuxx=_inc_vbuxx
inx
// [14] phi from print_person to print_person::@1 [phi:print_person->print_person::@1]
b1_from_print_person:
// [14] phi (byte) idx#14 = (byte) idx#5 [phi:print_person->print_person::@1#0] -- register_copy
// [14] phi (byte) print_person::i#2 = (byte) 0 [phi:print_person->print_person::@1#1] -- vbuyy=vbuc1
ldy #0
jmp b1
// print_person::@1
b1:
// [15] if((byte) 0!=*((byte[$10]) print_person::person_name#4 + (byte) print_person::i#2)) goto print_person::@2 -- vbuc1_neq_pbuz1_derefidx_vbuyy_then_la1
lda (person_name),y
cmp #0
bne b2
jmp b3
// print_person::@3
b3:
// [16] *((const byte*) SCREEN#0 + (byte) idx#14) ← (byte) ' ' -- pbuc1_derefidx_vbuxx=vbuc2
lda #' '
sta SCREEN,x
// [17] (byte) idx#16 ← ++ (byte) idx#14 -- vbuyy=_inc_vbuxx
txa
tay
iny
jmp breturn
// print_person::@return
breturn:
// [18] return
rts
// print_person::@2
b2:
// [19] *((const byte*) SCREEN#0 + (byte) idx#14) ← *((byte[$10]) print_person::person_name#4 + (byte) print_person::i#2) -- pbuc1_derefidx_vbuxx=pbuz1_derefidx_vbuyy
lda (person_name),y
sta SCREEN,x
// [20] (byte) idx#6 ← ++ (byte) idx#14 -- vbuxx=_inc_vbuxx
inx
// [21] (byte) print_person::i#1 ← ++ (byte) print_person::i#2 -- vbuyy=_inc_vbuyy
iny
// [14] phi from print_person::@2 to print_person::@1 [phi:print_person::@2->print_person::@1]
b1_from_b2:
// [14] phi (byte) idx#14 = (byte) idx#6 [phi:print_person::@2->print_person::@1#0] -- register_copy
// [14] phi (byte) print_person::i#2 = (byte) print_person::i#1 [phi:print_person::@2->print_person::@1#1] -- register_copy
jmp b1
}
// File Data
DIGIT: .text "0123456789"
.byte 0
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp b1
Removing instruction jmp bend
Removing instruction jmp b1
Removing instruction jmp breturn
Removing instruction jmp b1
Removing instruction jmp b3
Removing instruction jmp breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction b1_from_bbegin:
Removing instruction b1:
Removing instruction main_from_b1:
Removing instruction bend_from_b1:
Removing instruction b1_from_main:
Removing instruction print_person_from_b1:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction bend:
Removing instruction print_person_from_main:
Removing instruction b1:
Removing instruction breturn:
Removing instruction b1_from_print_person:
Removing instruction b3:
Removing instruction breturn:
Removing instruction b1_from_b2:
Succesful ASM optimization Pass5UnusedLabelElimination
Updating BasicUpstart to call main directly
Removing instruction jsr main
Succesful ASM optimization Pass5SkipBegin
Removing instruction bbegin:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
(label) @1
(label) @begin
(label) @end
(byte[]) DIGIT
(const byte[]) DIGIT#0 DIGIT = (string) "0123456789"
(byte) Person::id
(byte[$10]) Person::name
(byte*) SCREEN
(const byte*) SCREEN#0 SCREEN = (byte*) 1024
(byte) idx
(byte) idx#13 reg byte y 3.0
(byte) idx#14 reg byte x 9.75
(byte) idx#16 reg byte y 1.0
(byte) idx#4 reg byte x 3.0
(byte) idx#5 reg byte x 4.0
(byte) idx#6 reg byte x 11.0
(void()) main()
(label) main::@1
(label) main::@return
(byte) main::henriette_id
(const byte) main::henriette_id#0 henriette_id = (byte) 7
(byte[$10]) main::henriette_name
(const byte[$10]) main::henriette_name#0 henriette_name = (string) "henriette"
(byte) main::jesper_id
(const byte) main::jesper_id#0 jesper_id = (byte) 4
(byte[$10]) main::jesper_name
(const byte[$10]) main::jesper_name#0 jesper_name = (string) "jesper"
(void()) print_person((byte) print_person::person_id , (byte[$10]) print_person::person_name)
(label) print_person::@1
(label) print_person::@2
(label) print_person::@3
(label) print_person::@return
(byte) print_person::i
(byte) print_person::i#1 reg byte y 22.0
(byte) print_person::i#2 reg byte y 11.0
(struct Person) print_person::person
(byte) print_person::person_id
(byte) print_person::person_id#2 reg byte x 2.0
(byte[$10]) print_person::person_name
(byte[$10]) print_person::person_name#4 person_name zp ZP_WORD:2 2.2
reg byte x [ print_person::person_id#2 ]
reg byte y [ idx#13 idx#16 ]
zp ZP_WORD:2 [ print_person::person_name#4 ]
reg byte y [ print_person::i#2 print_person::i#1 ]
reg byte x [ idx#14 idx#5 idx#6 ]
reg byte x [ idx#4 ]
FINAL ASSEMBLER
Score: 382
// File Comments
// Example of a struct containing an array
// Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
// @begin
// [1] phi from @begin to @1 [phi:@begin->@1]
// @1
// [2] call main
// [4] phi from @1 to main [phi:@1->main]
// [3] phi from @1 to @end [phi:@1->@end]
// @end
// main
main: {
.const jesper_id = 4
.const henriette_id = 7
// print_person(jesper)
// [5] call print_person
// [9] phi from main to print_person [phi:main->print_person]
// [9] phi (byte[$10]) print_person::person_name#4 = (const byte[$10]) main::jesper_name#0 [phi:main->print_person#0] -- pbuz1=pbuc1
lda #<jesper_name
sta.z print_person.person_name
lda #>jesper_name
sta.z print_person.person_name+1
// [9] phi (byte) idx#13 = (byte) 0 [phi:main->print_person#1] -- vbuyy=vbuc1
ldy #0
// [9] phi (byte) print_person::person_id#2 = (const byte) main::jesper_id#0 [phi:main->print_person#2] -- vbuxx=vbuc1
ldx #jesper_id
jsr print_person
// [6] phi from main to main::@1 [phi:main->main::@1]
// main::@1
// print_person(henriette)
// [7] call print_person
// [9] phi from main::@1 to print_person [phi:main::@1->print_person]
// [9] phi (byte[$10]) print_person::person_name#4 = (const byte[$10]) main::henriette_name#0 [phi:main::@1->print_person#0] -- pbuz1=pbuc1
lda #<henriette_name
sta.z print_person.person_name
lda #>henriette_name
sta.z print_person.person_name+1
// [9] phi (byte) idx#13 = (byte) idx#16 [phi:main::@1->print_person#1] -- register_copy
// [9] phi (byte) print_person::person_id#2 = (const byte) main::henriette_id#0 [phi:main::@1->print_person#2] -- vbuxx=vbuc1
ldx #henriette_id
jsr print_person
// main::@return
// }
// [8] return
rts
jesper_name: .text "jesper"
.byte 0
.fill 9, 0
henriette_name: .text "henriette"
.byte 0
.fill 6, 0
}
// print_person
// print_person(byte register(X) person_id, byte[$10] zeropage(2) person_name)
print_person: {
.label person_name = 2
// SCREEN[idx++] = DIGIT[person.id]
// [10] *((const byte*) SCREEN#0 + (byte) idx#13) ← *((const byte[]) DIGIT#0 + (byte) print_person::person_id#2) -- pbuc1_derefidx_vbuyy=pbuc2_derefidx_vbuxx
lda DIGIT,x
sta SCREEN,y
// SCREEN[idx++] = DIGIT[person.id];
// [11] (byte) idx#4 ← ++ (byte) idx#13 -- vbuxx=_inc_vbuyy
tya
tax
inx
// SCREEN[idx++] = ' '
// [12] *((const byte*) SCREEN#0 + (byte) idx#4) ← (byte) ' ' -- pbuc1_derefidx_vbuxx=vbuc2
lda #' '
sta SCREEN,x
// SCREEN[idx++] = ' ';
// [13] (byte) idx#5 ← ++ (byte) idx#4 -- vbuxx=_inc_vbuxx
inx
// [14] phi from print_person to print_person::@1 [phi:print_person->print_person::@1]
// [14] phi (byte) idx#14 = (byte) idx#5 [phi:print_person->print_person::@1#0] -- register_copy
// [14] phi (byte) print_person::i#2 = (byte) 0 [phi:print_person->print_person::@1#1] -- vbuyy=vbuc1
ldy #0
// print_person::@1
b1:
// for(byte i=0; person.name[i]; i++)
// [15] if((byte) 0!=*((byte[$10]) print_person::person_name#4 + (byte) print_person::i#2)) goto print_person::@2 -- vbuc1_neq_pbuz1_derefidx_vbuyy_then_la1
lda (person_name),y
cmp #0
bne b2
// print_person::@3
// SCREEN[idx++] = ' '
// [16] *((const byte*) SCREEN#0 + (byte) idx#14) ← (byte) ' ' -- pbuc1_derefidx_vbuxx=vbuc2
lda #' '
sta SCREEN,x
// SCREEN[idx++] = ' ';
// [17] (byte) idx#16 ← ++ (byte) idx#14 -- vbuyy=_inc_vbuxx
txa
tay
iny
// print_person::@return
// }
// [18] return
rts
// print_person::@2
b2:
// SCREEN[idx++] = person.name[i]
// [19] *((const byte*) SCREEN#0 + (byte) idx#14) ← *((byte[$10]) print_person::person_name#4 + (byte) print_person::i#2) -- pbuc1_derefidx_vbuxx=pbuz1_derefidx_vbuyy
lda (person_name),y
sta SCREEN,x
// SCREEN[idx++] = person.name[i];
// [20] (byte) idx#6 ← ++ (byte) idx#14 -- vbuxx=_inc_vbuxx
inx
// for(byte i=0; person.name[i]; i++)
// [21] (byte) print_person::i#1 ← ++ (byte) print_person::i#2 -- vbuyy=_inc_vbuyy
iny
// [14] phi from print_person::@2 to print_person::@1 [phi:print_person::@2->print_person::@1]
// [14] phi (byte) idx#14 = (byte) idx#6 [phi:print_person::@2->print_person::@1#0] -- register_copy
// [14] phi (byte) print_person::i#2 = (byte) print_person::i#1 [phi:print_person::@2->print_person::@1#1] -- register_copy
jmp b1
}
// File Data
DIGIT: .text "0123456789"
.byte 0