Culled Empty Block (label) malloc::@1 CONTROL FLOW GRAPH SSA @begin: scope:[] from (byte*) SCREEN ← ((byte*)) (number) $400 to:@1 (void()) main() main: scope:[main] from @2 (byte*) heap_head#13 ← phi( @2/(byte*) heap_head#14 ) call malloc (void*) malloc::return#0 ← (void*) malloc::return#3 to:main::@1 main::@1: scope:[main] from main (byte*) heap_head#7 ← phi( main/(byte*) heap_head#5 ) (void*) malloc::return#4 ← phi( main/(void*) malloc::return#0 ) (void*~) main::$0 ← (void*) malloc::return#4 (byte*) heap_head#0 ← (byte*) heap_head#7 (byte*) main::buf1#0 ← ((byte*)) (void*~) main::$0 call malloc (void*) malloc::return#1 ← (void*) malloc::return#3 to:main::@2 main::@2: scope:[main] from main::@1 (byte*) main::buf1#1 ← phi( main::@1/(byte*) main::buf1#0 ) (byte*) heap_head#8 ← phi( main::@1/(byte*) heap_head#5 ) (void*) malloc::return#5 ← phi( main::@1/(void*) malloc::return#1 ) (void*~) main::$1 ← (void*) malloc::return#5 (byte*) heap_head#1 ← (byte*) heap_head#8 (byte*) main::buf2#0 ← ((byte*)) (void*~) main::$1 *((byte*) main::buf1#1) ← (byte) 'a' *((byte*) main::buf2#0) ← (byte) 'b' *((byte*) SCREEN + (number) 0) ← *((byte*) main::buf1#1) *((byte*) SCREEN + (number) 1) ← *((byte*) main::buf2#0) to:main::@return main::@return: scope:[main] from main::@2 (byte*) heap_head#9 ← phi( main::@2/(byte*) heap_head#1 ) (byte*) heap_head#2 ← (byte*) heap_head#9 return to:@return @1: scope:[] from @begin (byte*) heap_head#3 ← ((byte*)) (number) $c000 to:@2 (void*()) malloc() malloc: scope:[malloc] from main main::@1 (byte*) heap_head#10 ← phi( main/(byte*) heap_head#13 main::@1/(byte*) heap_head#0 ) (byte*) heap_head#4 ← ++ (byte*) heap_head#10 (void*) malloc::return#2 ← ((void*)) (byte*) heap_head#4 to:malloc::@return malloc::@return: scope:[malloc] from malloc (byte*) heap_head#11 ← phi( malloc/(byte*) heap_head#4 ) (void*) malloc::return#6 ← phi( malloc/(void*) malloc::return#2 ) (void*) malloc::return#3 ← (void*) malloc::return#6 (byte*) heap_head#5 ← (byte*) heap_head#11 return to:@return @2: scope:[] from @1 (byte*) heap_head#14 ← phi( @1/(byte*) heap_head#3 ) call main to:@3 @3: scope:[] from @2 (byte*) heap_head#12 ← phi( @2/(byte*) heap_head#2 ) (byte*) heap_head#6 ← (byte*) heap_head#12 to:@end @end: scope:[] from @3 SYMBOL TABLE SSA (label) @1 (label) @2 (label) @3 (label) @begin (label) @end (byte*) SCREEN (byte*) heap_head (byte*) heap_head#0 (byte*) heap_head#1 (byte*) heap_head#10 (byte*) heap_head#11 (byte*) heap_head#12 (byte*) heap_head#13 (byte*) heap_head#14 (byte*) heap_head#2 (byte*) heap_head#3 (byte*) heap_head#4 (byte*) heap_head#5 (byte*) heap_head#6 (byte*) heap_head#7 (byte*) heap_head#8 (byte*) heap_head#9 (void()) main() (void*~) main::$0 (void*~) main::$1 (label) main::@1 (label) main::@2 (label) main::@return (byte*) main::buf1 (byte*) main::buf1#0 (byte*) main::buf1#1 (byte*) main::buf2 (byte*) main::buf2#0 (void*()) malloc() (label) malloc::@return (void*) malloc::return (void*) malloc::return#0 (void*) malloc::return#1 (void*) malloc::return#2 (void*) malloc::return#3 (void*) malloc::return#4 (void*) malloc::return#5 (void*) malloc::return#6 Adding number conversion cast (unumber) 0 in *((byte*) SCREEN + (number) 0) ← *((byte*) main::buf1#1) Adding number conversion cast (unumber) 1 in *((byte*) SCREEN + (number) 1) ← *((byte*) main::buf2#0) Successful SSA optimization PassNAddNumberTypeConversions Inlining cast (byte*) SCREEN ← (byte*)(number) $400 Inlining cast (byte*) main::buf1#0 ← (byte*)(void*~) main::$0 Inlining cast (byte*) main::buf2#0 ← (byte*)(void*~) main::$1 Inlining cast (byte*) heap_head#3 ← (byte*)(number) $c000 Inlining cast (void*) malloc::return#2 ← (void*)(byte*) heap_head#4 Successful SSA optimization Pass2InlineCast Simplifying constant pointer cast (byte*) 1024 Simplifying constant integer cast 0 Simplifying constant integer cast 1 Simplifying constant pointer cast (byte*) 49152 Successful SSA optimization PassNCastSimplification Finalized unsigned number type (byte) 0 Finalized unsigned number type (byte) 1 Successful SSA optimization PassNFinalizeNumberTypeConversions Alias (void*) malloc::return#0 = (void*) malloc::return#4 Alias (byte*) heap_head#0 = (byte*) heap_head#7 Alias (void*) malloc::return#1 = (void*) malloc::return#5 Alias (byte*) main::buf1#0 = (byte*) main::buf1#1 Alias (byte*) heap_head#1 = (byte*) heap_head#8 (byte*) heap_head#9 (byte*) heap_head#2 Alias (void*) malloc::return#2 = (void*) malloc::return#6 (void*) malloc::return#3 Alias (byte*) heap_head#11 = (byte*) heap_head#4 (byte*) heap_head#5 Alias (byte*) heap_head#14 = (byte*) heap_head#3 Alias (byte*) heap_head#12 = (byte*) heap_head#6 Successful SSA optimization Pass2AliasElimination Identical Phi Values (byte*) heap_head#13 (byte*) heap_head#14 Identical Phi Values (byte*) heap_head#0 (byte*) heap_head#11 Identical Phi Values (byte*) heap_head#1 (byte*) heap_head#11 Identical Phi Values (byte*) heap_head#12 (byte*) heap_head#1 Successful SSA optimization Pass2IdenticalPhiElimination Constant (const byte*) SCREEN = (byte*) 1024 Constant (const byte*) heap_head#14 = (byte*) 49152 Successful SSA optimization Pass2ConstantIdentification Simplifying expression containing zero SCREEN in [16] *((const byte*) SCREEN + (byte) 0) ← *((byte*) main::buf1#0) Successful SSA optimization PassNSimplifyExpressionWithZero Inlining Noop Cast [3] (byte*) main::buf1#0 ← (byte*)(void*~) main::$0 keeping main::buf1#0 Inlining Noop Cast [7] (byte*) main::buf2#0 ← (byte*)(void*~) main::$1 keeping main::buf2#0 Successful SSA optimization Pass2NopCastInlining Inlining constant with var siblings (const byte*) heap_head#14 Constant inlined heap_head#14 = (byte*) 49152 Successful SSA optimization Pass2ConstantInlining 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 @3 Adding NOP phi() at start of @end Adding NOP phi() at start of main CALL GRAPH Calls in [] to main:3 Calls in [main] to malloc:7 malloc:11 Created 1 initial phi equivalence classes Coalesced [10] heap_head#15 ← heap_head#11 Coalesced down to 1 phi equivalence classes Culled Empty Block (label) @1 Culled Empty Block (label) @3 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 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] phi() [5] call malloc [6] (void*) malloc::return#0 ← (void*) malloc::return#2 to:main::@1 main::@1: scope:[main] from main [7] (void*) main::buf1#0 ← (void*) malloc::return#0 [8] call malloc [9] (void*) malloc::return#1 ← (void*) malloc::return#2 to:main::@2 main::@2: scope:[main] from main::@1 [10] (void*) main::buf2#0 ← (void*) malloc::return#1 [11] *((byte*)(void*) main::buf1#0) ← (byte) 'a' [12] *((byte*)(void*) main::buf2#0) ← (byte) 'b' [13] *((const byte*) SCREEN) ← *((byte*)(void*) main::buf1#0) [14] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(void*) main::buf2#0) to:main::@return main::@return: scope:[main] from main::@2 [15] return to:@return (void*()) malloc() malloc: scope:[malloc] from main main::@1 [16] (byte*) heap_head#10 ← phi( main/(byte*) 49152 main::@1/(byte*) heap_head#11 ) [17] (byte*) heap_head#11 ← ++ (byte*) heap_head#10 [18] (void*) malloc::return#2 ← (void*)(byte*) heap_head#11 to:malloc::@return malloc::@return: scope:[malloc] from malloc [19] return to:@return VARIABLE REGISTER WEIGHTS (byte*) heap_head (byte*) heap_head#10 4.0 (byte*) heap_head#11 0.6666666666666666 (void()) main() (byte*) main::buf1 (void*) main::buf1#0 0.3333333333333333 (byte*) main::buf2 (void*) main::buf2#0 0.5 (void*()) malloc() (void*) malloc::return (void*) malloc::return#0 4.0 (void*) malloc::return#1 4.0 (void*) malloc::return#2 1.5 Initial phi equivalence classes [ heap_head#10 heap_head#11 ] Added variable malloc::return#0 to zero page equivalence class [ malloc::return#0 ] Added variable main::buf1#0 to zero page equivalence class [ main::buf1#0 ] Added variable malloc::return#1 to zero page equivalence class [ malloc::return#1 ] Added variable main::buf2#0 to zero page equivalence class [ main::buf2#0 ] Added variable malloc::return#2 to zero page equivalence class [ malloc::return#2 ] Complete equivalence classes [ heap_head#10 heap_head#11 ] [ malloc::return#0 ] [ main::buf1#0 ] [ malloc::return#1 ] [ main::buf2#0 ] [ malloc::return#2 ] Allocated zp ZP_WORD:2 [ heap_head#10 heap_head#11 ] Allocated zp ZP_WORD:4 [ malloc::return#0 ] Allocated zp ZP_WORD:6 [ main::buf1#0 ] Allocated zp ZP_WORD:8 [ malloc::return#1 ] Allocated zp ZP_WORD:10 [ main::buf2#0 ] Allocated zp ZP_WORD:12 [ malloc::return#2 ] INITIAL ASM Target platform is c64basic / MOS6502X // File Comments // Test void pointer - issues when assigning returns from malloc() // Upstart .pc = $801 "Basic" :BasicUpstart(bbegin) .pc = $80d "Program" // Global Constants & labels .label SCREEN = $400 .label heap_head = 2 // @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: { .label buf1 = 6 .label buf2 = $a // [5] call malloc // [16] phi from main to malloc [phi:main->malloc] malloc_from_main: // [16] phi (byte*) heap_head#10 = (byte*) 49152 [phi:main->malloc#0] -- pbuz1=pbuc1 lda #<$c000 sta.z heap_head lda #>$c000 sta.z heap_head+1 jsr malloc // [6] (void*) malloc::return#0 ← (void*) malloc::return#2 -- pvoz1=pvoz2 lda.z malloc.return_2 sta.z malloc.return lda.z malloc.return_2+1 sta.z malloc.return+1 jmp b1 // main::@1 b1: // [7] (void*) main::buf1#0 ← (void*) malloc::return#0 -- pvoz1=pvoz2 lda.z malloc.return sta.z buf1 lda.z malloc.return+1 sta.z buf1+1 // [8] call malloc // [16] phi from main::@1 to malloc [phi:main::@1->malloc] malloc_from_b1: // [16] phi (byte*) heap_head#10 = (byte*) heap_head#11 [phi:main::@1->malloc#0] -- register_copy jsr malloc // [9] (void*) malloc::return#1 ← (void*) malloc::return#2 -- pvoz1=pvoz2 lda.z malloc.return_2 sta.z malloc.return_1 lda.z malloc.return_2+1 sta.z malloc.return_1+1 jmp b2 // main::@2 b2: // [10] (void*) main::buf2#0 ← (void*) malloc::return#1 -- pvoz1=pvoz2 lda.z malloc.return_1 sta.z buf2 lda.z malloc.return_1+1 sta.z buf2+1 // [11] *((byte*)(void*) main::buf1#0) ← (byte) 'a' -- _deref_pbuz1=vbuc1 lda #'a' ldy #0 sta (buf1),y // [12] *((byte*)(void*) main::buf2#0) ← (byte) 'b' -- _deref_pbuz1=vbuc1 lda #'b' ldy #0 sta (buf2),y // [13] *((const byte*) SCREEN) ← *((byte*)(void*) main::buf1#0) -- _deref_pbuc1=_deref_pbuz1 ldy #0 lda (buf1),y sta SCREEN // [14] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(void*) main::buf2#0) -- _deref_pbuc1=_deref_pbuz1 ldy #0 lda (buf2),y sta SCREEN+1 jmp breturn // main::@return breturn: // [15] return rts } // malloc malloc: { .label return = 4 .label return_1 = 8 .label return_2 = $c // [17] (byte*) heap_head#11 ← ++ (byte*) heap_head#10 -- pbuz1=_inc_pbuz1 inc.z heap_head bne !+ inc.z heap_head+1 !: // [18] (void*) malloc::return#2 ← (void*)(byte*) heap_head#11 -- pvoz1=pvoz2 lda.z heap_head sta.z return_2 lda.z heap_head+1 sta.z return_2+1 jmp breturn // malloc::@return breturn: // [19] return rts } // File Data REGISTER UPLIFT POTENTIAL REGISTERS Statement [6] (void*) malloc::return#0 ← (void*) malloc::return#2 [ malloc::return#0 heap_head#11 ] ( main:2 [ malloc::return#0 heap_head#11 ] ) always clobbers reg byte a Statement [7] (void*) main::buf1#0 ← (void*) malloc::return#0 [ main::buf1#0 heap_head#11 ] ( main:2 [ main::buf1#0 heap_head#11 ] ) always clobbers reg byte a Statement [9] (void*) malloc::return#1 ← (void*) malloc::return#2 [ main::buf1#0 malloc::return#1 ] ( main:2 [ main::buf1#0 malloc::return#1 ] ) always clobbers reg byte a Statement [10] (void*) main::buf2#0 ← (void*) malloc::return#1 [ main::buf1#0 main::buf2#0 ] ( main:2 [ main::buf1#0 main::buf2#0 ] ) always clobbers reg byte a Statement [11] *((byte*)(void*) main::buf1#0) ← (byte) 'a' [ main::buf1#0 main::buf2#0 ] ( main:2 [ main::buf1#0 main::buf2#0 ] ) always clobbers reg byte a reg byte y Statement [12] *((byte*)(void*) main::buf2#0) ← (byte) 'b' [ main::buf1#0 main::buf2#0 ] ( main:2 [ main::buf1#0 main::buf2#0 ] ) always clobbers reg byte a reg byte y Statement [13] *((const byte*) SCREEN) ← *((byte*)(void*) main::buf1#0) [ main::buf2#0 ] ( main:2 [ main::buf2#0 ] ) always clobbers reg byte a reg byte y Statement [14] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(void*) main::buf2#0) [ ] ( main:2 [ ] ) always clobbers reg byte a reg byte y Statement [18] (void*) malloc::return#2 ← (void*)(byte*) heap_head#11 [ malloc::return#2 heap_head#11 ] ( main:2::malloc:5 [ malloc::return#2 heap_head#11 ] main:2::malloc:8 [ main::buf1#0 malloc::return#2 heap_head#11 ] ) always clobbers reg byte a Potential registers zp ZP_WORD:2 [ heap_head#10 heap_head#11 ] : zp ZP_WORD:2 , Potential registers zp ZP_WORD:4 [ malloc::return#0 ] : zp ZP_WORD:4 , Potential registers zp ZP_WORD:6 [ main::buf1#0 ] : zp ZP_WORD:6 , Potential registers zp ZP_WORD:8 [ malloc::return#1 ] : zp ZP_WORD:8 , Potential registers zp ZP_WORD:10 [ main::buf2#0 ] : zp ZP_WORD:10 , Potential registers zp ZP_WORD:12 [ malloc::return#2 ] : zp ZP_WORD:12 , REGISTER UPLIFT SCOPES Uplift Scope [malloc] 4: zp ZP_WORD:4 [ malloc::return#0 ] 4: zp ZP_WORD:8 [ malloc::return#1 ] 1.5: zp ZP_WORD:12 [ malloc::return#2 ] Uplift Scope [] 4.67: zp ZP_WORD:2 [ heap_head#10 heap_head#11 ] Uplift Scope [main] 0.5: zp ZP_WORD:10 [ main::buf2#0 ] 0.33: zp ZP_WORD:6 [ main::buf1#0 ] Uplifting [malloc] best 172 combination zp ZP_WORD:4 [ malloc::return#0 ] zp ZP_WORD:8 [ malloc::return#1 ] zp ZP_WORD:12 [ malloc::return#2 ] Uplifting [] best 172 combination zp ZP_WORD:2 [ heap_head#10 heap_head#11 ] Uplifting [main] best 172 combination zp ZP_WORD:10 [ main::buf2#0 ] zp ZP_WORD:6 [ main::buf1#0 ] Coalescing zero page register [ zp ZP_WORD:4 [ malloc::return#0 ] ] with [ zp ZP_WORD:6 [ main::buf1#0 ] ] - score: 1 Coalescing zero page register [ zp ZP_WORD:8 [ malloc::return#1 ] ] with [ zp ZP_WORD:10 [ main::buf2#0 ] ] - score: 1 Coalescing zero page register [ zp ZP_WORD:8 [ malloc::return#1 main::buf2#0 ] ] with [ zp ZP_WORD:12 [ malloc::return#2 ] ] - score: 1 Allocated (was zp ZP_WORD:8) zp ZP_WORD:6 [ malloc::return#1 main::buf2#0 malloc::return#2 ] ASSEMBLER BEFORE OPTIMIZATION // File Comments // Test void pointer - issues when assigning returns from malloc() // Upstart .pc = $801 "Basic" :BasicUpstart(bbegin) .pc = $80d "Program" // Global Constants & labels .label SCREEN = $400 .label heap_head = 2 // @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: { .label buf1 = 4 .label buf2 = 6 // [5] call malloc // [16] phi from main to malloc [phi:main->malloc] malloc_from_main: // [16] phi (byte*) heap_head#10 = (byte*) 49152 [phi:main->malloc#0] -- pbuz1=pbuc1 lda #<$c000 sta.z heap_head lda #>$c000 sta.z heap_head+1 jsr malloc // [6] (void*) malloc::return#0 ← (void*) malloc::return#2 -- pvoz1=pvoz2 lda.z malloc.return_2 sta.z malloc.return lda.z malloc.return_2+1 sta.z malloc.return+1 jmp b1 // main::@1 b1: // [7] (void*) main::buf1#0 ← (void*) malloc::return#0 // [8] call malloc // [16] phi from main::@1 to malloc [phi:main::@1->malloc] malloc_from_b1: // [16] phi (byte*) heap_head#10 = (byte*) heap_head#11 [phi:main::@1->malloc#0] -- register_copy jsr malloc // [9] (void*) malloc::return#1 ← (void*) malloc::return#2 jmp b2 // main::@2 b2: // [10] (void*) main::buf2#0 ← (void*) malloc::return#1 // [11] *((byte*)(void*) main::buf1#0) ← (byte) 'a' -- _deref_pbuz1=vbuc1 lda #'a' ldy #0 sta (buf1),y // [12] *((byte*)(void*) main::buf2#0) ← (byte) 'b' -- _deref_pbuz1=vbuc1 lda #'b' ldy #0 sta (buf2),y // [13] *((const byte*) SCREEN) ← *((byte*)(void*) main::buf1#0) -- _deref_pbuc1=_deref_pbuz1 ldy #0 lda (buf1),y sta SCREEN // [14] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(void*) main::buf2#0) -- _deref_pbuc1=_deref_pbuz1 ldy #0 lda (buf2),y sta SCREEN+1 jmp breturn // main::@return breturn: // [15] return rts } // malloc malloc: { .label return = 4 .label return_1 = 6 .label return_2 = 6 // [17] (byte*) heap_head#11 ← ++ (byte*) heap_head#10 -- pbuz1=_inc_pbuz1 inc.z heap_head bne !+ inc.z heap_head+1 !: // [18] (void*) malloc::return#2 ← (void*)(byte*) heap_head#11 -- pvoz1=pvoz2 lda.z heap_head sta.z return_2 lda.z heap_head+1 sta.z return_2+1 jmp breturn // malloc::@return breturn: // [19] return rts } // File Data ASSEMBLER OPTIMIZATIONS Removing instruction jmp b1 Removing instruction jmp bend Removing instruction jmp b1 Removing instruction jmp b2 Removing instruction jmp breturn Removing instruction jmp breturn Succesful ASM optimization Pass5NextJumpElimination Removing instruction ldy #0 Removing instruction ldy #0 Removing instruction ldy #0 Succesful ASM optimization Pass5UnnecesaryLoadElimination Removing instruction b1_from_bbegin: Removing instruction b1: Removing instruction main_from_b1: Removing instruction bend_from_b1: Removing instruction malloc_from_b1: Succesful ASM optimization Pass5RedundantLabelElimination Removing instruction bend: Removing instruction malloc_from_main: Removing instruction b1: Removing instruction b2: Removing instruction breturn: Removing instruction breturn: 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 (const byte*) SCREEN SCREEN = (byte*) 1024 (byte*) heap_head (byte*) heap_head#10 heap_head zp ZP_WORD:2 4.0 (byte*) heap_head#11 heap_head zp ZP_WORD:2 0.6666666666666666 (void()) main() (label) main::@1 (label) main::@2 (label) main::@return (byte*) main::buf1 (void*) main::buf1#0 buf1 zp ZP_WORD:4 0.3333333333333333 (byte*) main::buf2 (void*) main::buf2#0 buf2 zp ZP_WORD:6 0.5 (void*()) malloc() (label) malloc::@return (void*) malloc::return (void*) malloc::return#0 return zp ZP_WORD:4 4.0 (void*) malloc::return#1 return#1 zp ZP_WORD:6 4.0 (void*) malloc::return#2 return#2 zp ZP_WORD:6 1.5 zp ZP_WORD:2 [ heap_head#10 heap_head#11 ] zp ZP_WORD:4 [ malloc::return#0 main::buf1#0 ] zp ZP_WORD:6 [ malloc::return#1 main::buf2#0 malloc::return#2 ] FINAL ASSEMBLER Score: 106 // File Comments // Test void pointer - issues when assigning returns from malloc() // Upstart .pc = $801 "Basic" :BasicUpstart(main) .pc = $80d "Program" // Global Constants & labels .label SCREEN = $400 .label heap_head = 2 // @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: { .label buf1 = 4 .label buf2 = 6 // malloc() // [5] call malloc // [16] phi from main to malloc [phi:main->malloc] // [16] phi (byte*) heap_head#10 = (byte*) 49152 [phi:main->malloc#0] -- pbuz1=pbuc1 lda #<$c000 sta.z heap_head lda #>$c000 sta.z heap_head+1 jsr malloc // malloc() // [6] (void*) malloc::return#0 ← (void*) malloc::return#2 -- pvoz1=pvoz2 lda.z malloc.return_2 sta.z malloc.return lda.z malloc.return_2+1 sta.z malloc.return+1 // main::@1 // [7] (void*) main::buf1#0 ← (void*) malloc::return#0 // [8] call malloc // [16] phi from main::@1 to malloc [phi:main::@1->malloc] // [16] phi (byte*) heap_head#10 = (byte*) heap_head#11 [phi:main::@1->malloc#0] -- register_copy jsr malloc // malloc() // [9] (void*) malloc::return#1 ← (void*) malloc::return#2 // main::@2 // [10] (void*) main::buf2#0 ← (void*) malloc::return#1 // *buf1 = 'a' // [11] *((byte*)(void*) main::buf1#0) ← (byte) 'a' -- _deref_pbuz1=vbuc1 lda #'a' ldy #0 sta (buf1),y // *buf2 = 'b' // [12] *((byte*)(void*) main::buf2#0) ← (byte) 'b' -- _deref_pbuz1=vbuc1 lda #'b' sta (buf2),y // SCREEN[0] = *buf1 // [13] *((const byte*) SCREEN) ← *((byte*)(void*) main::buf1#0) -- _deref_pbuc1=_deref_pbuz1 lda (buf1),y sta SCREEN // SCREEN[1] = *buf2 // [14] *((const byte*) SCREEN+(byte) 1) ← *((byte*)(void*) main::buf2#0) -- _deref_pbuc1=_deref_pbuz1 lda (buf2),y sta SCREEN+1 // main::@return // } // [15] return rts } // malloc malloc: { .label return = 4 .label return_1 = 6 .label return_2 = 6 // heap_head++; // [17] (byte*) heap_head#11 ← ++ (byte*) heap_head#10 -- pbuz1=_inc_pbuz1 inc.z heap_head bne !+ inc.z heap_head+1 !: // return heap_head; // [18] (void*) malloc::return#2 ← (void*)(byte*) heap_head#11 -- pvoz1=pvoz2 lda.z heap_head sta.z return_2 lda.z heap_head+1 sta.z return_2+1 // malloc::@return // } // [19] return rts } // File Data