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

Increased complexity of examples. Fixed A-clobber problems.

This commit is contained in:
jespergravgaard 2023-04-23 16:00:52 +02:00
parent 35b6395f02
commit 2b1bc3c11d
65 changed files with 4923 additions and 1965 deletions

View File

@ -1,7 +1,11 @@
sta $ff
lda $0 lda $0
pha pha
lda #{c1} lda #{c1}
sta $0 sta $0
lda $ff
jsr {la1} jsr {la1}
sta $ff
pla pla
sta $0 sta $0
lda $ff

View File

@ -1,7 +1,11 @@
sta $ff
lda $1 lda $1
pha pha
lda #{c1} lda #{c1}
sta $1 sta $1
lda $ff
jsr {la1} jsr {la1}
sta $ff
pla pla
sta $1 sta $1
lda $ff

View File

@ -767,6 +767,11 @@ public class TestProgramsFast extends TestPrograms {
compileAndCompare("examples/cx16/cx16-rasterbars.c"); compileAndCompare("examples/cx16/cx16-rasterbars.c");
} }
//@Test
//public void testCx16Banking() throws IOException {
// compileAndCompare("examples/cx16/banking/cx16-banking.c");
//}
@Test @Test
public void testMega65Camelot1536Dots() throws IOException { public void testMega65Camelot1536Dots() throws IOException {
compileAndCompare("examples/mega65/camelot-1536dots.c"); compileAndCompare("examples/mega65/camelot-1536dots.c");

View File

@ -32,6 +32,7 @@ char* const SCREEN = (char*)0x0400;
#pragma code_seg(Code) #pragma code_seg(Code)
void main(void) { void main(void) {
SCREEN[0] = plus('0', 7); // near call SCREEN[0] = plus('0', 7); // near call
SCREEN[1] = plus('1', 6); // near call
} }
#pragma code_seg(Code) #pragma code_seg(Code)

View File

@ -32,14 +32,15 @@ char* const SCREEN = (char*)0x0400;
#pragma code_seg(Code) #pragma code_seg(Code)
void main(void) { void main(void) {
SCREEN[0] = plus('0', 7); // near call SCREEN[0] = plus('0', 7); // near call
SCREEN[1] = plus('1', 6); // near call
} }
#pragma code_seg(Code) #pragma code_seg(Code)
char plus(char a, char b) { char plus(char a, char b) {
return min(a, b); // near call return add(a, b); // near call
} }
#pragma code_seg(Code) #pragma code_seg(Code)
char min(char a, char b) { char add(char a, char b) {
return a+b; return a+b;
} }

View File

@ -33,10 +33,10 @@ char* const SCREEN = (char*)0x0400;
#pragma code_seg(Code) #pragma code_seg(Code)
void main(void) { void main(void) {
SCREEN[0] = plus('0', 7); // close call SCREEN[0] = plus('0', 7); // close call
SCREEN[1] = plus('1', 6); // close call
} }
#pragma code_seg(RAM_Bank1) #pragma code_seg(RAM_Bank1)
__bank(cx16_ram,1) char plus(char a, char b) { __bank(cx16_ram,1) char plus(char a, char b) {
return a+b; return a+b;
} }

View File

@ -28,21 +28,16 @@
#pragma link("call-banked-phi.ld") #pragma link("call-banked-phi.ld")
char* const SCREEN = (char*)0x0400; char* const SCREEN = (char*)0x0400;
#pragma code_seg(Code) #pragma code_seg(Code)
void main(void) { void main(void) {
SCREEN[0] = plus('0', 7); // close call SCREEN[0] = plus('0', 7); // close call
SCREEN[1] = plus('1', 6); // close call
} }
#pragma code_seg(RAM_Bank1) #pragma code_seg(RAM_Bank1)
#pragma bank(cx16_ram, 1) #pragma bank(cx16_ram, 1)
char plus(char a, char b) { char plus(char a, char b) {
return a+b; return a+b;
} }
#pragma code_seg(Code)
#pragma nobank

View File

@ -33,15 +33,17 @@ char* const SCREEN = (char*)0x0400;
#pragma code_seg(Code) #pragma code_seg(Code)
void main(void) { void main(void) {
SCREEN[0] = plus('0', 7); // close call SCREEN[0] = plus('0', 7); // close call
SCREEN[1] = plus('1', 6); // close call
} }
#pragma code_seg(RAM_Bank1) #pragma code_seg(RAM_Bank1)
__bank(cx16_ram,1) char plus(char a, char b) { __bank(cx16_ram,1) char plus(char a, char b) {
return min(a, b); // near call return add(a, b); // near call
} }
#pragma code_seg(Code) #pragma code_seg(Code)
char min(char a, char b) { #pragma nobank
char add(char a, char b) {
return a+b; return a+b;
} }

View File

@ -33,17 +33,18 @@ char* const SCREEN = (char*)0x0400;
#pragma code_seg(Code) #pragma code_seg(Code)
void main(void) { void main(void) {
SCREEN[0] = plus('0', 7); // close call SCREEN[0] = plus('0', 7); // close call
SCREEN[1] = plus('1', 6); // close call
} }
#pragma code_seg(RAM_Bank1) #pragma code_seg(RAM_Bank1)
#pragma bank(cx16_ram, 1) #pragma bank(cx16_ram, 1)
char plus(char a, char b) { char plus(char a, char b) {
return min(a, b); // near call return add(a, b); // near call
} }
#pragma code_seg(Code) #pragma code_seg(Code)
#pragma nobank #pragma nobank
char min(char a, char b) { char add(char a, char b) {
return a+b; return a+b;
} }

View File

@ -28,20 +28,20 @@
#pragma link("call-banked-phi.ld") #pragma link("call-banked-phi.ld")
char* const SCREEN = (char*)0x0400; char* const SCREEN = (char*)0x0400;
#pragma code_seg(Code) #pragma code_seg(Code)
void main(void) { void main(void) {
SCREEN[0] = plus('0', 7); // close call SCREEN[0] = plus('0', 7); // close call
SCREEN[1] = plus('1', 6); // close call
} }
#pragma code_seg(RAM_Bank1) #pragma code_seg(RAM_Bank1)
char __bank(cx16_ram, 1) plus(char a, char b) { char __bank(cx16_ram, 1) plus(char a, char b) {
return min(a, b); // near call return add(a, b); // near call
} }
#pragma code_seg(RAM_Bank1) #pragma code_seg(RAM_Bank1)
char __bank(cx16_ram, 1) min(char a, char b) { char __bank(cx16_ram, 1) add(char a, char b) {
return a+b; return a+b;
} }

View File

@ -33,19 +33,17 @@ char* const SCREEN = (char*)0x0400;
#pragma code_seg(Code) #pragma code_seg(Code)
void main(void) { void main(void) {
SCREEN[0] = plus('0', 7); // close call SCREEN[0] = plus('0', 7); // close call
SCREEN[1] = plus('1', 6); // close call
} }
#pragma code_seg(RAM_Bank1) #pragma code_seg(RAM_Bank1)
#pragma bank(cx16_ram, 1) #pragma bank(cx16_ram, 1)
char plus(char a, char b) { char plus(char a, char b) {
return min(a, b); // near call return add(a, b); // near call
} }
#pragma code_seg(RAM_Bank1) #pragma code_seg(RAM_Bank1)
#pragma bank(cx16_ram, 1) #pragma bank(cx16_ram, 1)
char min(char a, char b) { char add(char a, char b) {
return a+b; return a+b;
} }
#pragma code_seg(Code)
#pragma nobank

View File

@ -33,14 +33,15 @@ char* const SCREEN = (char*)0x0400;
#pragma code_seg(Code) #pragma code_seg(Code)
void main(void) { void main(void) {
SCREEN[0] = plus('0', 7); // close call SCREEN[0] = plus('0', 7); // close call
SCREEN[1] = plus('1', 6); // close call
} }
#pragma code_seg(RAM_Bank1) #pragma code_seg(RAM_Bank1)
__bank(cx16_ram, 1) char plus(char a, char b) { __bank(cx16_ram, 1) char plus(char a, char b) {
return min(a, b); // far call return add(a, b); // far call
} }
#pragma code_seg(RAM_Bank2) #pragma code_seg(RAM_Bank2)
__bank(cx16_ram, 2) char min(char a, char b) { __bank(cx16_ram, 2) char add(char a, char b) {
return a+b; return a+b;
} }

View File

@ -33,19 +33,17 @@ char* const SCREEN = (char*)0x0400;
#pragma code_seg(Code) #pragma code_seg(Code)
void main(void) { void main(void) {
SCREEN[0] = plus('0', 7); // close call SCREEN[0] = plus('0', 7); // close call
SCREEN[1] = plus('1', 6); // close call
} }
#pragma code_seg(RAM_Bank1) #pragma code_seg(RAM_Bank1)
#pragma bank(cx16_ram, 1) #pragma bank(cx16_ram, 1)
char plus(char a, char b) { char plus(char a, char b) {
return min(a, b); // far call return add(a, b); // far call
} }
#pragma code_seg(RAM_Bank2) #pragma code_seg(RAM_Bank2)
#pragma bank(cx16_ram, 2) #pragma bank(cx16_ram, 2)
char min(char a, char b) { char add(char a, char b) {
return a+b; return a+b;
} }
#pragma code_seg(RAM_Bank2)
#pragma nobank

View File

@ -33,14 +33,15 @@ char* const SCREEN = (char*)0x0400;
#pragma code_seg(Code) #pragma code_seg(Code)
void main(void) { void main(void) {
SCREEN[0] = plus('0', 7); // close call SCREEN[0] = plus('0', 7); // close call
SCREEN[1] = plus('1', 6); // close call
} }
#pragma code_seg(RAM_Bank1) #pragma code_seg(RAM_Bank1)
__bank(cx16_ram, 1) char plus(char a, char b) { __bank(cx16_ram, 1) char plus(char a, char b) {
return min(a, b); // close call return add(a, b); // close call
} }
#pragma code_seg(ROM_Bank1) #pragma code_seg(ROM_Bank1)
__bank(cx16_rom, 1) char min(char a, char b) { __bank(cx16_rom, 1) char add(char a, char b) {
return a+b; return a+b;
} }

View File

@ -33,19 +33,17 @@ char* const SCREEN = (char*)0x0400;
#pragma code_seg(Code) #pragma code_seg(Code)
void main(void) { void main(void) {
SCREEN[0] = plus('0', 7); // close call SCREEN[0] = plus('0', 7); // close call
SCREEN[1] = plus('1', 6); // close call
} }
#pragma code_seg(RAM_Bank1) #pragma code_seg(RAM_Bank1)
#pragma bank(cx16_ram, 1) #pragma bank(cx16_ram, 1)
char plus(char a, char b) { char plus(char a, char b) {
return min(a, b); // close call return add(a, b); // close call
} }
#pragma code_seg(ROM_Bank1) #pragma code_seg(ROM_Bank1)
#pragma bank(cx16_rom, 1) #pragma bank(cx16_rom, 1)
char min(char a, char b) { char add(char a, char b) {
return a+b; return a+b;
} }
#pragma code_seg(Code)
#pragma nobank

View File

@ -1,38 +0,0 @@
/**
* @file cx16-banking-1.c
* @author your name (you@domain.com)
* @brief This program demonstrates a simple example of a banked call.
* @version 0.1
* @date 2023-04-05
*
* @copyright Copyright (c) 2023
*
*/
// The linker specification of the different segments.
#pragma var_model(mem)
#include <cx16.h>
#include <conio.h>
#include <printf.h>
#include <kernal.h>
// The target computer platform is the Commander X16,
// which implements banking in ram between 0xA0000 and 0xBFFF,
// and in ram between 0xC000 and 0xFFFF.
#pragma target(cx16)
char __stackcall plus(char a, char b) {
if (a > 0) {
return a + plus(a - b, b);
} else {
return 0;
}
}
void main(void) {
char result = plus(4, 1);
printf("result = %u\n", result);
}

View File

@ -10,6 +10,7 @@
*/ */
// The linker specification of the different segments. // The linker specification of the different segments.
#pragma target(cx16)
#pragma link("cx16-banking.ld") #pragma link("cx16-banking.ld")
#pragma var_model(mem) #pragma var_model(mem)

View File

@ -42,17 +42,29 @@
.segment Code .segment Code
main: { main: {
// plus('0', 7) // plus('0', 7)
lda #7
ldx #'0'
jsr plus jsr plus
// plus('0', 7)
// SCREEN[0] = plus('0', 7) // SCREEN[0] = plus('0', 7)
lda #plus.return
sta SCREEN sta SCREEN
// plus('1', 6)
lda #6
ldx #'1'
jsr plus
// plus('1', 6)
// SCREEN[1] = plus('1', 6)
// near call
sta SCREEN+1
// } // }
rts rts
} }
// char plus(char a, char b) // __register(A) char plus(__register(X) char a, __register(A) char b)
plus: { plus: {
.const a = '0' // a+b
.const b = 7 stx.z $ff
.label return = a+b clc
adc.z $ff
// }
rts rts
} }

View File

@ -3,18 +3,28 @@ void main()
main: scope:[main] from main: scope:[main] from
[0] phi() [0] phi()
[1] call plus [1] call plus
[2] plus::return#0 = plus::return#2
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
[2] *SCREEN = plus::return#1 [3] main::$0 = plus::return#0
[4] *SCREEN = main::$0
[5] call plus
[6] plus::return#1 = plus::return#2
to:main::@2
main::@2: scope:[main] from main::@1
[7] main::$1 = plus::return#1
[8] *(SCREEN+1) = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
[3] return [9] return
to:@return to:@return
char plus(char a , char b) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
[4] phi() [10] plus::b#2 = phi( main/7, main::@1/6 )
[10] plus::a#2 = phi( main/'0', main::@1/'1' )
[11] plus::return#2 = plus::a#2 + plus::b#2
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus
[5] return [12] return
to:@return to:@return

View File

@ -7,27 +7,36 @@ main: scope:[main] from __start
plus::a#0 = '0' plus::a#0 = '0'
plus::b#0 = 7 plus::b#0 = 7
call plus call plus
plus::return#0 = plus::return#2 plus::return#0 = plus::return#3
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
plus::return#3 = phi( main/plus::return#0 ) plus::return#4 = phi( main/plus::return#0 )
main::$0 = plus::return#3 main::$0 = plus::return#4
SCREEN[0] = main::$0 SCREEN[0] = main::$0
plus::a#1 = '1'
plus::b#1 = 6
call plus
plus::return#1 = plus::return#3
to:main::@2
main::@2: scope:[main] from main::@1
plus::return#5 = phi( main::@1/plus::return#1 )
main::$1 = plus::return#5
SCREEN[1] = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
return return
to:@return to:@return
char plus(char a , char b) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
plus::b#1 = phi( main/plus::b#0 ) plus::b#2 = phi( main/plus::b#0, main::@1/plus::b#1 )
plus::a#1 = phi( main/plus::a#0 ) plus::a#2 = phi( main/plus::a#0, main::@1/plus::a#1 )
plus::$0 = plus::a#1 + plus::b#1 plus::$0 = plus::a#2 + plus::b#2
plus::return#1 = plus::$0 plus::return#2 = plus::$0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus
plus::return#4 = phi( plus/plus::return#1 ) plus::return#6 = phi( plus/plus::return#2 )
plus::return#2 = plus::return#4 plus::return#3 = plus::return#6
return return
to:@return to:@return
@ -46,41 +55,53 @@ __constant char * const SCREEN = (char *)$400
void __start() void __start()
void main() void main()
char main::$0 char main::$0
char main::$1
char plus(char a , char b) char plus(char a , char b)
char plus::$0 char plus::$0
char plus::a char plus::a
char plus::a#0 char plus::a#0
char plus::a#1 char plus::a#1
char plus::a#2
char plus::b char plus::b
char plus::b#0 char plus::b#0
char plus::b#1 char plus::b#1
char plus::b#2
char plus::return char plus::return
char plus::return#0 char plus::return#0
char plus::return#1 char plus::return#1
char plus::return#2 char plus::return#2
char plus::return#3 char plus::return#3
char plus::return#4 char plus::return#4
char plus::return#5
char plus::return#6
Adding number conversion cast (unumber) 7 in plus::b#0 = 7 Adding number conversion cast (unumber) 7 in plus::b#0 = 7
Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0 Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0
Adding number conversion cast (unumber) 6 in plus::b#1 = 6
Adding number conversion cast (unumber) 1 in SCREEN[1] = main::$1
Successful SSA optimization PassNAddNumberTypeConversions Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast plus::b#0 = (unumber)7 Inlining cast plus::b#0 = (unumber)7
Inlining cast plus::b#1 = (unumber)6
Successful SSA optimization Pass2InlineCast Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (char *) 1024 Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast 7 Simplifying constant integer cast 7
Simplifying constant integer cast 0 Simplifying constant integer cast 0
Simplifying constant integer cast 6
Simplifying constant integer cast 1
Successful SSA optimization PassNCastSimplification Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 7 Finalized unsigned number type (char) 7
Finalized unsigned number type (char) 0 Finalized unsigned number type (char) 0
Finalized unsigned number type (char) 6
Finalized unsigned number type (char) 1
Successful SSA optimization PassNFinalizeNumberTypeConversions Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias plus::return#0 = plus::return#3 Alias plus::return#0 = plus::return#4
Alias plus::return#1 = plus::$0 plus::return#4 plus::return#2 Alias plus::return#1 = plus::return#5
Alias plus::return#2 = plus::$0 plus::return#6 plus::return#3
Successful SSA optimization Pass2AliasElimination Successful SSA optimization Pass2AliasElimination
Identical Phi Values plus::a#1 plus::a#0
Identical Phi Values plus::b#1 plus::b#0
Successful SSA optimization Pass2IdenticalPhiElimination
Constant plus::a#0 = '0' Constant plus::a#0 = '0'
Constant plus::b#0 = 7 Constant plus::b#0 = 7
Constant plus::a#1 = '1'
Constant plus::b#1 = 6
Successful SSA optimization Pass2ConstantIdentification Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0 Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0
Successful SSA optimization PassNSimplifyExpressionWithZero Successful SSA optimization PassNSimplifyExpressionWithZero
@ -89,27 +110,24 @@ Removing unused procedure block __start
Removing unused procedure block __start::@1 Removing unused procedure block __start::@1
Removing unused procedure block __start::@return Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart Successful SSA optimization PassNEliminateEmptyStart
Constant right-side identified [5] plus::return#1 = plus::a#0 + plus::b#0 Inlining constant with var siblings plus::a#0
Successful SSA optimization Pass2ConstantRValueConsolidation Inlining constant with var siblings plus::b#0
Constant plus::return#1 = plus::a#0+plus::b#0 Inlining constant with var siblings plus::a#1
Successful SSA optimization Pass2ConstantIdentification Inlining constant with var siblings plus::b#1
Constant plus::return#0 = plus::return#1 Constant inlined plus::b#1 = 6
Successful SSA optimization Pass2ConstantIdentification Constant inlined plus::b#0 = 7
Constant main::$0 = plus::return#0 Constant inlined plus::a#1 = '1'
Successful SSA optimization Pass2ConstantIdentification Constant inlined plus::a#0 = '0'
Inlining constant with different constant siblings plus::return#0
Constant inlined plus::return#0 = plus::return#1
Constant inlined main::$0 = plus::return#1
Successful SSA optimization Pass2ConstantInlining Successful SSA optimization Pass2ConstantInlining
Consolidated array index constant in *(SCREEN+1)
Successful SSA optimization Pass2ConstantAdditionElimination
Adding NOP phi() at start of main Adding NOP phi() at start of main
Adding NOP phi() at start of plus
CALL GRAPH CALL GRAPH
Calls in [main] to plus:1 Calls in [main] to plus:1 plus:5
Created 0 initial phi equivalence classes Created 2 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes Coalesced down to 2 phi equivalence classes
Adding NOP phi() at start of main Adding NOP phi() at start of main
Adding NOP phi() at start of plus
FINAL CONTROL FLOW GRAPH FINAL CONTROL FLOW GRAPH
@ -117,43 +135,91 @@ void main()
main: scope:[main] from main: scope:[main] from
[0] phi() [0] phi()
[1] call plus [1] call plus
[2] plus::return#0 = plus::return#2
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
[2] *SCREEN = plus::return#1 [3] main::$0 = plus::return#0
[4] *SCREEN = main::$0
[5] call plus
[6] plus::return#1 = plus::return#2
to:main::@2
main::@2: scope:[main] from main::@1
[7] main::$1 = plus::return#1
[8] *(SCREEN+1) = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
[3] return [9] return
to:@return to:@return
char plus(char a , char b) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
[4] phi() [10] plus::b#2 = phi( main/7, main::@1/6 )
[10] plus::a#2 = phi( main/'0', main::@1/'1' )
[11] plus::return#2 = plus::a#2 + plus::b#2
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus
[5] return [12] return
to:@return to:@return
VARIABLE REGISTER WEIGHTS VARIABLE REGISTER WEIGHTS
void main() void main()
char main::$0 // 4.0
char main::$1 // 4.0
char plus(char a , char b) char plus(char a , char b)
char plus::a char plus::a
char plus::a#2 // 11.0
char plus::b char plus::b
char plus::b#2 // 11.0
char plus::return char plus::return
char plus::return#0 // 4.0
char plus::return#1 // 4.0
char plus::return#2 // 3.75
Initial phi equivalence classes Initial phi equivalence classes
[ plus::a#2 ]
[ plus::b#2 ]
Added variable plus::return#0 to live range equivalence class [ plus::return#0 ]
Added variable main::$0 to live range equivalence class [ main::$0 ]
Added variable plus::return#1 to live range equivalence class [ plus::return#1 ]
Added variable main::$1 to live range equivalence class [ main::$1 ]
Added variable plus::return#2 to live range equivalence class [ plus::return#2 ]
Complete equivalence classes Complete equivalence classes
[ plus::a#2 ]
[ plus::b#2 ]
[ plus::return#0 ]
[ main::$0 ]
[ plus::return#1 ]
[ main::$1 ]
[ plus::return#2 ]
Allocated zp[1]:2 [ plus::a#2 ]
Allocated zp[1]:3 [ plus::b#2 ]
Allocated zp[1]:4 [ plus::return#0 ]
Allocated zp[1]:5 [ main::$0 ]
Allocated zp[1]:6 [ plus::return#1 ]
Allocated zp[1]:7 [ main::$1 ]
Allocated zp[1]:8 [ plus::return#2 ]
REGISTER UPLIFT POTENTIAL REGISTERS REGISTER UPLIFT POTENTIAL REGISTERS
Statement [2] *SCREEN = plus::return#1 [ ] ( [ ] { } ) always clobbers reg byte a Statement [11] plus::return#2 = plus::a#2 + plus::b#2 [ plus::return#2 ] ( plus:1 [ plus::return#2 ] { { plus::return#0 = plus::return#2 } } plus:5 [ plus::return#2 ] { { plus::return#1 = plus::return#2 } } ) always clobbers reg byte a
Potential registers zp[1]:2 [ plus::a#2 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:3 [ plus::b#2 ] : zp[1]:3 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:4 [ plus::return#0 ] : zp[1]:4 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:5 [ main::$0 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:6 [ plus::return#1 ] : zp[1]:6 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:7 [ main::$1 ] : zp[1]:7 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:8 [ plus::return#2 ] : zp[1]:8 , reg byte a , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES REGISTER UPLIFT SCOPES
Uplift Scope [main] Uplift Scope [plus] 11: zp[1]:2 [ plus::a#2 ] 11: zp[1]:3 [ plus::b#2 ] 4: zp[1]:4 [ plus::return#0 ] 4: zp[1]:6 [ plus::return#1 ] 3.75: zp[1]:8 [ plus::return#2 ]
Uplift Scope [plus] Uplift Scope [main] 4: zp[1]:5 [ main::$0 ] 4: zp[1]:7 [ main::$1 ]
Uplift Scope [] Uplift Scope []
Uplifting [main] best 60 combination Uplifting [plus] best 81 combination reg byte x [ plus::a#2 ] reg byte a [ plus::b#2 ] reg byte a [ plus::return#0 ] reg byte a [ plus::return#1 ] zp[1]:8 [ plus::return#2 ]
Uplifting [plus] best 60 combination Limited combination testing to 100 combinations of 1024 possible.
Uplifting [] best 60 combination Uplifting [main] best 69 combination reg byte a [ main::$0 ] reg byte a [ main::$1 ]
Uplifting [] best 69 combination
Attempting to uplift remaining variables inzp[1]:8 [ plus::return#2 ]
Uplifting [plus] best 60 combination reg byte a [ plus::return#2 ]
ASSEMBLER BEFORE OPTIMIZATION ASSEMBLER BEFORE OPTIMIZATION
// File Comments // File Comments
@ -204,42 +270,67 @@ ASSEMBLER BEFORE OPTIMIZATION
// main // main
main: { main: {
// [1] call plus // [1] call plus
// [4] phi from main to plus [phi:main->plus] // [10] phi from main to plus [phi:main->plus]
plus_from_main: plus_from_main:
// [10] phi plus::b#2 = 7 [phi:main->plus#0] -- vbuaa=vbuc1
lda #7
// [10] phi plus::a#2 = '0' [phi:main->plus#1] -- vbuxx=vbuc1
ldx #'0'
jsr plus jsr plus
// [2] plus::return#0 = plus::return#2
jmp __b1 jmp __b1
// main::@1 // main::@1
__b1: __b1:
// [2] *SCREEN = plus::return#1 -- _deref_pbuc1=vbuc2 // [3] main::$0 = plus::return#0
lda #plus.return // [4] *SCREEN = main::$0 -- _deref_pbuc1=vbuaa
sta SCREEN sta SCREEN
// [5] call plus
// [10] phi from main::@1 to plus [phi:main::@1->plus]
plus_from___b1:
// [10] phi plus::b#2 = 6 [phi:main::@1->plus#0] -- vbuaa=vbuc1
lda #6
// [10] phi plus::a#2 = '1' [phi:main::@1->plus#1] -- vbuxx=vbuc1
ldx #'1'
jsr plus
// [6] plus::return#1 = plus::return#2
jmp __b2
// main::@2
__b2:
// [7] main::$1 = plus::return#1
// [8] *(SCREEN+1) = main::$1 -- _deref_pbuc1=vbuaa
// near call
sta SCREEN+1
jmp __breturn jmp __breturn
// main::@return // main::@return
__breturn: __breturn:
// [3] return // [9] return
rts rts
} }
// plus // plus
// char plus(char a, char b) // __register(A) char plus(__register(X) char a, __register(A) char b)
plus: { plus: {
.const a = '0' // [11] plus::return#2 = plus::a#2 + plus::b#2 -- vbuaa=vbuxx_plus_vbuaa
.const b = 7 stx.z $ff
.label return = a+b clc
adc.z $ff
jmp __breturn jmp __breturn
// plus::@return // plus::@return
__breturn: __breturn:
// [5] return // [12] return
rts rts
} }
// File Data // File Data
ASSEMBLER OPTIMIZATIONS ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1 Removing instruction jmp __b1
Removing instruction jmp __b2
Removing instruction jmp __breturn Removing instruction jmp __breturn
Removing instruction jmp __breturn Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination Succesful ASM optimization Pass5NextJumpElimination
Removing instruction plus_from_main: Removing instruction plus_from_main:
Removing instruction __b1: Removing instruction __b1:
Removing instruction plus_from___b1:
Removing instruction __b2:
Removing instruction __breturn: Removing instruction __breturn:
Removing instruction __breturn: Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination Succesful ASM optimization Pass5UnusedLabelElimination
@ -247,18 +338,29 @@ Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE FINAL SYMBOL TABLE
__constant char * const SCREEN = (char *) 1024 __constant char * const SCREEN = (char *) 1024
void main() void main()
char main::$0 // reg byte a 4.0
char main::$1 // reg byte a 4.0
char plus(char a , char b) char plus(char a , char b)
char plus::a char plus::a
__constant char plus::a#0 = '0' // a char plus::a#2 // reg byte x 11.0
char plus::b char plus::b
__constant char plus::b#0 = 7 // b char plus::b#2 // reg byte a 11.0
char plus::return char plus::return
__constant char plus::return#1 = plus::a#0+plus::b#0 // return char plus::return#0 // reg byte a 4.0
char plus::return#1 // reg byte a 4.0
char plus::return#2 // reg byte a 3.75
reg byte x [ plus::a#2 ]
reg byte a [ plus::b#2 ]
reg byte a [ plus::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ plus::return#1 ]
reg byte a [ main::$1 ]
reg byte a [ plus::return#2 ]
FINAL ASSEMBLER FINAL ASSEMBLER
Score: 24 Score: 48
// File Comments // File Comments
/** /**
@ -309,26 +411,51 @@ Score: 24
main: { main: {
// plus('0', 7) // plus('0', 7)
// [1] call plus // [1] call plus
// [4] phi from main to plus [phi:main->plus] // [10] phi from main to plus [phi:main->plus]
// [10] phi plus::b#2 = 7 [phi:main->plus#0] -- vbuaa=vbuc1
lda #7
// [10] phi plus::a#2 = '0' [phi:main->plus#1] -- vbuxx=vbuc1
ldx #'0'
jsr plus jsr plus
// plus('0', 7)
// [2] plus::return#0 = plus::return#2
// main::@1 // main::@1
// [3] main::$0 = plus::return#0
// SCREEN[0] = plus('0', 7) // SCREEN[0] = plus('0', 7)
// [2] *SCREEN = plus::return#1 -- _deref_pbuc1=vbuc2 // [4] *SCREEN = main::$0 -- _deref_pbuc1=vbuaa
lda #plus.return
sta SCREEN sta SCREEN
// plus('1', 6)
// [5] call plus
// [10] phi from main::@1 to plus [phi:main::@1->plus]
// [10] phi plus::b#2 = 6 [phi:main::@1->plus#0] -- vbuaa=vbuc1
lda #6
// [10] phi plus::a#2 = '1' [phi:main::@1->plus#1] -- vbuxx=vbuc1
ldx #'1'
jsr plus
// plus('1', 6)
// [6] plus::return#1 = plus::return#2
// main::@2
// [7] main::$1 = plus::return#1
// SCREEN[1] = plus('1', 6)
// [8] *(SCREEN+1) = main::$1 -- _deref_pbuc1=vbuaa
// near call
sta SCREEN+1
// main::@return // main::@return
// } // }
// [3] return // [9] return
rts rts
} }
// plus // plus
// char plus(char a, char b) // __register(A) char plus(__register(X) char a, __register(A) char b)
plus: { plus: {
.const a = '0' // a+b
.const b = 7 // [11] plus::return#2 = plus::a#2 + plus::b#2 -- vbuaa=vbuxx_plus_vbuaa
.label return = a+b stx.z $ff
clc
adc.z $ff
// plus::@return // plus::@return
// [5] return // }
// [12] return
rts rts
} }
// File Data // File Data

View File

@ -1,10 +1,21 @@
__constant char * const SCREEN = (char *) 1024 __constant char * const SCREEN = (char *) 1024
void main() void main()
char main::$0 // reg byte a 4.0
char main::$1 // reg byte a 4.0
char plus(char a , char b) char plus(char a , char b)
char plus::a char plus::a
__constant char plus::a#0 = '0' // a char plus::a#2 // reg byte x 11.0
char plus::b char plus::b
__constant char plus::b#0 = 7 // b char plus::b#2 // reg byte a 11.0
char plus::return char plus::return
__constant char plus::return#1 = plus::a#0+plus::b#0 // return char plus::return#0 // reg byte a 4.0
char plus::return#1 // reg byte a 4.0
char plus::return#2 // reg byte a 3.75
reg byte x [ plus::a#2 ]
reg byte a [ plus::b#2 ]
reg byte a [ plus::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ plus::return#1 ]
reg byte a [ main::$1 ]
reg byte a [ plus::return#2 ]

View File

@ -42,24 +42,37 @@
.segment Code .segment Code
main: { main: {
// plus('0', 7) // plus('0', 7)
lda #7
ldx #'0'
jsr plus jsr plus
// plus('0', 7)
// SCREEN[0] = plus('0', 7) // SCREEN[0] = plus('0', 7)
lda #min.return
sta SCREEN sta SCREEN
// plus('1', 6)
lda #6
ldx #'1'
jsr plus
// plus('1', 6)
// SCREEN[1] = plus('1', 6)
// near call
sta SCREEN+1
// } // }
rts rts
} }
// char plus(char a, char b) // __register(A) char plus(__register(X) char a, __register(A) char b)
plus: { plus: {
.label a = '0' // add(a, b)
.label b = 7 stx.z add.a
// min(a, b) jsr add
jsr min
// } // }
rts rts
} }
// char min(char a, char b) // __register(A) char add(__zp(2) char a, __register(A) char b)
min: { add: {
.label return = plus.a+plus.b .label a = 2
// a+b
clc
adc.z a
// }
rts rts
} }

View File

@ -3,27 +3,42 @@ void main()
main: scope:[main] from main: scope:[main] from
[0] phi() [0] phi()
[1] call plus [1] call plus
[2] plus::return#0 = plus::return#2
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
[2] *SCREEN = min::return#1 [3] main::$0 = plus::return#0
[4] *SCREEN = main::$0
[5] call plus
[6] plus::return#1 = plus::return#2
to:main::@2
main::@2: scope:[main] from main::@1
[7] main::$1 = plus::return#1
[8] *(SCREEN+1) = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
[3] return [9] return
to:@return to:@return
char plus(char a , char b) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
[4] phi() [10] plus::b#2 = phi( main/7, main::@1/6 )
[5] call min [10] plus::a#2 = phi( main/'0', main::@1/'1' )
[11] add::a#0 = plus::a#2
[12] add::b#0 = plus::b#2
[13] call add
[14] add::return#0 = add::return#1
to:plus::@1
plus::@1: scope:[plus] from plus
[15] plus::return#2 = add::return#0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus::@1
[6] return [16] return
to:@return to:@return
char min(char a , char b) char add(char a , char b)
min: scope:[min] from plus add: scope:[add] from plus
[7] phi() [17] add::return#1 = add::a#0 + add::b#0
to:min::@return to:add::@return
min::@return: scope:[min] from min add::@return: scope:[add] from add
[8] return [18] return
to:@return to:@return

View File

@ -7,47 +7,56 @@ main: scope:[main] from __start
plus::a#0 = '0' plus::a#0 = '0'
plus::b#0 = 7 plus::b#0 = 7
call plus call plus
plus::return#0 = plus::return#2 plus::return#0 = plus::return#3
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
plus::return#3 = phi( main/plus::return#0 ) plus::return#4 = phi( main/plus::return#0 )
main::$0 = plus::return#3 main::$0 = plus::return#4
SCREEN[0] = main::$0 SCREEN[0] = main::$0
plus::a#1 = '1'
plus::b#1 = 6
call plus
plus::return#1 = plus::return#3
to:main::@2
main::@2: scope:[main] from main::@1
plus::return#5 = phi( main::@1/plus::return#1 )
main::$1 = plus::return#5
SCREEN[1] = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
return return
to:@return to:@return
char plus(char a , char b) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
plus::b#1 = phi( main/plus::b#0 ) plus::b#2 = phi( main/plus::b#0, main::@1/plus::b#1 )
plus::a#1 = phi( main/plus::a#0 ) plus::a#2 = phi( main/plus::a#0, main::@1/plus::a#1 )
min::a#0 = plus::a#1 add::a#0 = plus::a#2
min::b#0 = plus::b#1 add::b#0 = plus::b#2
call min call add
min::return#0 = min::return#2 add::return#0 = add::return#2
to:plus::@1 to:plus::@1
plus::@1: scope:[plus] from plus plus::@1: scope:[plus] from plus
min::return#3 = phi( plus/min::return#0 ) add::return#3 = phi( plus/add::return#0 )
plus::$0 = min::return#3 plus::$0 = add::return#3
plus::return#1 = plus::$0 plus::return#2 = plus::$0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus::@1 plus::@return: scope:[plus] from plus::@1
plus::return#4 = phi( plus::@1/plus::return#1 ) plus::return#6 = phi( plus::@1/plus::return#2 )
plus::return#2 = plus::return#4 plus::return#3 = plus::return#6
return return
to:@return to:@return
char min(char a , char b) char add(char a , char b)
min: scope:[min] from plus add: scope:[add] from plus
min::b#1 = phi( plus/min::b#0 ) add::b#1 = phi( plus/add::b#0 )
min::a#1 = phi( plus/min::a#0 ) add::a#1 = phi( plus/add::a#0 )
min::$0 = min::a#1 + min::b#1 add::$0 = add::a#1 + add::b#1
min::return#1 = min::$0 add::return#1 = add::$0
to:min::@return to:add::@return
min::@return: scope:[min] from min add::@return: scope:[add] from add
min::return#4 = phi( min/min::return#1 ) add::return#4 = phi( add/add::return#1 )
min::return#2 = min::return#4 add::return#2 = add::return#4
return return
to:@return to:@return
@ -64,64 +73,74 @@ __start::@return: scope:[__start] from __start::@1
SYMBOL TABLE SSA SYMBOL TABLE SSA
__constant char * const SCREEN = (char *)$400 __constant char * const SCREEN = (char *)$400
void __start() void __start()
char add(char a , char b)
char add::$0
char add::a
char add::a#0
char add::a#1
char add::b
char add::b#0
char add::b#1
char add::return
char add::return#0
char add::return#1
char add::return#2
char add::return#3
char add::return#4
void main() void main()
char main::$0 char main::$0
char min(char a , char b) char main::$1
char min::$0
char min::a
char min::a#0
char min::a#1
char min::b
char min::b#0
char min::b#1
char min::return
char min::return#0
char min::return#1
char min::return#2
char min::return#3
char min::return#4
char plus(char a , char b) char plus(char a , char b)
char plus::$0 char plus::$0
char plus::a char plus::a
char plus::a#0 char plus::a#0
char plus::a#1 char plus::a#1
char plus::a#2
char plus::b char plus::b
char plus::b#0 char plus::b#0
char plus::b#1 char plus::b#1
char plus::b#2
char plus::return char plus::return
char plus::return#0 char plus::return#0
char plus::return#1 char plus::return#1
char plus::return#2 char plus::return#2
char plus::return#3 char plus::return#3
char plus::return#4 char plus::return#4
char plus::return#5
char plus::return#6
Adding number conversion cast (unumber) 7 in plus::b#0 = 7 Adding number conversion cast (unumber) 7 in plus::b#0 = 7
Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0 Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0
Adding number conversion cast (unumber) 6 in plus::b#1 = 6
Adding number conversion cast (unumber) 1 in SCREEN[1] = main::$1
Successful SSA optimization PassNAddNumberTypeConversions Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast plus::b#0 = (unumber)7 Inlining cast plus::b#0 = (unumber)7
Inlining cast plus::b#1 = (unumber)6
Successful SSA optimization Pass2InlineCast Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (char *) 1024 Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast 7 Simplifying constant integer cast 7
Simplifying constant integer cast 0 Simplifying constant integer cast 0
Simplifying constant integer cast 6
Simplifying constant integer cast 1
Successful SSA optimization PassNCastSimplification Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 7 Finalized unsigned number type (char) 7
Finalized unsigned number type (char) 0 Finalized unsigned number type (char) 0
Finalized unsigned number type (char) 6
Finalized unsigned number type (char) 1
Successful SSA optimization PassNFinalizeNumberTypeConversions Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias plus::return#0 = plus::return#3 Alias plus::return#0 = plus::return#4
Alias min::return#0 = min::return#3 Alias plus::return#1 = plus::return#5
Alias plus::return#1 = plus::$0 plus::return#4 plus::return#2 Alias add::return#0 = add::return#3
Alias min::return#1 = min::$0 min::return#4 min::return#2 Alias plus::return#2 = plus::$0 plus::return#6 plus::return#3
Alias add::return#1 = add::$0 add::return#4 add::return#2
Successful SSA optimization Pass2AliasElimination Successful SSA optimization Pass2AliasElimination
Identical Phi Values plus::a#1 plus::a#0 Identical Phi Values add::a#1 add::a#0
Identical Phi Values plus::b#1 plus::b#0 Identical Phi Values add::b#1 add::b#0
Identical Phi Values min::a#1 min::a#0
Identical Phi Values min::b#1 min::b#0
Successful SSA optimization Pass2IdenticalPhiElimination Successful SSA optimization Pass2IdenticalPhiElimination
Constant plus::a#0 = '0' Constant plus::a#0 = '0'
Constant plus::b#0 = 7 Constant plus::b#0 = 7
Successful SSA optimization Pass2ConstantIdentification Constant plus::a#1 = '1'
Constant min::a#0 = plus::a#0 Constant plus::b#1 = 6
Constant min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantIdentification Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0 Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0
Successful SSA optimization PassNSimplifyExpressionWithZero Successful SSA optimization PassNSimplifyExpressionWithZero
@ -130,40 +149,25 @@ Removing unused procedure block __start
Removing unused procedure block __start::@1 Removing unused procedure block __start::@1
Removing unused procedure block __start::@return Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart Successful SSA optimization PassNEliminateEmptyStart
Constant right-side identified [9] min::return#1 = min::a#0 + min::b#0 Inlining constant with var siblings plus::a#0
Successful SSA optimization Pass2ConstantRValueConsolidation Inlining constant with var siblings plus::b#0
Constant min::return#1 = min::a#0+min::b#0 Inlining constant with var siblings plus::a#1
Successful SSA optimization Pass2ConstantIdentification Inlining constant with var siblings plus::b#1
Constant min::return#0 = min::return#1 Constant inlined plus::b#1 = 6
Successful SSA optimization Pass2ConstantIdentification Constant inlined plus::b#0 = 7
Constant plus::return#1 = min::return#0 Constant inlined plus::a#1 = '1'
Successful SSA optimization Pass2ConstantIdentification Constant inlined plus::a#0 = '0'
Constant plus::return#0 = plus::return#1
Successful SSA optimization Pass2ConstantIdentification
Constant main::$0 = plus::return#0
Successful SSA optimization Pass2ConstantIdentification
Inlining constant with different constant siblings min::return#0
Constant inlined plus::return#0 = min::return#1
Constant inlined main::$0 = min::return#1
Constant inlined plus::return#1 = min::return#1
Constant inlined min::a#0 = plus::a#0
Constant inlined min::return#0 = min::return#1
Constant inlined min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantInlining Successful SSA optimization Pass2ConstantInlining
Consolidated array index constant in *(SCREEN+1)
Successful SSA optimization Pass2ConstantAdditionElimination
Adding NOP phi() at start of main Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of plus::@1
Adding NOP phi() at start of min
CALL GRAPH CALL GRAPH
Calls in [main] to plus:1 Calls in [main] to plus:1 plus:5
Calls in [plus] to min:5 Calls in [plus] to add:13
Created 0 initial phi equivalence classes Created 2 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes Coalesced down to 2 phi equivalence classes
Culled Empty Block label plus::@1
Adding NOP phi() at start of main Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of min
FINAL CONTROL FLOW GRAPH FINAL CONTROL FLOW GRAPH
@ -171,58 +175,135 @@ void main()
main: scope:[main] from main: scope:[main] from
[0] phi() [0] phi()
[1] call plus [1] call plus
[2] plus::return#0 = plus::return#2
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
[2] *SCREEN = min::return#1 [3] main::$0 = plus::return#0
[4] *SCREEN = main::$0
[5] call plus
[6] plus::return#1 = plus::return#2
to:main::@2
main::@2: scope:[main] from main::@1
[7] main::$1 = plus::return#1
[8] *(SCREEN+1) = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
[3] return [9] return
to:@return to:@return
char plus(char a , char b) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
[4] phi() [10] plus::b#2 = phi( main/7, main::@1/6 )
[5] call min [10] plus::a#2 = phi( main/'0', main::@1/'1' )
[11] add::a#0 = plus::a#2
[12] add::b#0 = plus::b#2
[13] call add
[14] add::return#0 = add::return#1
to:plus::@1
plus::@1: scope:[plus] from plus
[15] plus::return#2 = add::return#0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus::@1
[6] return [16] return
to:@return to:@return
char min(char a , char b) char add(char a , char b)
min: scope:[min] from plus add: scope:[add] from plus
[7] phi() [17] add::return#1 = add::a#0 + add::b#0
to:min::@return to:add::@return
min::@return: scope:[min] from min add::@return: scope:[add] from add
[8] return [18] return
to:@return to:@return
VARIABLE REGISTER WEIGHTS VARIABLE REGISTER WEIGHTS
char add(char a , char b)
char add::a
char add::a#0 // 56.0
char add::b
char add::b#0 // 112.0
char add::return
char add::return#0 // 22.0
char add::return#1 // 37.33333333333333
void main() void main()
char min(char a , char b) char main::$0 // 4.0
char min::a char main::$1 // 4.0
char min::b
char min::return
char plus(char a , char b) char plus(char a , char b)
char plus::a char plus::a
char plus::a#2 // 11.0
char plus::b char plus::b
char plus::b#2 // 5.5
char plus::return char plus::return
char plus::return#0 // 4.0
char plus::return#1 // 4.0
char plus::return#2 // 3.75
Initial phi equivalence classes Initial phi equivalence classes
[ plus::a#2 ]
[ plus::b#2 ]
Added variable plus::return#0 to live range equivalence class [ plus::return#0 ]
Added variable main::$0 to live range equivalence class [ main::$0 ]
Added variable plus::return#1 to live range equivalence class [ plus::return#1 ]
Added variable main::$1 to live range equivalence class [ main::$1 ]
Added variable add::a#0 to live range equivalence class [ add::a#0 ]
Added variable add::b#0 to live range equivalence class [ add::b#0 ]
Added variable add::return#0 to live range equivalence class [ add::return#0 ]
Added variable plus::return#2 to live range equivalence class [ plus::return#2 ]
Added variable add::return#1 to live range equivalence class [ add::return#1 ]
Complete equivalence classes Complete equivalence classes
[ plus::a#2 ]
[ plus::b#2 ]
[ plus::return#0 ]
[ main::$0 ]
[ plus::return#1 ]
[ main::$1 ]
[ add::a#0 ]
[ add::b#0 ]
[ add::return#0 ]
[ plus::return#2 ]
[ add::return#1 ]
Allocated zp[1]:2 [ add::b#0 ]
Allocated zp[1]:3 [ add::a#0 ]
Allocated zp[1]:4 [ add::return#1 ]
Allocated zp[1]:5 [ add::return#0 ]
Allocated zp[1]:6 [ plus::a#2 ]
Allocated zp[1]:7 [ plus::b#2 ]
Allocated zp[1]:8 [ plus::return#0 ]
Allocated zp[1]:9 [ main::$0 ]
Allocated zp[1]:10 [ plus::return#1 ]
Allocated zp[1]:11 [ main::$1 ]
Allocated zp[1]:12 [ plus::return#2 ]
REGISTER UPLIFT POTENTIAL REGISTERS REGISTER UPLIFT POTENTIAL REGISTERS
Statement [2] *SCREEN = min::return#1 [ ] ( [ ] { } ) always clobbers reg byte a Statement [17] add::return#1 = add::a#0 + add::b#0 [ add::return#1 ] ( plus:1::add:13 [ add::return#1 ] { { plus::return#0 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } plus:5::add:13 [ add::return#1 ] { { plus::return#1 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } ) always clobbers reg byte a
Potential registers zp[1]:6 [ plus::a#2 ] : zp[1]:6 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:7 [ plus::b#2 ] : zp[1]:7 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:8 [ plus::return#0 ] : zp[1]:8 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:9 [ main::$0 ] : zp[1]:9 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:10 [ plus::return#1 ] : zp[1]:10 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:11 [ main::$1 ] : zp[1]:11 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:3 [ add::a#0 ] : zp[1]:3 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:2 [ add::b#0 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:5 [ add::return#0 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:12 [ plus::return#2 ] : zp[1]:12 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:4 [ add::return#1 ] : zp[1]:4 , reg byte a , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES REGISTER UPLIFT SCOPES
Uplift Scope [main] Uplift Scope [add] 112: zp[1]:2 [ add::b#0 ] 56: zp[1]:3 [ add::a#0 ] 37.33: zp[1]:4 [ add::return#1 ] 22: zp[1]:5 [ add::return#0 ]
Uplift Scope [plus] Uplift Scope [plus] 11: zp[1]:6 [ plus::a#2 ] 5.5: zp[1]:7 [ plus::b#2 ] 4: zp[1]:8 [ plus::return#0 ] 4: zp[1]:10 [ plus::return#1 ] 3.75: zp[1]:12 [ plus::return#2 ]
Uplift Scope [min] Uplift Scope [main] 4: zp[1]:9 [ main::$0 ] 4: zp[1]:11 [ main::$1 ]
Uplift Scope [] Uplift Scope []
Uplifting [main] best 75 combination Uplifting [add] best 129 combination reg byte a [ add::b#0 ] zp[1]:3 [ add::a#0 ] reg byte a [ add::return#1 ] reg byte a [ add::return#0 ]
Uplifting [plus] best 75 combination Limited combination testing to 100 combinations of 256 possible.
Uplifting [min] best 75 combination Uplifting [plus] best 99 combination reg byte x [ plus::a#2 ] reg byte a [ plus::b#2 ] reg byte a [ plus::return#0 ] reg byte a [ plus::return#1 ] zp[1]:12 [ plus::return#2 ]
Uplifting [] best 75 combination Limited combination testing to 100 combinations of 1024 possible.
Uplifting [main] best 87 combination reg byte a [ main::$0 ] reg byte a [ main::$1 ]
Uplifting [] best 87 combination
Attempting to uplift remaining variables inzp[1]:3 [ add::a#0 ]
Uplifting [add] best 87 combination zp[1]:3 [ add::a#0 ]
Attempting to uplift remaining variables inzp[1]:12 [ plus::return#2 ]
Uplifting [plus] best 78 combination reg byte a [ plus::return#2 ]
Allocated (was zp[1]:3) zp[1]:2 [ add::a#0 ]
ASSEMBLER BEFORE OPTIMIZATION ASSEMBLER BEFORE OPTIMIZATION
// File Comments // File Comments
@ -273,81 +354,133 @@ ASSEMBLER BEFORE OPTIMIZATION
// main // main
main: { main: {
// [1] call plus // [1] call plus
// [4] phi from main to plus [phi:main->plus] // [10] phi from main to plus [phi:main->plus]
plus_from_main: plus_from_main:
// [10] phi plus::b#2 = 7 [phi:main->plus#0] -- vbuaa=vbuc1
lda #7
// [10] phi plus::a#2 = '0' [phi:main->plus#1] -- vbuxx=vbuc1
ldx #'0'
jsr plus jsr plus
// [2] plus::return#0 = plus::return#2
jmp __b1 jmp __b1
// main::@1 // main::@1
__b1: __b1:
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2 // [3] main::$0 = plus::return#0
lda #min.return // [4] *SCREEN = main::$0 -- _deref_pbuc1=vbuaa
sta SCREEN sta SCREEN
// [5] call plus
// [10] phi from main::@1 to plus [phi:main::@1->plus]
plus_from___b1:
// [10] phi plus::b#2 = 6 [phi:main::@1->plus#0] -- vbuaa=vbuc1
lda #6
// [10] phi plus::a#2 = '1' [phi:main::@1->plus#1] -- vbuxx=vbuc1
ldx #'1'
jsr plus
// [6] plus::return#1 = plus::return#2
jmp __b2
// main::@2
__b2:
// [7] main::$1 = plus::return#1
// [8] *(SCREEN+1) = main::$1 -- _deref_pbuc1=vbuaa
// near call
sta SCREEN+1
jmp __breturn jmp __breturn
// main::@return // main::@return
__breturn: __breturn:
// [3] return // [9] return
rts rts
} }
// plus // plus
// char plus(char a, char b) // __register(A) char plus(__register(X) char a, __register(A) char b)
plus: { plus: {
.label a = '0' // [11] add::a#0 = plus::a#2 -- vbuz1=vbuxx
.label b = 7 stx.z add.a
// [5] call min // [12] add::b#0 = plus::b#2
// [7] phi from plus to min [phi:plus->min] // [13] call add
min_from_plus: jsr add
jsr min // [14] add::return#0 = add::return#1
jmp __b1
// plus::@1
__b1:
// [15] plus::return#2 = add::return#0
jmp __breturn jmp __breturn
// plus::@return // plus::@return
__breturn: __breturn:
// [6] return // [16] return
rts rts
} }
// min // add
// char min(char a, char b) // __register(A) char add(__zp(2) char a, __register(A) char b)
min: { add: {
.label return = plus.a+plus.b .label a = 2
// [17] add::return#1 = add::a#0 + add::b#0 -- vbuaa=vbuz1_plus_vbuaa
clc
adc.z a
jmp __breturn jmp __breturn
// min::@return // add::@return
__breturn: __breturn:
// [8] return // [18] return
rts rts
} }
// File Data // File Data
ASSEMBLER OPTIMIZATIONS ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1 Removing instruction jmp __b1
Removing instruction jmp __b2
Removing instruction jmp __breturn Removing instruction jmp __breturn
Removing instruction jmp __b1
Removing instruction jmp __breturn Removing instruction jmp __breturn
Removing instruction jmp __breturn Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination Succesful ASM optimization Pass5NextJumpElimination
Removing instruction __breturn:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction plus_from_main: Removing instruction plus_from_main:
Removing instruction __b1: Removing instruction __b1:
Removing instruction plus_from___b1:
Removing instruction __b2:
Removing instruction __breturn: Removing instruction __breturn:
Removing instruction min_from_plus: Removing instruction __b1:
Removing instruction __breturn:
Removing instruction __breturn: Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE FINAL SYMBOL TABLE
__constant char * const SCREEN = (char *) 1024 __constant char * const SCREEN = (char *) 1024
char add(char a , char b)
char add::a
char add::a#0 // a zp[1]:2 56.0
char add::b
char add::b#0 // reg byte a 112.0
char add::return
char add::return#0 // reg byte a 22.0
char add::return#1 // reg byte a 37.33333333333333
void main() void main()
char min(char a , char b) char main::$0 // reg byte a 4.0
char min::a char main::$1 // reg byte a 4.0
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
char plus(char a , char b) char plus(char a , char b)
char plus::a char plus::a
__constant char plus::a#0 = '0' // a char plus::a#2 // reg byte x 11.0
char plus::b char plus::b
__constant char plus::b#0 = 7 // b char plus::b#2 // reg byte a 5.5
char plus::return char plus::return
char plus::return#0 // reg byte a 4.0
char plus::return#1 // reg byte a 4.0
char plus::return#2 // reg byte a 3.75
reg byte x [ plus::a#2 ]
reg byte a [ plus::b#2 ]
reg byte a [ plus::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ plus::return#1 ]
reg byte a [ main::$1 ]
zp[1]:2 [ add::a#0 ]
reg byte a [ add::b#0 ]
reg byte a [ add::return#0 ]
reg byte a [ plus::return#2 ]
reg byte a [ add::return#1 ]
FINAL ASSEMBLER FINAL ASSEMBLER
Score: 36 Score: 60
// File Comments // File Comments
/** /**
@ -398,38 +531,68 @@ Score: 36
main: { main: {
// plus('0', 7) // plus('0', 7)
// [1] call plus // [1] call plus
// [4] phi from main to plus [phi:main->plus] // [10] phi from main to plus [phi:main->plus]
// [10] phi plus::b#2 = 7 [phi:main->plus#0] -- vbuaa=vbuc1
lda #7
// [10] phi plus::a#2 = '0' [phi:main->plus#1] -- vbuxx=vbuc1
ldx #'0'
jsr plus jsr plus
// plus('0', 7)
// [2] plus::return#0 = plus::return#2
// main::@1 // main::@1
// [3] main::$0 = plus::return#0
// SCREEN[0] = plus('0', 7) // SCREEN[0] = plus('0', 7)
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2 // [4] *SCREEN = main::$0 -- _deref_pbuc1=vbuaa
lda #min.return
sta SCREEN sta SCREEN
// plus('1', 6)
// [5] call plus
// [10] phi from main::@1 to plus [phi:main::@1->plus]
// [10] phi plus::b#2 = 6 [phi:main::@1->plus#0] -- vbuaa=vbuc1
lda #6
// [10] phi plus::a#2 = '1' [phi:main::@1->plus#1] -- vbuxx=vbuc1
ldx #'1'
jsr plus
// plus('1', 6)
// [6] plus::return#1 = plus::return#2
// main::@2
// [7] main::$1 = plus::return#1
// SCREEN[1] = plus('1', 6)
// [8] *(SCREEN+1) = main::$1 -- _deref_pbuc1=vbuaa
// near call
sta SCREEN+1
// main::@return // main::@return
// } // }
// [3] return // [9] return
rts rts
} }
// plus // plus
// char plus(char a, char b) // __register(A) char plus(__register(X) char a, __register(A) char b)
plus: { plus: {
.label a = '0' // add(a, b)
.label b = 7 // [11] add::a#0 = plus::a#2 -- vbuz1=vbuxx
// min(a, b) stx.z add.a
// [5] call min // [12] add::b#0 = plus::b#2
// [7] phi from plus to min [phi:plus->min] // [13] call add
jsr min jsr add
// [14] add::return#0 = add::return#1
// plus::@1
// [15] plus::return#2 = add::return#0
// plus::@return // plus::@return
// } // }
// [6] return // [16] return
rts rts
} }
// min // add
// char min(char a, char b) // __register(A) char add(__zp(2) char a, __register(A) char b)
min: { add: {
.label return = plus.a+plus.b .label a = 2
// min::@return // a+b
// [8] return // [17] add::return#1 = add::a#0 + add::b#0 -- vbuaa=vbuz1_plus_vbuaa
clc
adc.z a
// add::@return
// }
// [18] return
rts rts
} }
// File Data // File Data

View File

@ -1,14 +1,33 @@
__constant char * const SCREEN = (char *) 1024 __constant char * const SCREEN = (char *) 1024
char add(char a , char b)
char add::a
char add::a#0 // a zp[1]:2 56.0
char add::b
char add::b#0 // reg byte a 112.0
char add::return
char add::return#0 // reg byte a 22.0
char add::return#1 // reg byte a 37.33333333333333
void main() void main()
char min(char a , char b) char main::$0 // reg byte a 4.0
char min::a char main::$1 // reg byte a 4.0
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
char plus(char a , char b) char plus(char a , char b)
char plus::a char plus::a
__constant char plus::a#0 = '0' // a char plus::a#2 // reg byte x 11.0
char plus::b char plus::b
__constant char plus::b#0 = 7 // b char plus::b#2 // reg byte a 5.5
char plus::return char plus::return
char plus::return#0 // reg byte a 4.0
char plus::return#1 // reg byte a 4.0
char plus::return#2 // reg byte a 3.75
reg byte x [ plus::a#2 ]
reg byte a [ plus::b#2 ]
reg byte a [ plus::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ plus::return#1 ]
reg byte a [ main::$1 ]
zp[1]:2 [ add::a#0 ]
reg byte a [ add::b#0 ]
reg byte a [ add::return#0 ]
reg byte a [ plus::return#2 ]
reg byte a [ add::return#1 ]

View File

@ -43,25 +43,54 @@
.segment Code .segment Code
main: { main: {
// plus('0', 7) // plus('0', 7)
ldx #7
lda #'0'
sta.z $ff
lda.z 0 lda.z 0
pha pha
lda #1 lda #1
sta.z 0 sta.z 0
lda.z $ff
jsr plus jsr plus
sta.z $ff
pla pla
sta.z 0 sta.z 0
lda.z $ff
// plus('0', 7)
txa
// SCREEN[0] = plus('0', 7) // SCREEN[0] = plus('0', 7)
lda #plus.return
sta SCREEN sta SCREEN
// plus('1', 6)
ldx #6
lda #'1'
sta.z $ff
lda.z 0
pha
lda #1
sta.z 0
lda.z $ff
jsr plus
sta.z $ff
pla
sta.z 0
lda.z $ff
// plus('1', 6)
txa
// SCREEN[1] = plus('1', 6)
// close call
sta SCREEN+1
// } // }
rts rts
} }
.segment RAM_Bank1 .segment RAM_Bank1
// char plus(char a, char b) // __register(X) char plus(__register(A) char a, __register(X) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
plus: { plus: {
.const a = '0' // a+b
.const b = 7 stx.z $ff
.label return = a+b clc
adc.z $ff
tax
// }
rts rts
} }

View File

@ -3,18 +3,28 @@ void main()
main: scope:[main] from main: scope:[main] from
[0] phi() [0] phi()
[1] call plus [1] call plus
[2] plus::return#0 = plus::return#2
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
[2] *SCREEN = plus::return#1 [3] main::$0 = plus::return#0
[4] *SCREEN = main::$0
[5] call plus
[6] plus::return#1 = plus::return#2
to:main::@2
main::@2: scope:[main] from main::@1
[7] main::$1 = plus::return#1
[8] *(SCREEN+1) = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
[3] return [9] return
to:@return to:@return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
[4] phi() [10] plus::b#2 = phi( main/7, main::@1/6 )
[10] plus::a#2 = phi( main/'0', main::@1/'1' )
[11] plus::return#2 = plus::a#2 + plus::b#2
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus
[5] return [12] return
to:@return to:@return

View File

@ -7,27 +7,36 @@ main: scope:[main] from __start
plus::a#0 = '0' plus::a#0 = '0'
plus::b#0 = 7 plus::b#0 = 7
call plus call plus
plus::return#0 = plus::return#2 plus::return#0 = plus::return#3
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
plus::return#3 = phi( main/plus::return#0 ) plus::return#4 = phi( main/plus::return#0 )
main::$0 = plus::return#3 main::$0 = plus::return#4
SCREEN[0] = main::$0 SCREEN[0] = main::$0
plus::a#1 = '1'
plus::b#1 = 6
call plus
plus::return#1 = plus::return#3
to:main::@2
main::@2: scope:[main] from main::@1
plus::return#5 = phi( main::@1/plus::return#1 )
main::$1 = plus::return#5
SCREEN[1] = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
return return
to:@return to:@return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
plus::b#1 = phi( main/plus::b#0 ) plus::b#2 = phi( main/plus::b#0, main::@1/plus::b#1 )
plus::a#1 = phi( main/plus::a#0 ) plus::a#2 = phi( main/plus::a#0, main::@1/plus::a#1 )
plus::$0 = plus::a#1 + plus::b#1 plus::$0 = plus::a#2 + plus::b#2
plus::return#1 = plus::$0 plus::return#2 = plus::$0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus
plus::return#4 = phi( plus/plus::return#1 ) plus::return#6 = phi( plus/plus::return#2 )
plus::return#2 = plus::return#4 plus::return#3 = plus::return#6
return return
to:@return to:@return
@ -46,41 +55,53 @@ __constant char * const SCREEN = (char *)$400
void __start() void __start()
void main() void main()
char main::$0 char main::$0
char main::$1
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::$0 char plus::$0
char plus::a char plus::a
char plus::a#0 char plus::a#0
char plus::a#1 char plus::a#1
char plus::a#2
char plus::b char plus::b
char plus::b#0 char plus::b#0
char plus::b#1 char plus::b#1
char plus::b#2
char plus::return char plus::return
char plus::return#0 char plus::return#0
char plus::return#1 char plus::return#1
char plus::return#2 char plus::return#2
char plus::return#3 char plus::return#3
char plus::return#4 char plus::return#4
char plus::return#5
char plus::return#6
Adding number conversion cast (unumber) 7 in plus::b#0 = 7 Adding number conversion cast (unumber) 7 in plus::b#0 = 7
Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0 Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0
Adding number conversion cast (unumber) 6 in plus::b#1 = 6
Adding number conversion cast (unumber) 1 in SCREEN[1] = main::$1
Successful SSA optimization PassNAddNumberTypeConversions Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast plus::b#0 = (unumber)7 Inlining cast plus::b#0 = (unumber)7
Inlining cast plus::b#1 = (unumber)6
Successful SSA optimization Pass2InlineCast Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (char *) 1024 Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast 7 Simplifying constant integer cast 7
Simplifying constant integer cast 0 Simplifying constant integer cast 0
Simplifying constant integer cast 6
Simplifying constant integer cast 1
Successful SSA optimization PassNCastSimplification Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 7 Finalized unsigned number type (char) 7
Finalized unsigned number type (char) 0 Finalized unsigned number type (char) 0
Finalized unsigned number type (char) 6
Finalized unsigned number type (char) 1
Successful SSA optimization PassNFinalizeNumberTypeConversions Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias plus::return#0 = plus::return#3 Alias plus::return#0 = plus::return#4
Alias plus::return#1 = plus::$0 plus::return#4 plus::return#2 Alias plus::return#1 = plus::return#5
Alias plus::return#2 = plus::$0 plus::return#6 plus::return#3
Successful SSA optimization Pass2AliasElimination Successful SSA optimization Pass2AliasElimination
Identical Phi Values plus::a#1 plus::a#0
Identical Phi Values plus::b#1 plus::b#0
Successful SSA optimization Pass2IdenticalPhiElimination
Constant plus::a#0 = '0' Constant plus::a#0 = '0'
Constant plus::b#0 = 7 Constant plus::b#0 = 7
Constant plus::a#1 = '1'
Constant plus::b#1 = 6
Successful SSA optimization Pass2ConstantIdentification Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0 Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0
Successful SSA optimization PassNSimplifyExpressionWithZero Successful SSA optimization PassNSimplifyExpressionWithZero
@ -89,27 +110,24 @@ Removing unused procedure block __start
Removing unused procedure block __start::@1 Removing unused procedure block __start::@1
Removing unused procedure block __start::@return Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart Successful SSA optimization PassNEliminateEmptyStart
Constant right-side identified [5] plus::return#1 = plus::a#0 + plus::b#0 Inlining constant with var siblings plus::a#0
Successful SSA optimization Pass2ConstantRValueConsolidation Inlining constant with var siblings plus::b#0
Constant plus::return#1 = plus::a#0+plus::b#0 Inlining constant with var siblings plus::a#1
Successful SSA optimization Pass2ConstantIdentification Inlining constant with var siblings plus::b#1
Constant plus::return#0 = plus::return#1 Constant inlined plus::b#1 = 6
Successful SSA optimization Pass2ConstantIdentification Constant inlined plus::b#0 = 7
Constant main::$0 = plus::return#0 Constant inlined plus::a#1 = '1'
Successful SSA optimization Pass2ConstantIdentification Constant inlined plus::a#0 = '0'
Inlining constant with different constant siblings plus::return#0
Constant inlined plus::return#0 = plus::return#1
Constant inlined main::$0 = plus::return#1
Successful SSA optimization Pass2ConstantInlining Successful SSA optimization Pass2ConstantInlining
Consolidated array index constant in *(SCREEN+1)
Successful SSA optimization Pass2ConstantAdditionElimination
Adding NOP phi() at start of main Adding NOP phi() at start of main
Adding NOP phi() at start of plus
CALL GRAPH CALL GRAPH
Calls in [main] to plus:1 Calls in [main] to plus:1 plus:5
Created 0 initial phi equivalence classes Created 2 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes Coalesced down to 2 phi equivalence classes
Adding NOP phi() at start of main Adding NOP phi() at start of main
Adding NOP phi() at start of plus
FINAL CONTROL FLOW GRAPH FINAL CONTROL FLOW GRAPH
@ -117,44 +135,97 @@ void main()
main: scope:[main] from main: scope:[main] from
[0] phi() [0] phi()
[1] call plus [1] call plus
[2] plus::return#0 = plus::return#2
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
[2] *SCREEN = plus::return#1 [3] main::$0 = plus::return#0
[4] *SCREEN = main::$0
[5] call plus
[6] plus::return#1 = plus::return#2
to:main::@2
main::@2: scope:[main] from main::@1
[7] main::$1 = plus::return#1
[8] *(SCREEN+1) = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
[3] return [9] return
to:@return to:@return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
[4] phi() [10] plus::b#2 = phi( main/7, main::@1/6 )
[10] plus::a#2 = phi( main/'0', main::@1/'1' )
[11] plus::return#2 = plus::a#2 + plus::b#2
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus
[5] return [12] return
to:@return to:@return
VARIABLE REGISTER WEIGHTS VARIABLE REGISTER WEIGHTS
void main() void main()
char main::$0 // 4.0
char main::$1 // 4.0
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::a char plus::a
char plus::a#2 // 11.0
char plus::b char plus::b
char plus::b#2 // 11.0
char plus::return char plus::return
char plus::return#0 // 4.0
char plus::return#1 // 4.0
char plus::return#2 // 3.75
Initial phi equivalence classes Initial phi equivalence classes
[ plus::a#2 ]
[ plus::b#2 ]
Added variable plus::return#0 to live range equivalence class [ plus::return#0 ]
Added variable main::$0 to live range equivalence class [ main::$0 ]
Added variable plus::return#1 to live range equivalence class [ plus::return#1 ]
Added variable main::$1 to live range equivalence class [ main::$1 ]
Added variable plus::return#2 to live range equivalence class [ plus::return#2 ]
Complete equivalence classes Complete equivalence classes
[ plus::a#2 ]
[ plus::b#2 ]
[ plus::return#0 ]
[ main::$0 ]
[ plus::return#1 ]
[ main::$1 ]
[ plus::return#2 ]
Allocated zp[1]:2 [ plus::a#2 ]
Allocated zp[1]:3 [ plus::b#2 ]
Allocated zp[1]:4 [ plus::return#0 ]
Allocated zp[1]:5 [ main::$0 ]
Allocated zp[1]:6 [ plus::return#1 ]
Allocated zp[1]:7 [ main::$1 ]
Allocated zp[1]:8 [ plus::return#2 ]
REGISTER UPLIFT POTENTIAL REGISTERS REGISTER UPLIFT POTENTIAL REGISTERS
Statement [1] call plus [ ] ( [ ] { } ) always clobbers reg byte a Statement [1] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#0 = plus::return#2 } } ) always clobbers reg byte a
Statement [2] *SCREEN = plus::return#1 [ ] ( [ ] { } ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:8 [ plus::return#2 ]
Statement [5] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#1 = plus::return#2 } } ) always clobbers reg byte a
Statement [11] plus::return#2 = plus::a#2 + plus::b#2 [ plus::return#2 ] ( plus:1 [ plus::return#2 ] { { plus::return#0 = plus::return#2 } } plus:5 [ plus::return#2 ] { { plus::return#1 = plus::return#2 } } ) always clobbers reg byte a
Statement [1] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#0 = plus::return#2 } } ) always clobbers reg byte a
Statement [5] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#1 = plus::return#2 } } ) always clobbers reg byte a
Statement [11] plus::return#2 = plus::a#2 + plus::b#2 [ plus::return#2 ] ( plus:1 [ plus::return#2 ] { { plus::return#0 = plus::return#2 } } plus:5 [ plus::return#2 ] { { plus::return#1 = plus::return#2 } } ) always clobbers reg byte a
Potential registers zp[1]:2 [ plus::a#2 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:3 [ plus::b#2 ] : zp[1]:3 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:4 [ plus::return#0 ] : zp[1]:4 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:5 [ main::$0 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:6 [ plus::return#1 ] : zp[1]:6 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:7 [ main::$1 ] : zp[1]:7 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:8 [ plus::return#2 ] : zp[1]:8 , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES REGISTER UPLIFT SCOPES
Uplift Scope [main] Uplift Scope [plus] 11: zp[1]:2 [ plus::a#2 ] 11: zp[1]:3 [ plus::b#2 ] 4: zp[1]:4 [ plus::return#0 ] 4: zp[1]:6 [ plus::return#1 ] 3.75: zp[1]:8 [ plus::return#2 ]
Uplift Scope [plus] Uplift Scope [main] 4: zp[1]:5 [ main::$0 ] 4: zp[1]:7 [ main::$1 ]
Uplift Scope [] Uplift Scope []
Uplifting [main] best 78 combination Uplifting [plus] best 141 combination reg byte a [ plus::a#2 ] reg byte x [ plus::b#2 ] reg byte a [ plus::return#0 ] reg byte a [ plus::return#1 ] zp[1]:8 [ plus::return#2 ]
Uplifting [plus] best 78 combination Limited combination testing to 100 combinations of 768 possible.
Uplifting [] best 78 combination Uplifting [main] best 129 combination reg byte a [ main::$0 ] reg byte a [ main::$1 ]
Uplifting [] best 129 combination
Attempting to uplift remaining variables inzp[1]:8 [ plus::return#2 ]
Uplifting [plus] best 126 combination reg byte x [ plus::return#2 ]
ASSEMBLER BEFORE OPTIMIZATION ASSEMBLER BEFORE OPTIMIZATION
// File Comments // File Comments
@ -206,50 +277,92 @@ ASSEMBLER BEFORE OPTIMIZATION
// main // main
main: { main: {
// [1] call plus // [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_phi_close_cx16_ram // [10] phi from main to plus [phi:main->plus]
plus_from_main: plus_from_main:
// [10] phi plus::b#2 = 7 [phi:main->plus#0] -- vbuxx=vbuc1
ldx #7
// [10] phi plus::a#2 = '0' [phi:main->plus#1] -- call_phi_close_cx16_ram
lda #'0'
sta.z $ff
lda.z 0 lda.z 0
pha pha
lda #1 lda #1
sta.z 0 sta.z 0
lda.z $ff
jsr plus jsr plus
sta.z $ff
pla pla
sta.z 0 sta.z 0
lda.z $ff
// [2] plus::return#0 = plus::return#2 -- vbuaa=vbuxx
txa
jmp __b1 jmp __b1
// main::@1 // main::@1
__b1: __b1:
// [2] *SCREEN = plus::return#1 -- _deref_pbuc1=vbuc2 // [3] main::$0 = plus::return#0
lda #plus.return // [4] *SCREEN = main::$0 -- _deref_pbuc1=vbuaa
sta SCREEN sta SCREEN
// [5] call plus
// [10] phi from main::@1 to plus [phi:main::@1->plus]
plus_from___b1:
// [10] phi plus::b#2 = 6 [phi:main::@1->plus#0] -- vbuxx=vbuc1
ldx #6
// [10] phi plus::a#2 = '1' [phi:main::@1->plus#1] -- call_phi_close_cx16_ram
lda #'1'
sta.z $ff
lda.z 0
pha
lda #1
sta.z 0
lda.z $ff
jsr plus
sta.z $ff
pla
sta.z 0
lda.z $ff
// [6] plus::return#1 = plus::return#2 -- vbuaa=vbuxx
txa
jmp __b2
// main::@2
__b2:
// [7] main::$1 = plus::return#1
// [8] *(SCREEN+1) = main::$1 -- _deref_pbuc1=vbuaa
// close call
sta SCREEN+1
jmp __breturn jmp __breturn
// main::@return // main::@return
__breturn: __breturn:
// [3] return // [9] return
rts rts
} }
.segment RAM_Bank1 .segment RAM_Bank1
// plus // plus
// char plus(char a, char b) // __register(X) char plus(__register(A) char a, __register(X) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
plus: { plus: {
.const a = '0' // [11] plus::return#2 = plus::a#2 + plus::b#2 -- vbuxx=vbuaa_plus_vbuxx
.const b = 7 stx.z $ff
.label return = a+b clc
adc.z $ff
tax
jmp __breturn jmp __breturn
// plus::@return // plus::@return
__breturn: __breturn:
// [5] return // [12] return
rts rts
} }
// File Data // File Data
ASSEMBLER OPTIMIZATIONS ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1 Removing instruction jmp __b1
Removing instruction jmp __b2
Removing instruction jmp __breturn Removing instruction jmp __breturn
Removing instruction jmp __breturn Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination Succesful ASM optimization Pass5NextJumpElimination
Removing instruction plus_from_main: Removing instruction plus_from_main:
Removing instruction __b1: Removing instruction __b1:
Removing instruction plus_from___b1:
Removing instruction __b2:
Removing instruction __breturn: Removing instruction __breturn:
Removing instruction __breturn: Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination Succesful ASM optimization Pass5UnusedLabelElimination
@ -257,18 +370,29 @@ Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE FINAL SYMBOL TABLE
__constant char * const SCREEN = (char *) 1024 __constant char * const SCREEN = (char *) 1024
void main() void main()
char main::$0 // reg byte a 4.0
char main::$1 // reg byte a 4.0
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::a char plus::a
__constant char plus::a#0 = '0' // a char plus::a#2 // reg byte a 11.0
char plus::b char plus::b
__constant char plus::b#0 = 7 // b char plus::b#2 // reg byte x 11.0
char plus::return char plus::return
__constant char plus::return#1 = plus::a#0+plus::b#0 // return char plus::return#0 // reg byte a 4.0
char plus::return#1 // reg byte a 4.0
char plus::return#2 // reg byte x 3.75
reg byte a [ plus::a#2 ]
reg byte x [ plus::b#2 ]
reg byte a [ plus::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ plus::return#1 ]
reg byte a [ main::$1 ]
reg byte x [ plus::return#2 ]
FINAL ASSEMBLER FINAL ASSEMBLER
Score: 42 Score: 114
// File Comments // File Comments
/** /**
@ -320,34 +444,76 @@ Score: 42
main: { main: {
// plus('0', 7) // plus('0', 7)
// [1] call plus // [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_phi_close_cx16_ram // [10] phi from main to plus [phi:main->plus]
// [10] phi plus::b#2 = 7 [phi:main->plus#0] -- vbuxx=vbuc1
ldx #7
// [10] phi plus::a#2 = '0' [phi:main->plus#1] -- call_phi_close_cx16_ram
lda #'0'
sta.z $ff
lda.z 0 lda.z 0
pha pha
lda #1 lda #1
sta.z 0 sta.z 0
lda.z $ff
jsr plus jsr plus
sta.z $ff
pla pla
sta.z 0 sta.z 0
lda.z $ff
// plus('0', 7)
// [2] plus::return#0 = plus::return#2 -- vbuaa=vbuxx
txa
// main::@1 // main::@1
// [3] main::$0 = plus::return#0
// SCREEN[0] = plus('0', 7) // SCREEN[0] = plus('0', 7)
// [2] *SCREEN = plus::return#1 -- _deref_pbuc1=vbuc2 // [4] *SCREEN = main::$0 -- _deref_pbuc1=vbuaa
lda #plus.return
sta SCREEN sta SCREEN
// plus('1', 6)
// [5] call plus
// [10] phi from main::@1 to plus [phi:main::@1->plus]
// [10] phi plus::b#2 = 6 [phi:main::@1->plus#0] -- vbuxx=vbuc1
ldx #6
// [10] phi plus::a#2 = '1' [phi:main::@1->plus#1] -- call_phi_close_cx16_ram
lda #'1'
sta.z $ff
lda.z 0
pha
lda #1
sta.z 0
lda.z $ff
jsr plus
sta.z $ff
pla
sta.z 0
lda.z $ff
// plus('1', 6)
// [6] plus::return#1 = plus::return#2 -- vbuaa=vbuxx
txa
// main::@2
// [7] main::$1 = plus::return#1
// SCREEN[1] = plus('1', 6)
// [8] *(SCREEN+1) = main::$1 -- _deref_pbuc1=vbuaa
// close call
sta SCREEN+1
// main::@return // main::@return
// } // }
// [3] return // [9] return
rts rts
} }
.segment RAM_Bank1 .segment RAM_Bank1
// plus // plus
// char plus(char a, char b) // __register(X) char plus(__register(A) char a, __register(X) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
plus: { plus: {
.const a = '0' // a+b
.const b = 7 // [11] plus::return#2 = plus::a#2 + plus::b#2 -- vbuxx=vbuaa_plus_vbuxx
.label return = a+b stx.z $ff
clc
adc.z $ff
tax
// plus::@return // plus::@return
// [5] return // }
// [12] return
rts rts
} }
// File Data // File Data

View File

@ -1,10 +1,21 @@
__constant char * const SCREEN = (char *) 1024 __constant char * const SCREEN = (char *) 1024
void main() void main()
char main::$0 // reg byte a 4.0
char main::$1 // reg byte a 4.0
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::a char plus::a
__constant char plus::a#0 = '0' // a char plus::a#2 // reg byte a 11.0
char plus::b char plus::b
__constant char plus::b#0 = 7 // b char plus::b#2 // reg byte x 11.0
char plus::return char plus::return
__constant char plus::return#1 = plus::a#0+plus::b#0 // return char plus::return#0 // reg byte a 4.0
char plus::return#1 // reg byte a 4.0
char plus::return#2 // reg byte x 3.75
reg byte a [ plus::a#2 ]
reg byte x [ plus::b#2 ]
reg byte a [ plus::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ plus::return#1 ]
reg byte a [ main::$1 ]
reg byte x [ plus::return#2 ]

View File

@ -43,25 +43,54 @@
.segment Code .segment Code
main: { main: {
// plus('0', 7) // plus('0', 7)
ldx #7
lda #'0'
sta.z $ff
lda.z 0 lda.z 0
pha pha
lda #1 lda #1
sta.z 0 sta.z 0
lda.z $ff
jsr plus jsr plus
sta.z $ff
pla pla
sta.z 0 sta.z 0
lda.z $ff
// plus('0', 7)
txa
// SCREEN[0] = plus('0', 7) // SCREEN[0] = plus('0', 7)
lda #plus.return
sta SCREEN sta SCREEN
// plus('1', 6)
ldx #6
lda #'1'
sta.z $ff
lda.z 0
pha
lda #1
sta.z 0
lda.z $ff
jsr plus
sta.z $ff
pla
sta.z 0
lda.z $ff
// plus('1', 6)
txa
// SCREEN[1] = plus('1', 6)
// close call
sta SCREEN+1
// } // }
rts rts
} }
.segment RAM_Bank1 .segment RAM_Bank1
// char plus(char a, char b) // __register(X) char plus(__register(A) char a, __register(X) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
plus: { plus: {
.const a = '0' // a+b
.const b = 7 stx.z $ff
.label return = a+b clc
adc.z $ff
tax
// }
rts rts
} }

View File

@ -3,18 +3,28 @@ void main()
main: scope:[main] from main: scope:[main] from
[0] phi() [0] phi()
[1] call plus [1] call plus
[2] plus::return#0 = plus::return#2
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
[2] *SCREEN = plus::return#1 [3] main::$0 = plus::return#0
[4] *SCREEN = main::$0
[5] call plus
[6] plus::return#1 = plus::return#2
to:main::@2
main::@2: scope:[main] from main::@1
[7] main::$1 = plus::return#1
[8] *(SCREEN+1) = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
[3] return [9] return
to:@return to:@return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
[4] phi() [10] plus::b#2 = phi( main/7, main::@1/6 )
[10] plus::a#2 = phi( main/'0', main::@1/'1' )
[11] plus::return#2 = plus::a#2 + plus::b#2
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus
[5] return [12] return
to:@return to:@return

View File

@ -7,27 +7,36 @@ main: scope:[main] from __start
plus::a#0 = '0' plus::a#0 = '0'
plus::b#0 = 7 plus::b#0 = 7
call plus call plus
plus::return#0 = plus::return#2 plus::return#0 = plus::return#3
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
plus::return#3 = phi( main/plus::return#0 ) plus::return#4 = phi( main/plus::return#0 )
main::$0 = plus::return#3 main::$0 = plus::return#4
SCREEN[0] = main::$0 SCREEN[0] = main::$0
plus::a#1 = '1'
plus::b#1 = 6
call plus
plus::return#1 = plus::return#3
to:main::@2
main::@2: scope:[main] from main::@1
plus::return#5 = phi( main::@1/plus::return#1 )
main::$1 = plus::return#5
SCREEN[1] = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
return return
to:@return to:@return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
plus::b#1 = phi( main/plus::b#0 ) plus::b#2 = phi( main/plus::b#0, main::@1/plus::b#1 )
plus::a#1 = phi( main/plus::a#0 ) plus::a#2 = phi( main/plus::a#0, main::@1/plus::a#1 )
plus::$0 = plus::a#1 + plus::b#1 plus::$0 = plus::a#2 + plus::b#2
plus::return#1 = plus::$0 plus::return#2 = plus::$0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus
plus::return#4 = phi( plus/plus::return#1 ) plus::return#6 = phi( plus/plus::return#2 )
plus::return#2 = plus::return#4 plus::return#3 = plus::return#6
return return
to:@return to:@return
@ -46,41 +55,53 @@ __constant char * const SCREEN = (char *)$400
void __start() void __start()
void main() void main()
char main::$0 char main::$0
char main::$1
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::$0 char plus::$0
char plus::a char plus::a
char plus::a#0 char plus::a#0
char plus::a#1 char plus::a#1
char plus::a#2
char plus::b char plus::b
char plus::b#0 char plus::b#0
char plus::b#1 char plus::b#1
char plus::b#2
char plus::return char plus::return
char plus::return#0 char plus::return#0
char plus::return#1 char plus::return#1
char plus::return#2 char plus::return#2
char plus::return#3 char plus::return#3
char plus::return#4 char plus::return#4
char plus::return#5
char plus::return#6
Adding number conversion cast (unumber) 7 in plus::b#0 = 7 Adding number conversion cast (unumber) 7 in plus::b#0 = 7
Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0 Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0
Adding number conversion cast (unumber) 6 in plus::b#1 = 6
Adding number conversion cast (unumber) 1 in SCREEN[1] = main::$1
Successful SSA optimization PassNAddNumberTypeConversions Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast plus::b#0 = (unumber)7 Inlining cast plus::b#0 = (unumber)7
Inlining cast plus::b#1 = (unumber)6
Successful SSA optimization Pass2InlineCast Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (char *) 1024 Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast 7 Simplifying constant integer cast 7
Simplifying constant integer cast 0 Simplifying constant integer cast 0
Simplifying constant integer cast 6
Simplifying constant integer cast 1
Successful SSA optimization PassNCastSimplification Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 7 Finalized unsigned number type (char) 7
Finalized unsigned number type (char) 0 Finalized unsigned number type (char) 0
Finalized unsigned number type (char) 6
Finalized unsigned number type (char) 1
Successful SSA optimization PassNFinalizeNumberTypeConversions Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias plus::return#0 = plus::return#3 Alias plus::return#0 = plus::return#4
Alias plus::return#1 = plus::$0 plus::return#4 plus::return#2 Alias plus::return#1 = plus::return#5
Alias plus::return#2 = plus::$0 plus::return#6 plus::return#3
Successful SSA optimization Pass2AliasElimination Successful SSA optimization Pass2AliasElimination
Identical Phi Values plus::a#1 plus::a#0
Identical Phi Values plus::b#1 plus::b#0
Successful SSA optimization Pass2IdenticalPhiElimination
Constant plus::a#0 = '0' Constant plus::a#0 = '0'
Constant plus::b#0 = 7 Constant plus::b#0 = 7
Constant plus::a#1 = '1'
Constant plus::b#1 = 6
Successful SSA optimization Pass2ConstantIdentification Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0 Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0
Successful SSA optimization PassNSimplifyExpressionWithZero Successful SSA optimization PassNSimplifyExpressionWithZero
@ -89,27 +110,24 @@ Removing unused procedure block __start
Removing unused procedure block __start::@1 Removing unused procedure block __start::@1
Removing unused procedure block __start::@return Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart Successful SSA optimization PassNEliminateEmptyStart
Constant right-side identified [5] plus::return#1 = plus::a#0 + plus::b#0 Inlining constant with var siblings plus::a#0
Successful SSA optimization Pass2ConstantRValueConsolidation Inlining constant with var siblings plus::b#0
Constant plus::return#1 = plus::a#0+plus::b#0 Inlining constant with var siblings plus::a#1
Successful SSA optimization Pass2ConstantIdentification Inlining constant with var siblings plus::b#1
Constant plus::return#0 = plus::return#1 Constant inlined plus::b#1 = 6
Successful SSA optimization Pass2ConstantIdentification Constant inlined plus::b#0 = 7
Constant main::$0 = plus::return#0 Constant inlined plus::a#1 = '1'
Successful SSA optimization Pass2ConstantIdentification Constant inlined plus::a#0 = '0'
Inlining constant with different constant siblings plus::return#0
Constant inlined plus::return#0 = plus::return#1
Constant inlined main::$0 = plus::return#1
Successful SSA optimization Pass2ConstantInlining Successful SSA optimization Pass2ConstantInlining
Consolidated array index constant in *(SCREEN+1)
Successful SSA optimization Pass2ConstantAdditionElimination
Adding NOP phi() at start of main Adding NOP phi() at start of main
Adding NOP phi() at start of plus
CALL GRAPH CALL GRAPH
Calls in [main] to plus:1 Calls in [main] to plus:1 plus:5
Created 0 initial phi equivalence classes Created 2 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes Coalesced down to 2 phi equivalence classes
Adding NOP phi() at start of main Adding NOP phi() at start of main
Adding NOP phi() at start of plus
FINAL CONTROL FLOW GRAPH FINAL CONTROL FLOW GRAPH
@ -117,44 +135,97 @@ void main()
main: scope:[main] from main: scope:[main] from
[0] phi() [0] phi()
[1] call plus [1] call plus
[2] plus::return#0 = plus::return#2
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
[2] *SCREEN = plus::return#1 [3] main::$0 = plus::return#0
[4] *SCREEN = main::$0
[5] call plus
[6] plus::return#1 = plus::return#2
to:main::@2
main::@2: scope:[main] from main::@1
[7] main::$1 = plus::return#1
[8] *(SCREEN+1) = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
[3] return [9] return
to:@return to:@return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
[4] phi() [10] plus::b#2 = phi( main/7, main::@1/6 )
[10] plus::a#2 = phi( main/'0', main::@1/'1' )
[11] plus::return#2 = plus::a#2 + plus::b#2
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus
[5] return [12] return
to:@return to:@return
VARIABLE REGISTER WEIGHTS VARIABLE REGISTER WEIGHTS
void main() void main()
char main::$0 // 4.0
char main::$1 // 4.0
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::a char plus::a
char plus::a#2 // 11.0
char plus::b char plus::b
char plus::b#2 // 11.0
char plus::return char plus::return
char plus::return#0 // 4.0
char plus::return#1 // 4.0
char plus::return#2 // 3.75
Initial phi equivalence classes Initial phi equivalence classes
[ plus::a#2 ]
[ plus::b#2 ]
Added variable plus::return#0 to live range equivalence class [ plus::return#0 ]
Added variable main::$0 to live range equivalence class [ main::$0 ]
Added variable plus::return#1 to live range equivalence class [ plus::return#1 ]
Added variable main::$1 to live range equivalence class [ main::$1 ]
Added variable plus::return#2 to live range equivalence class [ plus::return#2 ]
Complete equivalence classes Complete equivalence classes
[ plus::a#2 ]
[ plus::b#2 ]
[ plus::return#0 ]
[ main::$0 ]
[ plus::return#1 ]
[ main::$1 ]
[ plus::return#2 ]
Allocated zp[1]:2 [ plus::a#2 ]
Allocated zp[1]:3 [ plus::b#2 ]
Allocated zp[1]:4 [ plus::return#0 ]
Allocated zp[1]:5 [ main::$0 ]
Allocated zp[1]:6 [ plus::return#1 ]
Allocated zp[1]:7 [ main::$1 ]
Allocated zp[1]:8 [ plus::return#2 ]
REGISTER UPLIFT POTENTIAL REGISTERS REGISTER UPLIFT POTENTIAL REGISTERS
Statement [1] call plus [ ] ( [ ] { } ) always clobbers reg byte a Statement [1] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#0 = plus::return#2 } } ) always clobbers reg byte a
Statement [2] *SCREEN = plus::return#1 [ ] ( [ ] { } ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:8 [ plus::return#2 ]
Statement [5] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#1 = plus::return#2 } } ) always clobbers reg byte a
Statement [11] plus::return#2 = plus::a#2 + plus::b#2 [ plus::return#2 ] ( plus:1 [ plus::return#2 ] { { plus::return#0 = plus::return#2 } } plus:5 [ plus::return#2 ] { { plus::return#1 = plus::return#2 } } ) always clobbers reg byte a
Statement [1] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#0 = plus::return#2 } } ) always clobbers reg byte a
Statement [5] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#1 = plus::return#2 } } ) always clobbers reg byte a
Statement [11] plus::return#2 = plus::a#2 + plus::b#2 [ plus::return#2 ] ( plus:1 [ plus::return#2 ] { { plus::return#0 = plus::return#2 } } plus:5 [ plus::return#2 ] { { plus::return#1 = plus::return#2 } } ) always clobbers reg byte a
Potential registers zp[1]:2 [ plus::a#2 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:3 [ plus::b#2 ] : zp[1]:3 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:4 [ plus::return#0 ] : zp[1]:4 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:5 [ main::$0 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:6 [ plus::return#1 ] : zp[1]:6 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:7 [ main::$1 ] : zp[1]:7 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:8 [ plus::return#2 ] : zp[1]:8 , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES REGISTER UPLIFT SCOPES
Uplift Scope [main] Uplift Scope [plus] 11: zp[1]:2 [ plus::a#2 ] 11: zp[1]:3 [ plus::b#2 ] 4: zp[1]:4 [ plus::return#0 ] 4: zp[1]:6 [ plus::return#1 ] 3.75: zp[1]:8 [ plus::return#2 ]
Uplift Scope [plus] Uplift Scope [main] 4: zp[1]:5 [ main::$0 ] 4: zp[1]:7 [ main::$1 ]
Uplift Scope [] Uplift Scope []
Uplifting [main] best 78 combination Uplifting [plus] best 141 combination reg byte a [ plus::a#2 ] reg byte x [ plus::b#2 ] reg byte a [ plus::return#0 ] reg byte a [ plus::return#1 ] zp[1]:8 [ plus::return#2 ]
Uplifting [plus] best 78 combination Limited combination testing to 100 combinations of 768 possible.
Uplifting [] best 78 combination Uplifting [main] best 129 combination reg byte a [ main::$0 ] reg byte a [ main::$1 ]
Uplifting [] best 129 combination
Attempting to uplift remaining variables inzp[1]:8 [ plus::return#2 ]
Uplifting [plus] best 126 combination reg byte x [ plus::return#2 ]
ASSEMBLER BEFORE OPTIMIZATION ASSEMBLER BEFORE OPTIMIZATION
// File Comments // File Comments
@ -206,50 +277,92 @@ ASSEMBLER BEFORE OPTIMIZATION
// main // main
main: { main: {
// [1] call plus // [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_phi_close_cx16_ram // [10] phi from main to plus [phi:main->plus]
plus_from_main: plus_from_main:
// [10] phi plus::b#2 = 7 [phi:main->plus#0] -- vbuxx=vbuc1
ldx #7
// [10] phi plus::a#2 = '0' [phi:main->plus#1] -- call_phi_close_cx16_ram
lda #'0'
sta.z $ff
lda.z 0 lda.z 0
pha pha
lda #1 lda #1
sta.z 0 sta.z 0
lda.z $ff
jsr plus jsr plus
sta.z $ff
pla pla
sta.z 0 sta.z 0
lda.z $ff
// [2] plus::return#0 = plus::return#2 -- vbuaa=vbuxx
txa
jmp __b1 jmp __b1
// main::@1 // main::@1
__b1: __b1:
// [2] *SCREEN = plus::return#1 -- _deref_pbuc1=vbuc2 // [3] main::$0 = plus::return#0
lda #plus.return // [4] *SCREEN = main::$0 -- _deref_pbuc1=vbuaa
sta SCREEN sta SCREEN
// [5] call plus
// [10] phi from main::@1 to plus [phi:main::@1->plus]
plus_from___b1:
// [10] phi plus::b#2 = 6 [phi:main::@1->plus#0] -- vbuxx=vbuc1
ldx #6
// [10] phi plus::a#2 = '1' [phi:main::@1->plus#1] -- call_phi_close_cx16_ram
lda #'1'
sta.z $ff
lda.z 0
pha
lda #1
sta.z 0
lda.z $ff
jsr plus
sta.z $ff
pla
sta.z 0
lda.z $ff
// [6] plus::return#1 = plus::return#2 -- vbuaa=vbuxx
txa
jmp __b2
// main::@2
__b2:
// [7] main::$1 = plus::return#1
// [8] *(SCREEN+1) = main::$1 -- _deref_pbuc1=vbuaa
// close call
sta SCREEN+1
jmp __breturn jmp __breturn
// main::@return // main::@return
__breturn: __breturn:
// [3] return // [9] return
rts rts
} }
.segment RAM_Bank1 .segment RAM_Bank1
// plus // plus
// char plus(char a, char b) // __register(X) char plus(__register(A) char a, __register(X) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
plus: { plus: {
.const a = '0' // [11] plus::return#2 = plus::a#2 + plus::b#2 -- vbuxx=vbuaa_plus_vbuxx
.const b = 7 stx.z $ff
.label return = a+b clc
adc.z $ff
tax
jmp __breturn jmp __breturn
// plus::@return // plus::@return
__breturn: __breturn:
// [5] return // [12] return
rts rts
} }
// File Data // File Data
ASSEMBLER OPTIMIZATIONS ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1 Removing instruction jmp __b1
Removing instruction jmp __b2
Removing instruction jmp __breturn Removing instruction jmp __breturn
Removing instruction jmp __breturn Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination Succesful ASM optimization Pass5NextJumpElimination
Removing instruction plus_from_main: Removing instruction plus_from_main:
Removing instruction __b1: Removing instruction __b1:
Removing instruction plus_from___b1:
Removing instruction __b2:
Removing instruction __breturn: Removing instruction __breturn:
Removing instruction __breturn: Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination Succesful ASM optimization Pass5UnusedLabelElimination
@ -257,18 +370,29 @@ Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE FINAL SYMBOL TABLE
__constant char * const SCREEN = (char *) 1024 __constant char * const SCREEN = (char *) 1024
void main() void main()
char main::$0 // reg byte a 4.0
char main::$1 // reg byte a 4.0
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::a char plus::a
__constant char plus::a#0 = '0' // a char plus::a#2 // reg byte a 11.0
char plus::b char plus::b
__constant char plus::b#0 = 7 // b char plus::b#2 // reg byte x 11.0
char plus::return char plus::return
__constant char plus::return#1 = plus::a#0+plus::b#0 // return char plus::return#0 // reg byte a 4.0
char plus::return#1 // reg byte a 4.0
char plus::return#2 // reg byte x 3.75
reg byte a [ plus::a#2 ]
reg byte x [ plus::b#2 ]
reg byte a [ plus::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ plus::return#1 ]
reg byte a [ main::$1 ]
reg byte x [ plus::return#2 ]
FINAL ASSEMBLER FINAL ASSEMBLER
Score: 42 Score: 114
// File Comments // File Comments
/** /**
@ -320,34 +444,76 @@ Score: 42
main: { main: {
// plus('0', 7) // plus('0', 7)
// [1] call plus // [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_phi_close_cx16_ram // [10] phi from main to plus [phi:main->plus]
// [10] phi plus::b#2 = 7 [phi:main->plus#0] -- vbuxx=vbuc1
ldx #7
// [10] phi plus::a#2 = '0' [phi:main->plus#1] -- call_phi_close_cx16_ram
lda #'0'
sta.z $ff
lda.z 0 lda.z 0
pha pha
lda #1 lda #1
sta.z 0 sta.z 0
lda.z $ff
jsr plus jsr plus
sta.z $ff
pla pla
sta.z 0 sta.z 0
lda.z $ff
// plus('0', 7)
// [2] plus::return#0 = plus::return#2 -- vbuaa=vbuxx
txa
// main::@1 // main::@1
// [3] main::$0 = plus::return#0
// SCREEN[0] = plus('0', 7) // SCREEN[0] = plus('0', 7)
// [2] *SCREEN = plus::return#1 -- _deref_pbuc1=vbuc2 // [4] *SCREEN = main::$0 -- _deref_pbuc1=vbuaa
lda #plus.return
sta SCREEN sta SCREEN
// plus('1', 6)
// [5] call plus
// [10] phi from main::@1 to plus [phi:main::@1->plus]
// [10] phi plus::b#2 = 6 [phi:main::@1->plus#0] -- vbuxx=vbuc1
ldx #6
// [10] phi plus::a#2 = '1' [phi:main::@1->plus#1] -- call_phi_close_cx16_ram
lda #'1'
sta.z $ff
lda.z 0
pha
lda #1
sta.z 0
lda.z $ff
jsr plus
sta.z $ff
pla
sta.z 0
lda.z $ff
// plus('1', 6)
// [6] plus::return#1 = plus::return#2 -- vbuaa=vbuxx
txa
// main::@2
// [7] main::$1 = plus::return#1
// SCREEN[1] = plus('1', 6)
// [8] *(SCREEN+1) = main::$1 -- _deref_pbuc1=vbuaa
// close call
sta SCREEN+1
// main::@return // main::@return
// } // }
// [3] return // [9] return
rts rts
} }
.segment RAM_Bank1 .segment RAM_Bank1
// plus // plus
// char plus(char a, char b) // __register(X) char plus(__register(A) char a, __register(X) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
plus: { plus: {
.const a = '0' // a+b
.const b = 7 // [11] plus::return#2 = plus::a#2 + plus::b#2 -- vbuxx=vbuaa_plus_vbuxx
.label return = a+b stx.z $ff
clc
adc.z $ff
tax
// plus::@return // plus::@return
// [5] return // }
// [12] return
rts rts
} }
// File Data // File Data

View File

@ -1,10 +1,21 @@
__constant char * const SCREEN = (char *) 1024 __constant char * const SCREEN = (char *) 1024
void main() void main()
char main::$0 // reg byte a 4.0
char main::$1 // reg byte a 4.0
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::a char plus::a
__constant char plus::a#0 = '0' // a char plus::a#2 // reg byte a 11.0
char plus::b char plus::b
__constant char plus::b#0 = 7 // b char plus::b#2 // reg byte x 11.0
char plus::return char plus::return
__constant char plus::return#1 = plus::a#0+plus::b#0 // return char plus::return#0 // reg byte a 4.0
char plus::return#1 // reg byte a 4.0
char plus::return#2 // reg byte x 3.75
reg byte a [ plus::a#2 ]
reg byte x [ plus::b#2 ]
reg byte a [ plus::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ plus::return#1 ]
reg byte a [ main::$1 ]
reg byte x [ plus::return#2 ]

View File

@ -43,33 +43,64 @@
.segment Code .segment Code
main: { main: {
// plus('0', 7) // plus('0', 7)
ldx #7
lda #'0'
sta.z $ff
lda.z 0 lda.z 0
pha pha
lda #1 lda #1
sta.z 0 sta.z 0
lda.z $ff
jsr plus jsr plus
sta.z $ff
pla pla
sta.z 0 sta.z 0
lda.z $ff
// plus('0', 7)
txa
// SCREEN[0] = plus('0', 7) // SCREEN[0] = plus('0', 7)
lda #min.return
sta SCREEN sta SCREEN
// plus('1', 6)
ldx #6
lda #'1'
sta.z $ff
lda.z 0
pha
lda #1
sta.z 0
lda.z $ff
jsr plus
sta.z $ff
pla
sta.z 0
lda.z $ff
// plus('1', 6)
txa
// SCREEN[1] = plus('1', 6)
// close call
sta SCREEN+1
// } // }
rts rts
} }
.segment RAM_Bank1 .segment RAM_Bank1
// char plus(char a, char b) // __register(X) char plus(__register(A) char a, __register(X) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
plus: { plus: {
.label a = '0' // add(a, b)
.label b = 7 sta.z add.a
// min(a, b) txa
jsr min jsr add
tax
// } // }
rts rts
} }
.segment Code .segment Code
// char min(char a, char b) // __register(A) char add(__zp(2) char a, __register(A) char b)
min: { add: {
.label return = plus.a+plus.b .label a = 2
// a+b
clc
adc.z a
// }
rts rts
} }

View File

@ -3,27 +3,42 @@ void main()
main: scope:[main] from main: scope:[main] from
[0] phi() [0] phi()
[1] call plus [1] call plus
[2] plus::return#0 = plus::return#2
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
[2] *SCREEN = min::return#1 [3] main::$0 = plus::return#0
[4] *SCREEN = main::$0
[5] call plus
[6] plus::return#1 = plus::return#2
to:main::@2
main::@2: scope:[main] from main::@1
[7] main::$1 = plus::return#1
[8] *(SCREEN+1) = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
[3] return [9] return
to:@return to:@return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
[4] phi() [10] plus::b#2 = phi( main/7, main::@1/6 )
[5] call min [10] plus::a#2 = phi( main/'0', main::@1/'1' )
[11] add::a#0 = plus::a#2
[12] add::b#0 = plus::b#2
[13] call add
[14] add::return#0 = add::return#1
to:plus::@1
plus::@1: scope:[plus] from plus
[15] plus::return#2 = add::return#0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus::@1
[6] return [16] return
to:@return to:@return
char min(char a , char b) char add(char a , char b)
min: scope:[min] from plus add: scope:[add] from plus
[7] phi() [17] add::return#1 = add::a#0 + add::b#0
to:min::@return to:add::@return
min::@return: scope:[min] from min add::@return: scope:[add] from add
[8] return [18] return
to:@return to:@return

View File

@ -7,47 +7,56 @@ main: scope:[main] from __start
plus::a#0 = '0' plus::a#0 = '0'
plus::b#0 = 7 plus::b#0 = 7
call plus call plus
plus::return#0 = plus::return#2 plus::return#0 = plus::return#3
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
plus::return#3 = phi( main/plus::return#0 ) plus::return#4 = phi( main/plus::return#0 )
main::$0 = plus::return#3 main::$0 = plus::return#4
SCREEN[0] = main::$0 SCREEN[0] = main::$0
plus::a#1 = '1'
plus::b#1 = 6
call plus
plus::return#1 = plus::return#3
to:main::@2
main::@2: scope:[main] from main::@1
plus::return#5 = phi( main::@1/plus::return#1 )
main::$1 = plus::return#5
SCREEN[1] = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
return return
to:@return to:@return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
plus::b#1 = phi( main/plus::b#0 ) plus::b#2 = phi( main/plus::b#0, main::@1/plus::b#1 )
plus::a#1 = phi( main/plus::a#0 ) plus::a#2 = phi( main/plus::a#0, main::@1/plus::a#1 )
min::a#0 = plus::a#1 add::a#0 = plus::a#2
min::b#0 = plus::b#1 add::b#0 = plus::b#2
call min call add
min::return#0 = min::return#2 add::return#0 = add::return#2
to:plus::@1 to:plus::@1
plus::@1: scope:[plus] from plus plus::@1: scope:[plus] from plus
min::return#3 = phi( plus/min::return#0 ) add::return#3 = phi( plus/add::return#0 )
plus::$0 = min::return#3 plus::$0 = add::return#3
plus::return#1 = plus::$0 plus::return#2 = plus::$0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus::@1 plus::@return: scope:[plus] from plus::@1
plus::return#4 = phi( plus::@1/plus::return#1 ) plus::return#6 = phi( plus::@1/plus::return#2 )
plus::return#2 = plus::return#4 plus::return#3 = plus::return#6
return return
to:@return to:@return
char min(char a , char b) char add(char a , char b)
min: scope:[min] from plus add: scope:[add] from plus
min::b#1 = phi( plus/min::b#0 ) add::b#1 = phi( plus/add::b#0 )
min::a#1 = phi( plus/min::a#0 ) add::a#1 = phi( plus/add::a#0 )
min::$0 = min::a#1 + min::b#1 add::$0 = add::a#1 + add::b#1
min::return#1 = min::$0 add::return#1 = add::$0
to:min::@return to:add::@return
min::@return: scope:[min] from min add::@return: scope:[add] from add
min::return#4 = phi( min/min::return#1 ) add::return#4 = phi( add/add::return#1 )
min::return#2 = min::return#4 add::return#2 = add::return#4
return return
to:@return to:@return
@ -64,64 +73,74 @@ __start::@return: scope:[__start] from __start::@1
SYMBOL TABLE SSA SYMBOL TABLE SSA
__constant char * const SCREEN = (char *)$400 __constant char * const SCREEN = (char *)$400
void __start() void __start()
char add(char a , char b)
char add::$0
char add::a
char add::a#0
char add::a#1
char add::b
char add::b#0
char add::b#1
char add::return
char add::return#0
char add::return#1
char add::return#2
char add::return#3
char add::return#4
void main() void main()
char main::$0 char main::$0
char min(char a , char b) char main::$1
char min::$0
char min::a
char min::a#0
char min::a#1
char min::b
char min::b#0
char min::b#1
char min::return
char min::return#0
char min::return#1
char min::return#2
char min::return#3
char min::return#4
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::$0 char plus::$0
char plus::a char plus::a
char plus::a#0 char plus::a#0
char plus::a#1 char plus::a#1
char plus::a#2
char plus::b char plus::b
char plus::b#0 char plus::b#0
char plus::b#1 char plus::b#1
char plus::b#2
char plus::return char plus::return
char plus::return#0 char plus::return#0
char plus::return#1 char plus::return#1
char plus::return#2 char plus::return#2
char plus::return#3 char plus::return#3
char plus::return#4 char plus::return#4
char plus::return#5
char plus::return#6
Adding number conversion cast (unumber) 7 in plus::b#0 = 7 Adding number conversion cast (unumber) 7 in plus::b#0 = 7
Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0 Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0
Adding number conversion cast (unumber) 6 in plus::b#1 = 6
Adding number conversion cast (unumber) 1 in SCREEN[1] = main::$1
Successful SSA optimization PassNAddNumberTypeConversions Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast plus::b#0 = (unumber)7 Inlining cast plus::b#0 = (unumber)7
Inlining cast plus::b#1 = (unumber)6
Successful SSA optimization Pass2InlineCast Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (char *) 1024 Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast 7 Simplifying constant integer cast 7
Simplifying constant integer cast 0 Simplifying constant integer cast 0
Simplifying constant integer cast 6
Simplifying constant integer cast 1
Successful SSA optimization PassNCastSimplification Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 7 Finalized unsigned number type (char) 7
Finalized unsigned number type (char) 0 Finalized unsigned number type (char) 0
Finalized unsigned number type (char) 6
Finalized unsigned number type (char) 1
Successful SSA optimization PassNFinalizeNumberTypeConversions Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias plus::return#0 = plus::return#3 Alias plus::return#0 = plus::return#4
Alias min::return#0 = min::return#3 Alias plus::return#1 = plus::return#5
Alias plus::return#1 = plus::$0 plus::return#4 plus::return#2 Alias add::return#0 = add::return#3
Alias min::return#1 = min::$0 min::return#4 min::return#2 Alias plus::return#2 = plus::$0 plus::return#6 plus::return#3
Alias add::return#1 = add::$0 add::return#4 add::return#2
Successful SSA optimization Pass2AliasElimination Successful SSA optimization Pass2AliasElimination
Identical Phi Values plus::a#1 plus::a#0 Identical Phi Values add::a#1 add::a#0
Identical Phi Values plus::b#1 plus::b#0 Identical Phi Values add::b#1 add::b#0
Identical Phi Values min::a#1 min::a#0
Identical Phi Values min::b#1 min::b#0
Successful SSA optimization Pass2IdenticalPhiElimination Successful SSA optimization Pass2IdenticalPhiElimination
Constant plus::a#0 = '0' Constant plus::a#0 = '0'
Constant plus::b#0 = 7 Constant plus::b#0 = 7
Successful SSA optimization Pass2ConstantIdentification Constant plus::a#1 = '1'
Constant min::a#0 = plus::a#0 Constant plus::b#1 = 6
Constant min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantIdentification Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0 Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0
Successful SSA optimization PassNSimplifyExpressionWithZero Successful SSA optimization PassNSimplifyExpressionWithZero
@ -130,40 +149,25 @@ Removing unused procedure block __start
Removing unused procedure block __start::@1 Removing unused procedure block __start::@1
Removing unused procedure block __start::@return Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart Successful SSA optimization PassNEliminateEmptyStart
Constant right-side identified [9] min::return#1 = min::a#0 + min::b#0 Inlining constant with var siblings plus::a#0
Successful SSA optimization Pass2ConstantRValueConsolidation Inlining constant with var siblings plus::b#0
Constant min::return#1 = min::a#0+min::b#0 Inlining constant with var siblings plus::a#1
Successful SSA optimization Pass2ConstantIdentification Inlining constant with var siblings plus::b#1
Constant min::return#0 = min::return#1 Constant inlined plus::b#1 = 6
Successful SSA optimization Pass2ConstantIdentification Constant inlined plus::b#0 = 7
Constant plus::return#1 = min::return#0 Constant inlined plus::a#1 = '1'
Successful SSA optimization Pass2ConstantIdentification Constant inlined plus::a#0 = '0'
Constant plus::return#0 = plus::return#1
Successful SSA optimization Pass2ConstantIdentification
Constant main::$0 = plus::return#0
Successful SSA optimization Pass2ConstantIdentification
Inlining constant with different constant siblings min::return#0
Constant inlined plus::return#0 = min::return#1
Constant inlined main::$0 = min::return#1
Constant inlined plus::return#1 = min::return#1
Constant inlined min::a#0 = plus::a#0
Constant inlined min::return#0 = min::return#1
Constant inlined min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantInlining Successful SSA optimization Pass2ConstantInlining
Consolidated array index constant in *(SCREEN+1)
Successful SSA optimization Pass2ConstantAdditionElimination
Adding NOP phi() at start of main Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of plus::@1
Adding NOP phi() at start of min
CALL GRAPH CALL GRAPH
Calls in [main] to plus:1 Calls in [main] to plus:1 plus:5
Calls in [plus] to min:5 Calls in [plus] to add:13
Created 0 initial phi equivalence classes Created 2 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes Coalesced down to 2 phi equivalence classes
Culled Empty Block label plus::@1
Adding NOP phi() at start of main Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of min
FINAL CONTROL FLOW GRAPH FINAL CONTROL FLOW GRAPH
@ -171,59 +175,141 @@ void main()
main: scope:[main] from main: scope:[main] from
[0] phi() [0] phi()
[1] call plus [1] call plus
[2] plus::return#0 = plus::return#2
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
[2] *SCREEN = min::return#1 [3] main::$0 = plus::return#0
[4] *SCREEN = main::$0
[5] call plus
[6] plus::return#1 = plus::return#2
to:main::@2
main::@2: scope:[main] from main::@1
[7] main::$1 = plus::return#1
[8] *(SCREEN+1) = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
[3] return [9] return
to:@return to:@return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
[4] phi() [10] plus::b#2 = phi( main/7, main::@1/6 )
[5] call min [10] plus::a#2 = phi( main/'0', main::@1/'1' )
[11] add::a#0 = plus::a#2
[12] add::b#0 = plus::b#2
[13] call add
[14] add::return#0 = add::return#1
to:plus::@1
plus::@1: scope:[plus] from plus
[15] plus::return#2 = add::return#0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus::@1
[6] return [16] return
to:@return to:@return
char min(char a , char b) char add(char a , char b)
min: scope:[min] from plus add: scope:[add] from plus
[7] phi() [17] add::return#1 = add::a#0 + add::b#0
to:min::@return to:add::@return
min::@return: scope:[min] from min add::@return: scope:[add] from add
[8] return [18] return
to:@return to:@return
VARIABLE REGISTER WEIGHTS VARIABLE REGISTER WEIGHTS
char add(char a , char b)
char add::a
char add::a#0 // 56.0
char add::b
char add::b#0 // 112.0
char add::return
char add::return#0 // 22.0
char add::return#1 // 37.33333333333333
void main() void main()
char min(char a , char b) char main::$0 // 4.0
char min::a char main::$1 // 4.0
char min::b
char min::return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::a char plus::a
char plus::a#2 // 11.0
char plus::b char plus::b
char plus::b#2 // 5.5
char plus::return char plus::return
char plus::return#0 // 4.0
char plus::return#1 // 4.0
char plus::return#2 // 3.75
Initial phi equivalence classes Initial phi equivalence classes
[ plus::a#2 ]
[ plus::b#2 ]
Added variable plus::return#0 to live range equivalence class [ plus::return#0 ]
Added variable main::$0 to live range equivalence class [ main::$0 ]
Added variable plus::return#1 to live range equivalence class [ plus::return#1 ]
Added variable main::$1 to live range equivalence class [ main::$1 ]
Added variable add::a#0 to live range equivalence class [ add::a#0 ]
Added variable add::b#0 to live range equivalence class [ add::b#0 ]
Added variable add::return#0 to live range equivalence class [ add::return#0 ]
Added variable plus::return#2 to live range equivalence class [ plus::return#2 ]
Added variable add::return#1 to live range equivalence class [ add::return#1 ]
Complete equivalence classes Complete equivalence classes
[ plus::a#2 ]
[ plus::b#2 ]
[ plus::return#0 ]
[ main::$0 ]
[ plus::return#1 ]
[ main::$1 ]
[ add::a#0 ]
[ add::b#0 ]
[ add::return#0 ]
[ plus::return#2 ]
[ add::return#1 ]
Allocated zp[1]:2 [ add::b#0 ]
Allocated zp[1]:3 [ add::a#0 ]
Allocated zp[1]:4 [ add::return#1 ]
Allocated zp[1]:5 [ add::return#0 ]
Allocated zp[1]:6 [ plus::a#2 ]
Allocated zp[1]:7 [ plus::b#2 ]
Allocated zp[1]:8 [ plus::return#0 ]
Allocated zp[1]:9 [ main::$0 ]
Allocated zp[1]:10 [ plus::return#1 ]
Allocated zp[1]:11 [ main::$1 ]
Allocated zp[1]:12 [ plus::return#2 ]
REGISTER UPLIFT POTENTIAL REGISTERS REGISTER UPLIFT POTENTIAL REGISTERS
Statement [1] call plus [ ] ( [ ] { } ) always clobbers reg byte a Statement [1] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#0 = plus::return#2 } } ) always clobbers reg byte a
Statement [2] *SCREEN = min::return#1 [ ] ( [ ] { } ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:12 [ plus::return#2 ]
Statement [5] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#1 = plus::return#2 } } ) always clobbers reg byte a
Statement [17] add::return#1 = add::a#0 + add::b#0 [ add::return#1 ] ( plus:1::add:13 [ add::return#1 ] { { plus::return#0 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } plus:5::add:13 [ add::return#1 ] { { plus::return#1 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } ) always clobbers reg byte a
Statement [1] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#0 = plus::return#2 } } ) always clobbers reg byte a
Statement [5] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#1 = plus::return#2 } } ) always clobbers reg byte a
Statement [17] add::return#1 = add::a#0 + add::b#0 [ add::return#1 ] ( plus:1::add:13 [ add::return#1 ] { { plus::return#0 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } plus:5::add:13 [ add::return#1 ] { { plus::return#1 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } ) always clobbers reg byte a
Potential registers zp[1]:6 [ plus::a#2 ] : zp[1]:6 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:7 [ plus::b#2 ] : zp[1]:7 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:8 [ plus::return#0 ] : zp[1]:8 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:9 [ main::$0 ] : zp[1]:9 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:10 [ plus::return#1 ] : zp[1]:10 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:11 [ main::$1 ] : zp[1]:11 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:3 [ add::a#0 ] : zp[1]:3 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:2 [ add::b#0 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:5 [ add::return#0 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:12 [ plus::return#2 ] : zp[1]:12 , reg byte x , reg byte y ,
Potential registers zp[1]:4 [ add::return#1 ] : zp[1]:4 , reg byte a , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES REGISTER UPLIFT SCOPES
Uplift Scope [main] Uplift Scope [add] 112: zp[1]:2 [ add::b#0 ] 56: zp[1]:3 [ add::a#0 ] 37.33: zp[1]:4 [ add::return#1 ] 22: zp[1]:5 [ add::return#0 ]
Uplift Scope [plus] Uplift Scope [plus] 11: zp[1]:6 [ plus::a#2 ] 5.5: zp[1]:7 [ plus::b#2 ] 4: zp[1]:8 [ plus::return#0 ] 4: zp[1]:10 [ plus::return#1 ] 3.75: zp[1]:12 [ plus::return#2 ]
Uplift Scope [min] Uplift Scope [main] 4: zp[1]:9 [ main::$0 ] 4: zp[1]:11 [ main::$1 ]
Uplift Scope [] Uplift Scope []
Uplifting [main] best 93 combination Uplifting [add] best 189 combination reg byte a [ add::b#0 ] zp[1]:3 [ add::a#0 ] reg byte a [ add::return#1 ] reg byte a [ add::return#0 ]
Uplifting [plus] best 93 combination Limited combination testing to 100 combinations of 256 possible.
Uplifting [min] best 93 combination Uplifting [plus] best 161 combination reg byte a [ plus::a#2 ] reg byte x [ plus::b#2 ] reg byte a [ plus::return#0 ] reg byte a [ plus::return#1 ] zp[1]:12 [ plus::return#2 ]
Uplifting [] best 93 combination Limited combination testing to 100 combinations of 768 possible.
Uplifting [main] best 149 combination reg byte a [ main::$0 ] reg byte a [ main::$1 ]
Uplifting [] best 149 combination
Attempting to uplift remaining variables inzp[1]:3 [ add::a#0 ]
Uplifting [add] best 149 combination zp[1]:3 [ add::a#0 ]
Attempting to uplift remaining variables inzp[1]:12 [ plus::return#2 ]
Uplifting [plus] best 146 combination reg byte x [ plus::return#2 ]
Allocated (was zp[1]:3) zp[1]:2 [ add::a#0 ]
ASSEMBLER BEFORE OPTIMIZATION ASSEMBLER BEFORE OPTIMIZATION
// File Comments // File Comments
@ -275,90 +361,159 @@ ASSEMBLER BEFORE OPTIMIZATION
// main // main
main: { main: {
// [1] call plus // [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_phi_close_cx16_ram // [10] phi from main to plus [phi:main->plus]
plus_from_main: plus_from_main:
// [10] phi plus::b#2 = 7 [phi:main->plus#0] -- vbuxx=vbuc1
ldx #7
// [10] phi plus::a#2 = '0' [phi:main->plus#1] -- call_phi_close_cx16_ram
lda #'0'
sta.z $ff
lda.z 0 lda.z 0
pha pha
lda #1 lda #1
sta.z 0 sta.z 0
lda.z $ff
jsr plus jsr plus
sta.z $ff
pla pla
sta.z 0 sta.z 0
lda.z $ff
// [2] plus::return#0 = plus::return#2 -- vbuaa=vbuxx
txa
jmp __b1 jmp __b1
// main::@1 // main::@1
__b1: __b1:
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2 // [3] main::$0 = plus::return#0
lda #min.return // [4] *SCREEN = main::$0 -- _deref_pbuc1=vbuaa
sta SCREEN sta SCREEN
// [5] call plus
// [10] phi from main::@1 to plus [phi:main::@1->plus]
plus_from___b1:
// [10] phi plus::b#2 = 6 [phi:main::@1->plus#0] -- vbuxx=vbuc1
ldx #6
// [10] phi plus::a#2 = '1' [phi:main::@1->plus#1] -- call_phi_close_cx16_ram
lda #'1'
sta.z $ff
lda.z 0
pha
lda #1
sta.z 0
lda.z $ff
jsr plus
sta.z $ff
pla
sta.z 0
lda.z $ff
// [6] plus::return#1 = plus::return#2 -- vbuaa=vbuxx
txa
jmp __b2
// main::@2
__b2:
// [7] main::$1 = plus::return#1
// [8] *(SCREEN+1) = main::$1 -- _deref_pbuc1=vbuaa
// close call
sta SCREEN+1
jmp __breturn jmp __breturn
// main::@return // main::@return
__breturn: __breturn:
// [3] return // [9] return
rts rts
} }
.segment RAM_Bank1 .segment RAM_Bank1
// plus // plus
// char plus(char a, char b) // __register(X) char plus(__register(A) char a, __register(X) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
plus: { plus: {
.label a = '0' // [11] add::a#0 = plus::a#2 -- vbuz1=vbuaa
.label b = 7 sta.z add.a
// [5] call min // [12] add::b#0 = plus::b#2 -- vbuaa=vbuxx
// [7] phi from plus to min [phi:plus->min] txa
min_from_plus: // [13] call add
jsr min jsr add
// [14] add::return#0 = add::return#1
jmp __b1
// plus::@1
__b1:
// [15] plus::return#2 = add::return#0 -- vbuxx=vbuaa
tax
jmp __breturn jmp __breturn
// plus::@return // plus::@return
__breturn: __breturn:
// [6] return // [16] return
rts rts
} }
.segment Code .segment Code
// min // add
// char min(char a, char b) // __register(A) char add(__zp(2) char a, __register(A) char b)
min: { add: {
.label return = plus.a+plus.b .label a = 2
// [17] add::return#1 = add::a#0 + add::b#0 -- vbuaa=vbuz1_plus_vbuaa
clc
adc.z a
jmp __breturn jmp __breturn
// min::@return // add::@return
__breturn: __breturn:
// [8] return // [18] return
rts rts
} }
// File Data // File Data
ASSEMBLER OPTIMIZATIONS ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1 Removing instruction jmp __b1
Removing instruction jmp __b2
Removing instruction jmp __breturn Removing instruction jmp __breturn
Removing instruction jmp __b1
Removing instruction jmp __breturn Removing instruction jmp __breturn
Removing instruction jmp __breturn Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination Succesful ASM optimization Pass5NextJumpElimination
Removing instruction plus_from_main: Removing instruction plus_from_main:
Removing instruction __b1: Removing instruction __b1:
Removing instruction plus_from___b1:
Removing instruction __b2:
Removing instruction __breturn: Removing instruction __breturn:
Removing instruction min_from_plus: Removing instruction __b1:
Removing instruction __breturn: Removing instruction __breturn:
Removing instruction __breturn: Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE FINAL SYMBOL TABLE
__constant char * const SCREEN = (char *) 1024 __constant char * const SCREEN = (char *) 1024
char add(char a , char b)
char add::a
char add::a#0 // a zp[1]:2 56.0
char add::b
char add::b#0 // reg byte a 112.0
char add::return
char add::return#0 // reg byte a 22.0
char add::return#1 // reg byte a 37.33333333333333
void main() void main()
char min(char a , char b) char main::$0 // reg byte a 4.0
char min::a char main::$1 // reg byte a 4.0
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::a char plus::a
__constant char plus::a#0 = '0' // a char plus::a#2 // reg byte a 11.0
char plus::b char plus::b
__constant char plus::b#0 = 7 // b char plus::b#2 // reg byte x 5.5
char plus::return char plus::return
char plus::return#0 // reg byte a 4.0
char plus::return#1 // reg byte a 4.0
char plus::return#2 // reg byte x 3.75
reg byte a [ plus::a#2 ]
reg byte x [ plus::b#2 ]
reg byte a [ plus::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ plus::return#1 ]
reg byte a [ main::$1 ]
zp[1]:2 [ add::a#0 ]
reg byte a [ add::b#0 ]
reg byte a [ add::return#0 ]
reg byte x [ plus::return#2 ]
reg byte a [ add::return#1 ]
FINAL ASSEMBLER FINAL ASSEMBLER
Score: 54 Score: 128
// File Comments // File Comments
/** /**
@ -410,47 +565,95 @@ Score: 54
main: { main: {
// plus('0', 7) // plus('0', 7)
// [1] call plus // [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_phi_close_cx16_ram // [10] phi from main to plus [phi:main->plus]
// [10] phi plus::b#2 = 7 [phi:main->plus#0] -- vbuxx=vbuc1
ldx #7
// [10] phi plus::a#2 = '0' [phi:main->plus#1] -- call_phi_close_cx16_ram
lda #'0'
sta.z $ff
lda.z 0 lda.z 0
pha pha
lda #1 lda #1
sta.z 0 sta.z 0
lda.z $ff
jsr plus jsr plus
sta.z $ff
pla pla
sta.z 0 sta.z 0
lda.z $ff
// plus('0', 7)
// [2] plus::return#0 = plus::return#2 -- vbuaa=vbuxx
txa
// main::@1 // main::@1
// [3] main::$0 = plus::return#0
// SCREEN[0] = plus('0', 7) // SCREEN[0] = plus('0', 7)
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2 // [4] *SCREEN = main::$0 -- _deref_pbuc1=vbuaa
lda #min.return
sta SCREEN sta SCREEN
// plus('1', 6)
// [5] call plus
// [10] phi from main::@1 to plus [phi:main::@1->plus]
// [10] phi plus::b#2 = 6 [phi:main::@1->plus#0] -- vbuxx=vbuc1
ldx #6
// [10] phi plus::a#2 = '1' [phi:main::@1->plus#1] -- call_phi_close_cx16_ram
lda #'1'
sta.z $ff
lda.z 0
pha
lda #1
sta.z 0
lda.z $ff
jsr plus
sta.z $ff
pla
sta.z 0
lda.z $ff
// plus('1', 6)
// [6] plus::return#1 = plus::return#2 -- vbuaa=vbuxx
txa
// main::@2
// [7] main::$1 = plus::return#1
// SCREEN[1] = plus('1', 6)
// [8] *(SCREEN+1) = main::$1 -- _deref_pbuc1=vbuaa
// close call
sta SCREEN+1
// main::@return // main::@return
// } // }
// [3] return // [9] return
rts rts
} }
.segment RAM_Bank1 .segment RAM_Bank1
// plus // plus
// char plus(char a, char b) // __register(X) char plus(__register(A) char a, __register(X) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
plus: { plus: {
.label a = '0' // add(a, b)
.label b = 7 // [11] add::a#0 = plus::a#2 -- vbuz1=vbuaa
// min(a, b) sta.z add.a
// [5] call min // [12] add::b#0 = plus::b#2 -- vbuaa=vbuxx
// [7] phi from plus to min [phi:plus->min] txa
jsr min // [13] call add
jsr add
// [14] add::return#0 = add::return#1
// plus::@1
// [15] plus::return#2 = add::return#0 -- vbuxx=vbuaa
tax
// plus::@return // plus::@return
// } // }
// [6] return // [16] return
rts rts
} }
.segment Code .segment Code
// min // add
// char min(char a, char b) // __register(A) char add(__zp(2) char a, __register(A) char b)
min: { add: {
.label return = plus.a+plus.b .label a = 2
// min::@return // a+b
// [8] return // [17] add::return#1 = add::a#0 + add::b#0 -- vbuaa=vbuz1_plus_vbuaa
clc
adc.z a
// add::@return
// }
// [18] return
rts rts
} }
// File Data // File Data

View File

@ -1,14 +1,33 @@
__constant char * const SCREEN = (char *) 1024 __constant char * const SCREEN = (char *) 1024
char add(char a , char b)
char add::a
char add::a#0 // a zp[1]:2 56.0
char add::b
char add::b#0 // reg byte a 112.0
char add::return
char add::return#0 // reg byte a 22.0
char add::return#1 // reg byte a 37.33333333333333
void main() void main()
char min(char a , char b) char main::$0 // reg byte a 4.0
char min::a char main::$1 // reg byte a 4.0
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::a char plus::a
__constant char plus::a#0 = '0' // a char plus::a#2 // reg byte a 11.0
char plus::b char plus::b
__constant char plus::b#0 = 7 // b char plus::b#2 // reg byte x 5.5
char plus::return char plus::return
char plus::return#0 // reg byte a 4.0
char plus::return#1 // reg byte a 4.0
char plus::return#2 // reg byte x 3.75
reg byte a [ plus::a#2 ]
reg byte x [ plus::b#2 ]
reg byte a [ plus::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ plus::return#1 ]
reg byte a [ main::$1 ]
zp[1]:2 [ add::a#0 ]
reg byte a [ add::b#0 ]
reg byte a [ add::return#0 ]
reg byte x [ plus::return#2 ]
reg byte a [ add::return#1 ]

View File

@ -43,33 +43,64 @@
.segment Code .segment Code
main: { main: {
// plus('0', 7) // plus('0', 7)
ldx #7
lda #'0'
sta.z $ff
lda.z 0 lda.z 0
pha pha
lda #1 lda #1
sta.z 0 sta.z 0
lda.z $ff
jsr plus jsr plus
sta.z $ff
pla pla
sta.z 0 sta.z 0
lda.z $ff
// plus('0', 7)
txa
// SCREEN[0] = plus('0', 7) // SCREEN[0] = plus('0', 7)
lda #min.return
sta SCREEN sta SCREEN
// plus('1', 6)
ldx #6
lda #'1'
sta.z $ff
lda.z 0
pha
lda #1
sta.z 0
lda.z $ff
jsr plus
sta.z $ff
pla
sta.z 0
lda.z $ff
// plus('1', 6)
txa
// SCREEN[1] = plus('1', 6)
// close call
sta SCREEN+1
// } // }
rts rts
} }
.segment RAM_Bank1 .segment RAM_Bank1
// char plus(char a, char b) // __register(X) char plus(__register(A) char a, __register(X) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
plus: { plus: {
.label a = '0' // add(a, b)
.label b = 7 sta.z add.a
// min(a, b) txa
jsr min jsr add
tax
// } // }
rts rts
} }
.segment Code .segment Code
// char min(char a, char b) // __register(A) char add(__zp(2) char a, __register(A) char b)
min: { add: {
.label return = plus.a+plus.b .label a = 2
// a+b
clc
adc.z a
// }
rts rts
} }

View File

@ -3,27 +3,42 @@ void main()
main: scope:[main] from main: scope:[main] from
[0] phi() [0] phi()
[1] call plus [1] call plus
[2] plus::return#0 = plus::return#2
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
[2] *SCREEN = min::return#1 [3] main::$0 = plus::return#0
[4] *SCREEN = main::$0
[5] call plus
[6] plus::return#1 = plus::return#2
to:main::@2
main::@2: scope:[main] from main::@1
[7] main::$1 = plus::return#1
[8] *(SCREEN+1) = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
[3] return [9] return
to:@return to:@return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
[4] phi() [10] plus::b#2 = phi( main/7, main::@1/6 )
[5] call min [10] plus::a#2 = phi( main/'0', main::@1/'1' )
[11] add::a#0 = plus::a#2
[12] add::b#0 = plus::b#2
[13] call add
[14] add::return#0 = add::return#1
to:plus::@1
plus::@1: scope:[plus] from plus
[15] plus::return#2 = add::return#0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus::@1
[6] return [16] return
to:@return to:@return
char min(char a , char b) char add(char a , char b)
min: scope:[min] from plus add: scope:[add] from plus
[7] phi() [17] add::return#1 = add::a#0 + add::b#0
to:min::@return to:add::@return
min::@return: scope:[min] from min add::@return: scope:[add] from add
[8] return [18] return
to:@return to:@return

View File

@ -7,47 +7,56 @@ main: scope:[main] from __start
plus::a#0 = '0' plus::a#0 = '0'
plus::b#0 = 7 plus::b#0 = 7
call plus call plus
plus::return#0 = plus::return#2 plus::return#0 = plus::return#3
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
plus::return#3 = phi( main/plus::return#0 ) plus::return#4 = phi( main/plus::return#0 )
main::$0 = plus::return#3 main::$0 = plus::return#4
SCREEN[0] = main::$0 SCREEN[0] = main::$0
plus::a#1 = '1'
plus::b#1 = 6
call plus
plus::return#1 = plus::return#3
to:main::@2
main::@2: scope:[main] from main::@1
plus::return#5 = phi( main::@1/plus::return#1 )
main::$1 = plus::return#5
SCREEN[1] = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
return return
to:@return to:@return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
plus::b#1 = phi( main/plus::b#0 ) plus::b#2 = phi( main/plus::b#0, main::@1/plus::b#1 )
plus::a#1 = phi( main/plus::a#0 ) plus::a#2 = phi( main/plus::a#0, main::@1/plus::a#1 )
min::a#0 = plus::a#1 add::a#0 = plus::a#2
min::b#0 = plus::b#1 add::b#0 = plus::b#2
call min call add
min::return#0 = min::return#2 add::return#0 = add::return#2
to:plus::@1 to:plus::@1
plus::@1: scope:[plus] from plus plus::@1: scope:[plus] from plus
min::return#3 = phi( plus/min::return#0 ) add::return#3 = phi( plus/add::return#0 )
plus::$0 = min::return#3 plus::$0 = add::return#3
plus::return#1 = plus::$0 plus::return#2 = plus::$0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus::@1 plus::@return: scope:[plus] from plus::@1
plus::return#4 = phi( plus::@1/plus::return#1 ) plus::return#6 = phi( plus::@1/plus::return#2 )
plus::return#2 = plus::return#4 plus::return#3 = plus::return#6
return return
to:@return to:@return
char min(char a , char b) char add(char a , char b)
min: scope:[min] from plus add: scope:[add] from plus
min::b#1 = phi( plus/min::b#0 ) add::b#1 = phi( plus/add::b#0 )
min::a#1 = phi( plus/min::a#0 ) add::a#1 = phi( plus/add::a#0 )
min::$0 = min::a#1 + min::b#1 add::$0 = add::a#1 + add::b#1
min::return#1 = min::$0 add::return#1 = add::$0
to:min::@return to:add::@return
min::@return: scope:[min] from min add::@return: scope:[add] from add
min::return#4 = phi( min/min::return#1 ) add::return#4 = phi( add/add::return#1 )
min::return#2 = min::return#4 add::return#2 = add::return#4
return return
to:@return to:@return
@ -64,64 +73,74 @@ __start::@return: scope:[__start] from __start::@1
SYMBOL TABLE SSA SYMBOL TABLE SSA
__constant char * const SCREEN = (char *)$400 __constant char * const SCREEN = (char *)$400
void __start() void __start()
char add(char a , char b)
char add::$0
char add::a
char add::a#0
char add::a#1
char add::b
char add::b#0
char add::b#1
char add::return
char add::return#0
char add::return#1
char add::return#2
char add::return#3
char add::return#4
void main() void main()
char main::$0 char main::$0
char min(char a , char b) char main::$1
char min::$0
char min::a
char min::a#0
char min::a#1
char min::b
char min::b#0
char min::b#1
char min::return
char min::return#0
char min::return#1
char min::return#2
char min::return#3
char min::return#4
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::$0 char plus::$0
char plus::a char plus::a
char plus::a#0 char plus::a#0
char plus::a#1 char plus::a#1
char plus::a#2
char plus::b char plus::b
char plus::b#0 char plus::b#0
char plus::b#1 char plus::b#1
char plus::b#2
char plus::return char plus::return
char plus::return#0 char plus::return#0
char plus::return#1 char plus::return#1
char plus::return#2 char plus::return#2
char plus::return#3 char plus::return#3
char plus::return#4 char plus::return#4
char plus::return#5
char plus::return#6
Adding number conversion cast (unumber) 7 in plus::b#0 = 7 Adding number conversion cast (unumber) 7 in plus::b#0 = 7
Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0 Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0
Adding number conversion cast (unumber) 6 in plus::b#1 = 6
Adding number conversion cast (unumber) 1 in SCREEN[1] = main::$1
Successful SSA optimization PassNAddNumberTypeConversions Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast plus::b#0 = (unumber)7 Inlining cast plus::b#0 = (unumber)7
Inlining cast plus::b#1 = (unumber)6
Successful SSA optimization Pass2InlineCast Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (char *) 1024 Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast 7 Simplifying constant integer cast 7
Simplifying constant integer cast 0 Simplifying constant integer cast 0
Simplifying constant integer cast 6
Simplifying constant integer cast 1
Successful SSA optimization PassNCastSimplification Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 7 Finalized unsigned number type (char) 7
Finalized unsigned number type (char) 0 Finalized unsigned number type (char) 0
Finalized unsigned number type (char) 6
Finalized unsigned number type (char) 1
Successful SSA optimization PassNFinalizeNumberTypeConversions Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias plus::return#0 = plus::return#3 Alias plus::return#0 = plus::return#4
Alias min::return#0 = min::return#3 Alias plus::return#1 = plus::return#5
Alias plus::return#1 = plus::$0 plus::return#4 plus::return#2 Alias add::return#0 = add::return#3
Alias min::return#1 = min::$0 min::return#4 min::return#2 Alias plus::return#2 = plus::$0 plus::return#6 plus::return#3
Alias add::return#1 = add::$0 add::return#4 add::return#2
Successful SSA optimization Pass2AliasElimination Successful SSA optimization Pass2AliasElimination
Identical Phi Values plus::a#1 plus::a#0 Identical Phi Values add::a#1 add::a#0
Identical Phi Values plus::b#1 plus::b#0 Identical Phi Values add::b#1 add::b#0
Identical Phi Values min::a#1 min::a#0
Identical Phi Values min::b#1 min::b#0
Successful SSA optimization Pass2IdenticalPhiElimination Successful SSA optimization Pass2IdenticalPhiElimination
Constant plus::a#0 = '0' Constant plus::a#0 = '0'
Constant plus::b#0 = 7 Constant plus::b#0 = 7
Successful SSA optimization Pass2ConstantIdentification Constant plus::a#1 = '1'
Constant min::a#0 = plus::a#0 Constant plus::b#1 = 6
Constant min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantIdentification Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0 Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0
Successful SSA optimization PassNSimplifyExpressionWithZero Successful SSA optimization PassNSimplifyExpressionWithZero
@ -130,40 +149,25 @@ Removing unused procedure block __start
Removing unused procedure block __start::@1 Removing unused procedure block __start::@1
Removing unused procedure block __start::@return Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart Successful SSA optimization PassNEliminateEmptyStart
Constant right-side identified [9] min::return#1 = min::a#0 + min::b#0 Inlining constant with var siblings plus::a#0
Successful SSA optimization Pass2ConstantRValueConsolidation Inlining constant with var siblings plus::b#0
Constant min::return#1 = min::a#0+min::b#0 Inlining constant with var siblings plus::a#1
Successful SSA optimization Pass2ConstantIdentification Inlining constant with var siblings plus::b#1
Constant min::return#0 = min::return#1 Constant inlined plus::b#1 = 6
Successful SSA optimization Pass2ConstantIdentification Constant inlined plus::b#0 = 7
Constant plus::return#1 = min::return#0 Constant inlined plus::a#1 = '1'
Successful SSA optimization Pass2ConstantIdentification Constant inlined plus::a#0 = '0'
Constant plus::return#0 = plus::return#1
Successful SSA optimization Pass2ConstantIdentification
Constant main::$0 = plus::return#0
Successful SSA optimization Pass2ConstantIdentification
Inlining constant with different constant siblings min::return#0
Constant inlined plus::return#0 = min::return#1
Constant inlined main::$0 = min::return#1
Constant inlined plus::return#1 = min::return#1
Constant inlined min::a#0 = plus::a#0
Constant inlined min::return#0 = min::return#1
Constant inlined min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantInlining Successful SSA optimization Pass2ConstantInlining
Consolidated array index constant in *(SCREEN+1)
Successful SSA optimization Pass2ConstantAdditionElimination
Adding NOP phi() at start of main Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of plus::@1
Adding NOP phi() at start of min
CALL GRAPH CALL GRAPH
Calls in [main] to plus:1 Calls in [main] to plus:1 plus:5
Calls in [plus] to min:5 Calls in [plus] to add:13
Created 0 initial phi equivalence classes Created 2 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes Coalesced down to 2 phi equivalence classes
Culled Empty Block label plus::@1
Adding NOP phi() at start of main Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of min
FINAL CONTROL FLOW GRAPH FINAL CONTROL FLOW GRAPH
@ -171,59 +175,141 @@ void main()
main: scope:[main] from main: scope:[main] from
[0] phi() [0] phi()
[1] call plus [1] call plus
[2] plus::return#0 = plus::return#2
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
[2] *SCREEN = min::return#1 [3] main::$0 = plus::return#0
[4] *SCREEN = main::$0
[5] call plus
[6] plus::return#1 = plus::return#2
to:main::@2
main::@2: scope:[main] from main::@1
[7] main::$1 = plus::return#1
[8] *(SCREEN+1) = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
[3] return [9] return
to:@return to:@return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
[4] phi() [10] plus::b#2 = phi( main/7, main::@1/6 )
[5] call min [10] plus::a#2 = phi( main/'0', main::@1/'1' )
[11] add::a#0 = plus::a#2
[12] add::b#0 = plus::b#2
[13] call add
[14] add::return#0 = add::return#1
to:plus::@1
plus::@1: scope:[plus] from plus
[15] plus::return#2 = add::return#0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus::@1
[6] return [16] return
to:@return to:@return
char min(char a , char b) char add(char a , char b)
min: scope:[min] from plus add: scope:[add] from plus
[7] phi() [17] add::return#1 = add::a#0 + add::b#0
to:min::@return to:add::@return
min::@return: scope:[min] from min add::@return: scope:[add] from add
[8] return [18] return
to:@return to:@return
VARIABLE REGISTER WEIGHTS VARIABLE REGISTER WEIGHTS
char add(char a , char b)
char add::a
char add::a#0 // 56.0
char add::b
char add::b#0 // 112.0
char add::return
char add::return#0 // 22.0
char add::return#1 // 37.33333333333333
void main() void main()
char min(char a , char b) char main::$0 // 4.0
char min::a char main::$1 // 4.0
char min::b
char min::return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::a char plus::a
char plus::a#2 // 11.0
char plus::b char plus::b
char plus::b#2 // 5.5
char plus::return char plus::return
char plus::return#0 // 4.0
char plus::return#1 // 4.0
char plus::return#2 // 3.75
Initial phi equivalence classes Initial phi equivalence classes
[ plus::a#2 ]
[ plus::b#2 ]
Added variable plus::return#0 to live range equivalence class [ plus::return#0 ]
Added variable main::$0 to live range equivalence class [ main::$0 ]
Added variable plus::return#1 to live range equivalence class [ plus::return#1 ]
Added variable main::$1 to live range equivalence class [ main::$1 ]
Added variable add::a#0 to live range equivalence class [ add::a#0 ]
Added variable add::b#0 to live range equivalence class [ add::b#0 ]
Added variable add::return#0 to live range equivalence class [ add::return#0 ]
Added variable plus::return#2 to live range equivalence class [ plus::return#2 ]
Added variable add::return#1 to live range equivalence class [ add::return#1 ]
Complete equivalence classes Complete equivalence classes
[ plus::a#2 ]
[ plus::b#2 ]
[ plus::return#0 ]
[ main::$0 ]
[ plus::return#1 ]
[ main::$1 ]
[ add::a#0 ]
[ add::b#0 ]
[ add::return#0 ]
[ plus::return#2 ]
[ add::return#1 ]
Allocated zp[1]:2 [ add::b#0 ]
Allocated zp[1]:3 [ add::a#0 ]
Allocated zp[1]:4 [ add::return#1 ]
Allocated zp[1]:5 [ add::return#0 ]
Allocated zp[1]:6 [ plus::a#2 ]
Allocated zp[1]:7 [ plus::b#2 ]
Allocated zp[1]:8 [ plus::return#0 ]
Allocated zp[1]:9 [ main::$0 ]
Allocated zp[1]:10 [ plus::return#1 ]
Allocated zp[1]:11 [ main::$1 ]
Allocated zp[1]:12 [ plus::return#2 ]
REGISTER UPLIFT POTENTIAL REGISTERS REGISTER UPLIFT POTENTIAL REGISTERS
Statement [1] call plus [ ] ( [ ] { } ) always clobbers reg byte a Statement [1] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#0 = plus::return#2 } } ) always clobbers reg byte a
Statement [2] *SCREEN = min::return#1 [ ] ( [ ] { } ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:12 [ plus::return#2 ]
Statement [5] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#1 = plus::return#2 } } ) always clobbers reg byte a
Statement [17] add::return#1 = add::a#0 + add::b#0 [ add::return#1 ] ( plus:1::add:13 [ add::return#1 ] { { plus::return#0 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } plus:5::add:13 [ add::return#1 ] { { plus::return#1 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } ) always clobbers reg byte a
Statement [1] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#0 = plus::return#2 } } ) always clobbers reg byte a
Statement [5] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#1 = plus::return#2 } } ) always clobbers reg byte a
Statement [17] add::return#1 = add::a#0 + add::b#0 [ add::return#1 ] ( plus:1::add:13 [ add::return#1 ] { { plus::return#0 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } plus:5::add:13 [ add::return#1 ] { { plus::return#1 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } ) always clobbers reg byte a
Potential registers zp[1]:6 [ plus::a#2 ] : zp[1]:6 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:7 [ plus::b#2 ] : zp[1]:7 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:8 [ plus::return#0 ] : zp[1]:8 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:9 [ main::$0 ] : zp[1]:9 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:10 [ plus::return#1 ] : zp[1]:10 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:11 [ main::$1 ] : zp[1]:11 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:3 [ add::a#0 ] : zp[1]:3 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:2 [ add::b#0 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:5 [ add::return#0 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:12 [ plus::return#2 ] : zp[1]:12 , reg byte x , reg byte y ,
Potential registers zp[1]:4 [ add::return#1 ] : zp[1]:4 , reg byte a , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES REGISTER UPLIFT SCOPES
Uplift Scope [main] Uplift Scope [add] 112: zp[1]:2 [ add::b#0 ] 56: zp[1]:3 [ add::a#0 ] 37.33: zp[1]:4 [ add::return#1 ] 22: zp[1]:5 [ add::return#0 ]
Uplift Scope [plus] Uplift Scope [plus] 11: zp[1]:6 [ plus::a#2 ] 5.5: zp[1]:7 [ plus::b#2 ] 4: zp[1]:8 [ plus::return#0 ] 4: zp[1]:10 [ plus::return#1 ] 3.75: zp[1]:12 [ plus::return#2 ]
Uplift Scope [min] Uplift Scope [main] 4: zp[1]:9 [ main::$0 ] 4: zp[1]:11 [ main::$1 ]
Uplift Scope [] Uplift Scope []
Uplifting [main] best 93 combination Uplifting [add] best 189 combination reg byte a [ add::b#0 ] zp[1]:3 [ add::a#0 ] reg byte a [ add::return#1 ] reg byte a [ add::return#0 ]
Uplifting [plus] best 93 combination Limited combination testing to 100 combinations of 256 possible.
Uplifting [min] best 93 combination Uplifting [plus] best 161 combination reg byte a [ plus::a#2 ] reg byte x [ plus::b#2 ] reg byte a [ plus::return#0 ] reg byte a [ plus::return#1 ] zp[1]:12 [ plus::return#2 ]
Uplifting [] best 93 combination Limited combination testing to 100 combinations of 768 possible.
Uplifting [main] best 149 combination reg byte a [ main::$0 ] reg byte a [ main::$1 ]
Uplifting [] best 149 combination
Attempting to uplift remaining variables inzp[1]:3 [ add::a#0 ]
Uplifting [add] best 149 combination zp[1]:3 [ add::a#0 ]
Attempting to uplift remaining variables inzp[1]:12 [ plus::return#2 ]
Uplifting [plus] best 146 combination reg byte x [ plus::return#2 ]
Allocated (was zp[1]:3) zp[1]:2 [ add::a#0 ]
ASSEMBLER BEFORE OPTIMIZATION ASSEMBLER BEFORE OPTIMIZATION
// File Comments // File Comments
@ -275,90 +361,159 @@ ASSEMBLER BEFORE OPTIMIZATION
// main // main
main: { main: {
// [1] call plus // [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_phi_close_cx16_ram // [10] phi from main to plus [phi:main->plus]
plus_from_main: plus_from_main:
// [10] phi plus::b#2 = 7 [phi:main->plus#0] -- vbuxx=vbuc1
ldx #7
// [10] phi plus::a#2 = '0' [phi:main->plus#1] -- call_phi_close_cx16_ram
lda #'0'
sta.z $ff
lda.z 0 lda.z 0
pha pha
lda #1 lda #1
sta.z 0 sta.z 0
lda.z $ff
jsr plus jsr plus
sta.z $ff
pla pla
sta.z 0 sta.z 0
lda.z $ff
// [2] plus::return#0 = plus::return#2 -- vbuaa=vbuxx
txa
jmp __b1 jmp __b1
// main::@1 // main::@1
__b1: __b1:
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2 // [3] main::$0 = plus::return#0
lda #min.return // [4] *SCREEN = main::$0 -- _deref_pbuc1=vbuaa
sta SCREEN sta SCREEN
// [5] call plus
// [10] phi from main::@1 to plus [phi:main::@1->plus]
plus_from___b1:
// [10] phi plus::b#2 = 6 [phi:main::@1->plus#0] -- vbuxx=vbuc1
ldx #6
// [10] phi plus::a#2 = '1' [phi:main::@1->plus#1] -- call_phi_close_cx16_ram
lda #'1'
sta.z $ff
lda.z 0
pha
lda #1
sta.z 0
lda.z $ff
jsr plus
sta.z $ff
pla
sta.z 0
lda.z $ff
// [6] plus::return#1 = plus::return#2 -- vbuaa=vbuxx
txa
jmp __b2
// main::@2
__b2:
// [7] main::$1 = plus::return#1
// [8] *(SCREEN+1) = main::$1 -- _deref_pbuc1=vbuaa
// close call
sta SCREEN+1
jmp __breturn jmp __breturn
// main::@return // main::@return
__breturn: __breturn:
// [3] return // [9] return
rts rts
} }
.segment RAM_Bank1 .segment RAM_Bank1
// plus // plus
// char plus(char a, char b) // __register(X) char plus(__register(A) char a, __register(X) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
plus: { plus: {
.label a = '0' // [11] add::a#0 = plus::a#2 -- vbuz1=vbuaa
.label b = 7 sta.z add.a
// [5] call min // [12] add::b#0 = plus::b#2 -- vbuaa=vbuxx
// [7] phi from plus to min [phi:plus->min] txa
min_from_plus: // [13] call add
jsr min jsr add
// [14] add::return#0 = add::return#1
jmp __b1
// plus::@1
__b1:
// [15] plus::return#2 = add::return#0 -- vbuxx=vbuaa
tax
jmp __breturn jmp __breturn
// plus::@return // plus::@return
__breturn: __breturn:
// [6] return // [16] return
rts rts
} }
.segment Code .segment Code
// min // add
// char min(char a, char b) // __register(A) char add(__zp(2) char a, __register(A) char b)
min: { add: {
.label return = plus.a+plus.b .label a = 2
// [17] add::return#1 = add::a#0 + add::b#0 -- vbuaa=vbuz1_plus_vbuaa
clc
adc.z a
jmp __breturn jmp __breturn
// min::@return // add::@return
__breturn: __breturn:
// [8] return // [18] return
rts rts
} }
// File Data // File Data
ASSEMBLER OPTIMIZATIONS ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1 Removing instruction jmp __b1
Removing instruction jmp __b2
Removing instruction jmp __breturn Removing instruction jmp __breturn
Removing instruction jmp __b1
Removing instruction jmp __breturn Removing instruction jmp __breturn
Removing instruction jmp __breturn Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination Succesful ASM optimization Pass5NextJumpElimination
Removing instruction plus_from_main: Removing instruction plus_from_main:
Removing instruction __b1: Removing instruction __b1:
Removing instruction plus_from___b1:
Removing instruction __b2:
Removing instruction __breturn: Removing instruction __breturn:
Removing instruction min_from_plus: Removing instruction __b1:
Removing instruction __breturn: Removing instruction __breturn:
Removing instruction __breturn: Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE FINAL SYMBOL TABLE
__constant char * const SCREEN = (char *) 1024 __constant char * const SCREEN = (char *) 1024
char add(char a , char b)
char add::a
char add::a#0 // a zp[1]:2 56.0
char add::b
char add::b#0 // reg byte a 112.0
char add::return
char add::return#0 // reg byte a 22.0
char add::return#1 // reg byte a 37.33333333333333
void main() void main()
char min(char a , char b) char main::$0 // reg byte a 4.0
char min::a char main::$1 // reg byte a 4.0
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::a char plus::a
__constant char plus::a#0 = '0' // a char plus::a#2 // reg byte a 11.0
char plus::b char plus::b
__constant char plus::b#0 = 7 // b char plus::b#2 // reg byte x 5.5
char plus::return char plus::return
char plus::return#0 // reg byte a 4.0
char plus::return#1 // reg byte a 4.0
char plus::return#2 // reg byte x 3.75
reg byte a [ plus::a#2 ]
reg byte x [ plus::b#2 ]
reg byte a [ plus::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ plus::return#1 ]
reg byte a [ main::$1 ]
zp[1]:2 [ add::a#0 ]
reg byte a [ add::b#0 ]
reg byte a [ add::return#0 ]
reg byte x [ plus::return#2 ]
reg byte a [ add::return#1 ]
FINAL ASSEMBLER FINAL ASSEMBLER
Score: 54 Score: 128
// File Comments // File Comments
/** /**
@ -410,47 +565,95 @@ Score: 54
main: { main: {
// plus('0', 7) // plus('0', 7)
// [1] call plus // [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_phi_close_cx16_ram // [10] phi from main to plus [phi:main->plus]
// [10] phi plus::b#2 = 7 [phi:main->plus#0] -- vbuxx=vbuc1
ldx #7
// [10] phi plus::a#2 = '0' [phi:main->plus#1] -- call_phi_close_cx16_ram
lda #'0'
sta.z $ff
lda.z 0 lda.z 0
pha pha
lda #1 lda #1
sta.z 0 sta.z 0
lda.z $ff
jsr plus jsr plus
sta.z $ff
pla pla
sta.z 0 sta.z 0
lda.z $ff
// plus('0', 7)
// [2] plus::return#0 = plus::return#2 -- vbuaa=vbuxx
txa
// main::@1 // main::@1
// [3] main::$0 = plus::return#0
// SCREEN[0] = plus('0', 7) // SCREEN[0] = plus('0', 7)
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2 // [4] *SCREEN = main::$0 -- _deref_pbuc1=vbuaa
lda #min.return
sta SCREEN sta SCREEN
// plus('1', 6)
// [5] call plus
// [10] phi from main::@1 to plus [phi:main::@1->plus]
// [10] phi plus::b#2 = 6 [phi:main::@1->plus#0] -- vbuxx=vbuc1
ldx #6
// [10] phi plus::a#2 = '1' [phi:main::@1->plus#1] -- call_phi_close_cx16_ram
lda #'1'
sta.z $ff
lda.z 0
pha
lda #1
sta.z 0
lda.z $ff
jsr plus
sta.z $ff
pla
sta.z 0
lda.z $ff
// plus('1', 6)
// [6] plus::return#1 = plus::return#2 -- vbuaa=vbuxx
txa
// main::@2
// [7] main::$1 = plus::return#1
// SCREEN[1] = plus('1', 6)
// [8] *(SCREEN+1) = main::$1 -- _deref_pbuc1=vbuaa
// close call
sta SCREEN+1
// main::@return // main::@return
// } // }
// [3] return // [9] return
rts rts
} }
.segment RAM_Bank1 .segment RAM_Bank1
// plus // plus
// char plus(char a, char b) // __register(X) char plus(__register(A) char a, __register(X) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
plus: { plus: {
.label a = '0' // add(a, b)
.label b = 7 // [11] add::a#0 = plus::a#2 -- vbuz1=vbuaa
// min(a, b) sta.z add.a
// [5] call min // [12] add::b#0 = plus::b#2 -- vbuaa=vbuxx
// [7] phi from plus to min [phi:plus->min] txa
jsr min // [13] call add
jsr add
// [14] add::return#0 = add::return#1
// plus::@1
// [15] plus::return#2 = add::return#0 -- vbuxx=vbuaa
tax
// plus::@return // plus::@return
// } // }
// [6] return // [16] return
rts rts
} }
.segment Code .segment Code
// min // add
// char min(char a, char b) // __register(A) char add(__zp(2) char a, __register(A) char b)
min: { add: {
.label return = plus.a+plus.b .label a = 2
// min::@return // a+b
// [8] return // [17] add::return#1 = add::a#0 + add::b#0 -- vbuaa=vbuz1_plus_vbuaa
clc
adc.z a
// add::@return
// }
// [18] return
rts rts
} }
// File Data // File Data

View File

@ -1,14 +1,33 @@
__constant char * const SCREEN = (char *) 1024 __constant char * const SCREEN = (char *) 1024
char add(char a , char b)
char add::a
char add::a#0 // a zp[1]:2 56.0
char add::b
char add::b#0 // reg byte a 112.0
char add::return
char add::return#0 // reg byte a 22.0
char add::return#1 // reg byte a 37.33333333333333
void main() void main()
char min(char a , char b) char main::$0 // reg byte a 4.0
char min::a char main::$1 // reg byte a 4.0
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::a char plus::a
__constant char plus::a#0 = '0' // a char plus::a#2 // reg byte a 11.0
char plus::b char plus::b
__constant char plus::b#0 = 7 // b char plus::b#2 // reg byte x 5.5
char plus::return char plus::return
char plus::return#0 // reg byte a 4.0
char plus::return#1 // reg byte a 4.0
char plus::return#2 // reg byte x 3.75
reg byte a [ plus::a#2 ]
reg byte x [ plus::b#2 ]
reg byte a [ plus::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ plus::return#1 ]
reg byte a [ main::$1 ]
zp[1]:2 [ add::a#0 ]
reg byte a [ add::b#0 ]
reg byte a [ add::return#0 ]
reg byte x [ plus::return#2 ]
reg byte a [ add::return#1 ]

View File

@ -43,33 +43,64 @@
.segment Code .segment Code
main: { main: {
// plus('0', 7) // plus('0', 7)
ldx #7
lda #'0'
sta.z $ff
lda.z 0 lda.z 0
pha pha
lda #1 lda #1
sta.z 0 sta.z 0
lda.z $ff
jsr plus jsr plus
sta.z $ff
pla pla
sta.z 0 sta.z 0
lda.z $ff
// plus('0', 7)
txa
// SCREEN[0] = plus('0', 7) // SCREEN[0] = plus('0', 7)
lda #min.return
sta SCREEN sta SCREEN
// plus('1', 6)
ldx #6
lda #'1'
sta.z $ff
lda.z 0
pha
lda #1
sta.z 0
lda.z $ff
jsr plus
sta.z $ff
pla
sta.z 0
lda.z $ff
// plus('1', 6)
txa
// SCREEN[1] = plus('1', 6)
// close call
sta SCREEN+1
// } // }
rts rts
} }
.segment RAM_Bank1 .segment RAM_Bank1
// char plus(char a, char b) // __register(X) char plus(__register(A) char a, __register(X) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
plus: { plus: {
.label a = '0' // add(a, b)
.label b = 7 sta.z add.a
// min(a, b) txa
jsr min jsr add
tax
// } // }
rts rts
} }
// char min(char a, char b) // __register(A) char add(__zp(2) char a, __register(A) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
min: { add: {
.label return = plus.a+plus.b .label a = 2
// a+b
clc
adc.z a
// }
rts rts
} }

View File

@ -3,27 +3,42 @@ void main()
main: scope:[main] from main: scope:[main] from
[0] phi() [0] phi()
[1] call plus [1] call plus
[2] plus::return#0 = plus::return#2
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
[2] *SCREEN = min::return#1 [3] main::$0 = plus::return#0
[4] *SCREEN = main::$0
[5] call plus
[6] plus::return#1 = plus::return#2
to:main::@2
main::@2: scope:[main] from main::@1
[7] main::$1 = plus::return#1
[8] *(SCREEN+1) = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
[3] return [9] return
to:@return to:@return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
[4] phi() [10] plus::b#2 = phi( main/7, main::@1/6 )
[5] call min [10] plus::a#2 = phi( main/'0', main::@1/'1' )
[11] add::a#0 = plus::a#2
[12] add::b#0 = plus::b#2
[13] call add
[14] add::return#0 = add::return#1
to:plus::@1
plus::@1: scope:[plus] from plus
[15] plus::return#2 = add::return#0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus::@1
[6] return [16] return
to:@return to:@return
__bank(cx16_ram, 1) char min(char a , char b) __bank(cx16_ram, 1) char add(char a , char b)
min: scope:[min] from plus add: scope:[add] from plus
[7] phi() [17] add::return#1 = add::a#0 + add::b#0
to:min::@return to:add::@return
min::@return: scope:[min] from min add::@return: scope:[add] from add
[8] return [18] return
to:@return to:@return

View File

@ -7,47 +7,56 @@ main: scope:[main] from __start
plus::a#0 = '0' plus::a#0 = '0'
plus::b#0 = 7 plus::b#0 = 7
call plus call plus
plus::return#0 = plus::return#2 plus::return#0 = plus::return#3
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
plus::return#3 = phi( main/plus::return#0 ) plus::return#4 = phi( main/plus::return#0 )
main::$0 = plus::return#3 main::$0 = plus::return#4
SCREEN[0] = main::$0 SCREEN[0] = main::$0
plus::a#1 = '1'
plus::b#1 = 6
call plus
plus::return#1 = plus::return#3
to:main::@2
main::@2: scope:[main] from main::@1
plus::return#5 = phi( main::@1/plus::return#1 )
main::$1 = plus::return#5
SCREEN[1] = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
return return
to:@return to:@return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
plus::b#1 = phi( main/plus::b#0 ) plus::b#2 = phi( main/plus::b#0, main::@1/plus::b#1 )
plus::a#1 = phi( main/plus::a#0 ) plus::a#2 = phi( main/plus::a#0, main::@1/plus::a#1 )
min::a#0 = plus::a#1 add::a#0 = plus::a#2
min::b#0 = plus::b#1 add::b#0 = plus::b#2
call min call add
min::return#0 = min::return#2 add::return#0 = add::return#2
to:plus::@1 to:plus::@1
plus::@1: scope:[plus] from plus plus::@1: scope:[plus] from plus
min::return#3 = phi( plus/min::return#0 ) add::return#3 = phi( plus/add::return#0 )
plus::$0 = min::return#3 plus::$0 = add::return#3
plus::return#1 = plus::$0 plus::return#2 = plus::$0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus::@1 plus::@return: scope:[plus] from plus::@1
plus::return#4 = phi( plus::@1/plus::return#1 ) plus::return#6 = phi( plus::@1/plus::return#2 )
plus::return#2 = plus::return#4 plus::return#3 = plus::return#6
return return
to:@return to:@return
__bank(cx16_ram, 1) char min(char a , char b) __bank(cx16_ram, 1) char add(char a , char b)
min: scope:[min] from plus add: scope:[add] from plus
min::b#1 = phi( plus/min::b#0 ) add::b#1 = phi( plus/add::b#0 )
min::a#1 = phi( plus/min::a#0 ) add::a#1 = phi( plus/add::a#0 )
min::$0 = min::a#1 + min::b#1 add::$0 = add::a#1 + add::b#1
min::return#1 = min::$0 add::return#1 = add::$0
to:min::@return to:add::@return
min::@return: scope:[min] from min add::@return: scope:[add] from add
min::return#4 = phi( min/min::return#1 ) add::return#4 = phi( add/add::return#1 )
min::return#2 = min::return#4 add::return#2 = add::return#4
return return
to:@return to:@return
@ -64,64 +73,74 @@ __start::@return: scope:[__start] from __start::@1
SYMBOL TABLE SSA SYMBOL TABLE SSA
__constant char * const SCREEN = (char *)$400 __constant char * const SCREEN = (char *)$400
void __start() void __start()
__bank(cx16_ram, 1) char add(char a , char b)
char add::$0
char add::a
char add::a#0
char add::a#1
char add::b
char add::b#0
char add::b#1
char add::return
char add::return#0
char add::return#1
char add::return#2
char add::return#3
char add::return#4
void main() void main()
char main::$0 char main::$0
__bank(cx16_ram, 1) char min(char a , char b) char main::$1
char min::$0
char min::a
char min::a#0
char min::a#1
char min::b
char min::b#0
char min::b#1
char min::return
char min::return#0
char min::return#1
char min::return#2
char min::return#3
char min::return#4
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::$0 char plus::$0
char plus::a char plus::a
char plus::a#0 char plus::a#0
char plus::a#1 char plus::a#1
char plus::a#2
char plus::b char plus::b
char plus::b#0 char plus::b#0
char plus::b#1 char plus::b#1
char plus::b#2
char plus::return char plus::return
char plus::return#0 char plus::return#0
char plus::return#1 char plus::return#1
char plus::return#2 char plus::return#2
char plus::return#3 char plus::return#3
char plus::return#4 char plus::return#4
char plus::return#5
char plus::return#6
Adding number conversion cast (unumber) 7 in plus::b#0 = 7 Adding number conversion cast (unumber) 7 in plus::b#0 = 7
Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0 Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0
Adding number conversion cast (unumber) 6 in plus::b#1 = 6
Adding number conversion cast (unumber) 1 in SCREEN[1] = main::$1
Successful SSA optimization PassNAddNumberTypeConversions Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast plus::b#0 = (unumber)7 Inlining cast plus::b#0 = (unumber)7
Inlining cast plus::b#1 = (unumber)6
Successful SSA optimization Pass2InlineCast Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (char *) 1024 Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast 7 Simplifying constant integer cast 7
Simplifying constant integer cast 0 Simplifying constant integer cast 0
Simplifying constant integer cast 6
Simplifying constant integer cast 1
Successful SSA optimization PassNCastSimplification Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 7 Finalized unsigned number type (char) 7
Finalized unsigned number type (char) 0 Finalized unsigned number type (char) 0
Finalized unsigned number type (char) 6
Finalized unsigned number type (char) 1
Successful SSA optimization PassNFinalizeNumberTypeConversions Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias plus::return#0 = plus::return#3 Alias plus::return#0 = plus::return#4
Alias min::return#0 = min::return#3 Alias plus::return#1 = plus::return#5
Alias plus::return#1 = plus::$0 plus::return#4 plus::return#2 Alias add::return#0 = add::return#3
Alias min::return#1 = min::$0 min::return#4 min::return#2 Alias plus::return#2 = plus::$0 plus::return#6 plus::return#3
Alias add::return#1 = add::$0 add::return#4 add::return#2
Successful SSA optimization Pass2AliasElimination Successful SSA optimization Pass2AliasElimination
Identical Phi Values plus::a#1 plus::a#0 Identical Phi Values add::a#1 add::a#0
Identical Phi Values plus::b#1 plus::b#0 Identical Phi Values add::b#1 add::b#0
Identical Phi Values min::a#1 min::a#0
Identical Phi Values min::b#1 min::b#0
Successful SSA optimization Pass2IdenticalPhiElimination Successful SSA optimization Pass2IdenticalPhiElimination
Constant plus::a#0 = '0' Constant plus::a#0 = '0'
Constant plus::b#0 = 7 Constant plus::b#0 = 7
Successful SSA optimization Pass2ConstantIdentification Constant plus::a#1 = '1'
Constant min::a#0 = plus::a#0 Constant plus::b#1 = 6
Constant min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantIdentification Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0 Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0
Successful SSA optimization PassNSimplifyExpressionWithZero Successful SSA optimization PassNSimplifyExpressionWithZero
@ -130,40 +149,25 @@ Removing unused procedure block __start
Removing unused procedure block __start::@1 Removing unused procedure block __start::@1
Removing unused procedure block __start::@return Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart Successful SSA optimization PassNEliminateEmptyStart
Constant right-side identified [9] min::return#1 = min::a#0 + min::b#0 Inlining constant with var siblings plus::a#0
Successful SSA optimization Pass2ConstantRValueConsolidation Inlining constant with var siblings plus::b#0
Constant min::return#1 = min::a#0+min::b#0 Inlining constant with var siblings plus::a#1
Successful SSA optimization Pass2ConstantIdentification Inlining constant with var siblings plus::b#1
Constant min::return#0 = min::return#1 Constant inlined plus::b#1 = 6
Successful SSA optimization Pass2ConstantIdentification Constant inlined plus::b#0 = 7
Constant plus::return#1 = min::return#0 Constant inlined plus::a#1 = '1'
Successful SSA optimization Pass2ConstantIdentification Constant inlined plus::a#0 = '0'
Constant plus::return#0 = plus::return#1
Successful SSA optimization Pass2ConstantIdentification
Constant main::$0 = plus::return#0
Successful SSA optimization Pass2ConstantIdentification
Inlining constant with different constant siblings min::return#0
Constant inlined plus::return#0 = min::return#1
Constant inlined main::$0 = min::return#1
Constant inlined plus::return#1 = min::return#1
Constant inlined min::a#0 = plus::a#0
Constant inlined min::return#0 = min::return#1
Constant inlined min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantInlining Successful SSA optimization Pass2ConstantInlining
Consolidated array index constant in *(SCREEN+1)
Successful SSA optimization Pass2ConstantAdditionElimination
Adding NOP phi() at start of main Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of plus::@1
Adding NOP phi() at start of min
CALL GRAPH CALL GRAPH
Calls in [main] to plus:1 Calls in [main] to plus:1 plus:5
Calls in [plus] to min:5 Calls in [plus] to add:13
Created 0 initial phi equivalence classes Created 2 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes Coalesced down to 2 phi equivalence classes
Culled Empty Block label plus::@1
Adding NOP phi() at start of main Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of min
FINAL CONTROL FLOW GRAPH FINAL CONTROL FLOW GRAPH
@ -171,59 +175,141 @@ void main()
main: scope:[main] from main: scope:[main] from
[0] phi() [0] phi()
[1] call plus [1] call plus
[2] plus::return#0 = plus::return#2
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
[2] *SCREEN = min::return#1 [3] main::$0 = plus::return#0
[4] *SCREEN = main::$0
[5] call plus
[6] plus::return#1 = plus::return#2
to:main::@2
main::@2: scope:[main] from main::@1
[7] main::$1 = plus::return#1
[8] *(SCREEN+1) = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
[3] return [9] return
to:@return to:@return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
[4] phi() [10] plus::b#2 = phi( main/7, main::@1/6 )
[5] call min [10] plus::a#2 = phi( main/'0', main::@1/'1' )
[11] add::a#0 = plus::a#2
[12] add::b#0 = plus::b#2
[13] call add
[14] add::return#0 = add::return#1
to:plus::@1
plus::@1: scope:[plus] from plus
[15] plus::return#2 = add::return#0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus::@1
[6] return [16] return
to:@return to:@return
__bank(cx16_ram, 1) char min(char a , char b) __bank(cx16_ram, 1) char add(char a , char b)
min: scope:[min] from plus add: scope:[add] from plus
[7] phi() [17] add::return#1 = add::a#0 + add::b#0
to:min::@return to:add::@return
min::@return: scope:[min] from min add::@return: scope:[add] from add
[8] return [18] return
to:@return to:@return
VARIABLE REGISTER WEIGHTS VARIABLE REGISTER WEIGHTS
__bank(cx16_ram, 1) char add(char a , char b)
char add::a
char add::a#0 // 56.0
char add::b
char add::b#0 // 112.0
char add::return
char add::return#0 // 22.0
char add::return#1 // 37.33333333333333
void main() void main()
__bank(cx16_ram, 1) char min(char a , char b) char main::$0 // 4.0
char min::a char main::$1 // 4.0
char min::b
char min::return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::a char plus::a
char plus::a#2 // 11.0
char plus::b char plus::b
char plus::b#2 // 5.5
char plus::return char plus::return
char plus::return#0 // 4.0
char plus::return#1 // 4.0
char plus::return#2 // 3.75
Initial phi equivalence classes Initial phi equivalence classes
[ plus::a#2 ]
[ plus::b#2 ]
Added variable plus::return#0 to live range equivalence class [ plus::return#0 ]
Added variable main::$0 to live range equivalence class [ main::$0 ]
Added variable plus::return#1 to live range equivalence class [ plus::return#1 ]
Added variable main::$1 to live range equivalence class [ main::$1 ]
Added variable add::a#0 to live range equivalence class [ add::a#0 ]
Added variable add::b#0 to live range equivalence class [ add::b#0 ]
Added variable add::return#0 to live range equivalence class [ add::return#0 ]
Added variable plus::return#2 to live range equivalence class [ plus::return#2 ]
Added variable add::return#1 to live range equivalence class [ add::return#1 ]
Complete equivalence classes Complete equivalence classes
[ plus::a#2 ]
[ plus::b#2 ]
[ plus::return#0 ]
[ main::$0 ]
[ plus::return#1 ]
[ main::$1 ]
[ add::a#0 ]
[ add::b#0 ]
[ add::return#0 ]
[ plus::return#2 ]
[ add::return#1 ]
Allocated zp[1]:2 [ add::b#0 ]
Allocated zp[1]:3 [ add::a#0 ]
Allocated zp[1]:4 [ add::return#1 ]
Allocated zp[1]:5 [ add::return#0 ]
Allocated zp[1]:6 [ plus::a#2 ]
Allocated zp[1]:7 [ plus::b#2 ]
Allocated zp[1]:8 [ plus::return#0 ]
Allocated zp[1]:9 [ main::$0 ]
Allocated zp[1]:10 [ plus::return#1 ]
Allocated zp[1]:11 [ main::$1 ]
Allocated zp[1]:12 [ plus::return#2 ]
REGISTER UPLIFT POTENTIAL REGISTERS REGISTER UPLIFT POTENTIAL REGISTERS
Statement [1] call plus [ ] ( [ ] { } ) always clobbers reg byte a Statement [1] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#0 = plus::return#2 } } ) always clobbers reg byte a
Statement [2] *SCREEN = min::return#1 [ ] ( [ ] { } ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:12 [ plus::return#2 ]
Statement [5] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#1 = plus::return#2 } } ) always clobbers reg byte a
Statement [17] add::return#1 = add::a#0 + add::b#0 [ add::return#1 ] ( plus:1::add:13 [ add::return#1 ] { { plus::return#0 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } plus:5::add:13 [ add::return#1 ] { { plus::return#1 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } ) always clobbers reg byte a
Statement [1] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#0 = plus::return#2 } } ) always clobbers reg byte a
Statement [5] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#1 = plus::return#2 } } ) always clobbers reg byte a
Statement [17] add::return#1 = add::a#0 + add::b#0 [ add::return#1 ] ( plus:1::add:13 [ add::return#1 ] { { plus::return#0 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } plus:5::add:13 [ add::return#1 ] { { plus::return#1 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } ) always clobbers reg byte a
Potential registers zp[1]:6 [ plus::a#2 ] : zp[1]:6 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:7 [ plus::b#2 ] : zp[1]:7 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:8 [ plus::return#0 ] : zp[1]:8 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:9 [ main::$0 ] : zp[1]:9 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:10 [ plus::return#1 ] : zp[1]:10 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:11 [ main::$1 ] : zp[1]:11 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:3 [ add::a#0 ] : zp[1]:3 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:2 [ add::b#0 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:5 [ add::return#0 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:12 [ plus::return#2 ] : zp[1]:12 , reg byte x , reg byte y ,
Potential registers zp[1]:4 [ add::return#1 ] : zp[1]:4 , reg byte a , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES REGISTER UPLIFT SCOPES
Uplift Scope [main] Uplift Scope [add] 112: zp[1]:2 [ add::b#0 ] 56: zp[1]:3 [ add::a#0 ] 37.33: zp[1]:4 [ add::return#1 ] 22: zp[1]:5 [ add::return#0 ]
Uplift Scope [plus] Uplift Scope [plus] 11: zp[1]:6 [ plus::a#2 ] 5.5: zp[1]:7 [ plus::b#2 ] 4: zp[1]:8 [ plus::return#0 ] 4: zp[1]:10 [ plus::return#1 ] 3.75: zp[1]:12 [ plus::return#2 ]
Uplift Scope [min] Uplift Scope [main] 4: zp[1]:9 [ main::$0 ] 4: zp[1]:11 [ main::$1 ]
Uplift Scope [] Uplift Scope []
Uplifting [main] best 93 combination Uplifting [add] best 189 combination reg byte a [ add::b#0 ] zp[1]:3 [ add::a#0 ] reg byte a [ add::return#1 ] reg byte a [ add::return#0 ]
Uplifting [plus] best 93 combination Limited combination testing to 100 combinations of 256 possible.
Uplifting [min] best 93 combination Uplifting [plus] best 161 combination reg byte a [ plus::a#2 ] reg byte x [ plus::b#2 ] reg byte a [ plus::return#0 ] reg byte a [ plus::return#1 ] zp[1]:12 [ plus::return#2 ]
Uplifting [] best 93 combination Limited combination testing to 100 combinations of 768 possible.
Uplifting [main] best 149 combination reg byte a [ main::$0 ] reg byte a [ main::$1 ]
Uplifting [] best 149 combination
Attempting to uplift remaining variables inzp[1]:3 [ add::a#0 ]
Uplifting [add] best 149 combination zp[1]:3 [ add::a#0 ]
Attempting to uplift remaining variables inzp[1]:12 [ plus::return#2 ]
Uplifting [plus] best 146 combination reg byte x [ plus::return#2 ]
Allocated (was zp[1]:3) zp[1]:2 [ add::a#0 ]
ASSEMBLER BEFORE OPTIMIZATION ASSEMBLER BEFORE OPTIMIZATION
// File Comments // File Comments
@ -275,90 +361,159 @@ ASSEMBLER BEFORE OPTIMIZATION
// main // main
main: { main: {
// [1] call plus // [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_phi_close_cx16_ram // [10] phi from main to plus [phi:main->plus]
plus_from_main: plus_from_main:
// [10] phi plus::b#2 = 7 [phi:main->plus#0] -- vbuxx=vbuc1
ldx #7
// [10] phi plus::a#2 = '0' [phi:main->plus#1] -- call_phi_close_cx16_ram
lda #'0'
sta.z $ff
lda.z 0 lda.z 0
pha pha
lda #1 lda #1
sta.z 0 sta.z 0
lda.z $ff
jsr plus jsr plus
sta.z $ff
pla pla
sta.z 0 sta.z 0
lda.z $ff
// [2] plus::return#0 = plus::return#2 -- vbuaa=vbuxx
txa
jmp __b1 jmp __b1
// main::@1 // main::@1
__b1: __b1:
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2 // [3] main::$0 = plus::return#0
lda #min.return // [4] *SCREEN = main::$0 -- _deref_pbuc1=vbuaa
sta SCREEN sta SCREEN
// [5] call plus
// [10] phi from main::@1 to plus [phi:main::@1->plus]
plus_from___b1:
// [10] phi plus::b#2 = 6 [phi:main::@1->plus#0] -- vbuxx=vbuc1
ldx #6
// [10] phi plus::a#2 = '1' [phi:main::@1->plus#1] -- call_phi_close_cx16_ram
lda #'1'
sta.z $ff
lda.z 0
pha
lda #1
sta.z 0
lda.z $ff
jsr plus
sta.z $ff
pla
sta.z 0
lda.z $ff
// [6] plus::return#1 = plus::return#2 -- vbuaa=vbuxx
txa
jmp __b2
// main::@2
__b2:
// [7] main::$1 = plus::return#1
// [8] *(SCREEN+1) = main::$1 -- _deref_pbuc1=vbuaa
// close call
sta SCREEN+1
jmp __breturn jmp __breturn
// main::@return // main::@return
__breturn: __breturn:
// [3] return // [9] return
rts rts
} }
.segment RAM_Bank1 .segment RAM_Bank1
// plus // plus
// char plus(char a, char b) // __register(X) char plus(__register(A) char a, __register(X) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
plus: { plus: {
.label a = '0' // [11] add::a#0 = plus::a#2 -- vbuz1=vbuaa
.label b = 7 sta.z add.a
// [5] call min // [12] add::b#0 = plus::b#2 -- vbuaa=vbuxx
// [7] phi from plus to min [phi:plus->min] txa
min_from_plus: // [13] call add
jsr min jsr add
// [14] add::return#0 = add::return#1
jmp __b1
// plus::@1
__b1:
// [15] plus::return#2 = add::return#0 -- vbuxx=vbuaa
tax
jmp __breturn jmp __breturn
// plus::@return // plus::@return
__breturn: __breturn:
// [6] return // [16] return
rts rts
} }
// min // add
// char min(char a, char b) // __register(A) char add(__zp(2) char a, __register(A) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
min: { add: {
.label return = plus.a+plus.b .label a = 2
// [17] add::return#1 = add::a#0 + add::b#0 -- vbuaa=vbuz1_plus_vbuaa
clc
adc.z a
jmp __breturn jmp __breturn
// min::@return // add::@return
__breturn: __breturn:
// [8] return // [18] return
rts rts
} }
// File Data // File Data
ASSEMBLER OPTIMIZATIONS ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1 Removing instruction jmp __b1
Removing instruction jmp __b2
Removing instruction jmp __breturn Removing instruction jmp __breturn
Removing instruction jmp __b1
Removing instruction jmp __breturn Removing instruction jmp __breturn
Removing instruction jmp __breturn Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination Succesful ASM optimization Pass5NextJumpElimination
Removing instruction plus_from_main: Removing instruction plus_from_main:
Removing instruction __b1: Removing instruction __b1:
Removing instruction plus_from___b1:
Removing instruction __b2:
Removing instruction __breturn: Removing instruction __breturn:
Removing instruction min_from_plus: Removing instruction __b1:
Removing instruction __breturn: Removing instruction __breturn:
Removing instruction __breturn: Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE FINAL SYMBOL TABLE
__constant char * const SCREEN = (char *) 1024 __constant char * const SCREEN = (char *) 1024
__bank(cx16_ram, 1) char add(char a , char b)
char add::a
char add::a#0 // a zp[1]:2 56.0
char add::b
char add::b#0 // reg byte a 112.0
char add::return
char add::return#0 // reg byte a 22.0
char add::return#1 // reg byte a 37.33333333333333
void main() void main()
__bank(cx16_ram, 1) char min(char a , char b) char main::$0 // reg byte a 4.0
char min::a char main::$1 // reg byte a 4.0
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::a char plus::a
__constant char plus::a#0 = '0' // a char plus::a#2 // reg byte a 11.0
char plus::b char plus::b
__constant char plus::b#0 = 7 // b char plus::b#2 // reg byte x 5.5
char plus::return char plus::return
char plus::return#0 // reg byte a 4.0
char plus::return#1 // reg byte a 4.0
char plus::return#2 // reg byte x 3.75
reg byte a [ plus::a#2 ]
reg byte x [ plus::b#2 ]
reg byte a [ plus::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ plus::return#1 ]
reg byte a [ main::$1 ]
zp[1]:2 [ add::a#0 ]
reg byte a [ add::b#0 ]
reg byte a [ add::return#0 ]
reg byte x [ plus::return#2 ]
reg byte a [ add::return#1 ]
FINAL ASSEMBLER FINAL ASSEMBLER
Score: 54 Score: 128
// File Comments // File Comments
/** /**
@ -410,47 +565,95 @@ Score: 54
main: { main: {
// plus('0', 7) // plus('0', 7)
// [1] call plus // [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_phi_close_cx16_ram // [10] phi from main to plus [phi:main->plus]
// [10] phi plus::b#2 = 7 [phi:main->plus#0] -- vbuxx=vbuc1
ldx #7
// [10] phi plus::a#2 = '0' [phi:main->plus#1] -- call_phi_close_cx16_ram
lda #'0'
sta.z $ff
lda.z 0 lda.z 0
pha pha
lda #1 lda #1
sta.z 0 sta.z 0
lda.z $ff
jsr plus jsr plus
sta.z $ff
pla pla
sta.z 0 sta.z 0
lda.z $ff
// plus('0', 7)
// [2] plus::return#0 = plus::return#2 -- vbuaa=vbuxx
txa
// main::@1 // main::@1
// [3] main::$0 = plus::return#0
// SCREEN[0] = plus('0', 7) // SCREEN[0] = plus('0', 7)
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2 // [4] *SCREEN = main::$0 -- _deref_pbuc1=vbuaa
lda #min.return
sta SCREEN sta SCREEN
// plus('1', 6)
// [5] call plus
// [10] phi from main::@1 to plus [phi:main::@1->plus]
// [10] phi plus::b#2 = 6 [phi:main::@1->plus#0] -- vbuxx=vbuc1
ldx #6
// [10] phi plus::a#2 = '1' [phi:main::@1->plus#1] -- call_phi_close_cx16_ram
lda #'1'
sta.z $ff
lda.z 0
pha
lda #1
sta.z 0
lda.z $ff
jsr plus
sta.z $ff
pla
sta.z 0
lda.z $ff
// plus('1', 6)
// [6] plus::return#1 = plus::return#2 -- vbuaa=vbuxx
txa
// main::@2
// [7] main::$1 = plus::return#1
// SCREEN[1] = plus('1', 6)
// [8] *(SCREEN+1) = main::$1 -- _deref_pbuc1=vbuaa
// close call
sta SCREEN+1
// main::@return // main::@return
// } // }
// [3] return // [9] return
rts rts
} }
.segment RAM_Bank1 .segment RAM_Bank1
// plus // plus
// char plus(char a, char b) // __register(X) char plus(__register(A) char a, __register(X) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
plus: { plus: {
.label a = '0' // add(a, b)
.label b = 7 // [11] add::a#0 = plus::a#2 -- vbuz1=vbuaa
// min(a, b) sta.z add.a
// [5] call min // [12] add::b#0 = plus::b#2 -- vbuaa=vbuxx
// [7] phi from plus to min [phi:plus->min] txa
jsr min // [13] call add
jsr add
// [14] add::return#0 = add::return#1
// plus::@1
// [15] plus::return#2 = add::return#0 -- vbuxx=vbuaa
tax
// plus::@return // plus::@return
// } // }
// [6] return // [16] return
rts rts
} }
// min // add
// char min(char a, char b) // __register(A) char add(__zp(2) char a, __register(A) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
min: { add: {
.label return = plus.a+plus.b .label a = 2
// min::@return // a+b
// [8] return // [17] add::return#1 = add::a#0 + add::b#0 -- vbuaa=vbuz1_plus_vbuaa
clc
adc.z a
// add::@return
// }
// [18] return
rts rts
} }
// File Data // File Data

View File

@ -1,14 +1,33 @@
__constant char * const SCREEN = (char *) 1024 __constant char * const SCREEN = (char *) 1024
__bank(cx16_ram, 1) char add(char a , char b)
char add::a
char add::a#0 // a zp[1]:2 56.0
char add::b
char add::b#0 // reg byte a 112.0
char add::return
char add::return#0 // reg byte a 22.0
char add::return#1 // reg byte a 37.33333333333333
void main() void main()
__bank(cx16_ram, 1) char min(char a , char b) char main::$0 // reg byte a 4.0
char min::a char main::$1 // reg byte a 4.0
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::a char plus::a
__constant char plus::a#0 = '0' // a char plus::a#2 // reg byte a 11.0
char plus::b char plus::b
__constant char plus::b#0 = 7 // b char plus::b#2 // reg byte x 5.5
char plus::return char plus::return
char plus::return#0 // reg byte a 4.0
char plus::return#1 // reg byte a 4.0
char plus::return#2 // reg byte x 3.75
reg byte a [ plus::a#2 ]
reg byte x [ plus::b#2 ]
reg byte a [ plus::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ plus::return#1 ]
reg byte a [ main::$1 ]
zp[1]:2 [ add::a#0 ]
reg byte a [ add::b#0 ]
reg byte a [ add::return#0 ]
reg byte x [ plus::return#2 ]
reg byte a [ add::return#1 ]

View File

@ -43,33 +43,64 @@
.segment Code .segment Code
main: { main: {
// plus('0', 7) // plus('0', 7)
ldx #7
lda #'0'
sta.z $ff
lda.z 0 lda.z 0
pha pha
lda #1 lda #1
sta.z 0 sta.z 0
lda.z $ff
jsr plus jsr plus
sta.z $ff
pla pla
sta.z 0 sta.z 0
lda.z $ff
// plus('0', 7)
txa
// SCREEN[0] = plus('0', 7) // SCREEN[0] = plus('0', 7)
lda #min.return
sta SCREEN sta SCREEN
// plus('1', 6)
ldx #6
lda #'1'
sta.z $ff
lda.z 0
pha
lda #1
sta.z 0
lda.z $ff
jsr plus
sta.z $ff
pla
sta.z 0
lda.z $ff
// plus('1', 6)
txa
// SCREEN[1] = plus('1', 6)
// close call
sta SCREEN+1
// } // }
rts rts
} }
.segment RAM_Bank1 .segment RAM_Bank1
// char plus(char a, char b) // __register(X) char plus(__register(A) char a, __register(X) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
plus: { plus: {
.label a = '0' // add(a, b)
.label b = 7 sta.z add.a
// min(a, b) txa
jsr min jsr add
tax
// } // }
rts rts
} }
// char min(char a, char b) // __register(A) char add(__zp(2) char a, __register(A) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
min: { add: {
.label return = plus.a+plus.b .label a = 2
// a+b
clc
adc.z a
// }
rts rts
} }

View File

@ -3,27 +3,42 @@ void main()
main: scope:[main] from main: scope:[main] from
[0] phi() [0] phi()
[1] call plus [1] call plus
[2] plus::return#0 = plus::return#2
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
[2] *SCREEN = min::return#1 [3] main::$0 = plus::return#0
[4] *SCREEN = main::$0
[5] call plus
[6] plus::return#1 = plus::return#2
to:main::@2
main::@2: scope:[main] from main::@1
[7] main::$1 = plus::return#1
[8] *(SCREEN+1) = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
[3] return [9] return
to:@return to:@return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
[4] phi() [10] plus::b#2 = phi( main/7, main::@1/6 )
[5] call min [10] plus::a#2 = phi( main/'0', main::@1/'1' )
[11] add::a#0 = plus::a#2
[12] add::b#0 = plus::b#2
[13] call add
[14] add::return#0 = add::return#1
to:plus::@1
plus::@1: scope:[plus] from plus
[15] plus::return#2 = add::return#0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus::@1
[6] return [16] return
to:@return to:@return
__bank(cx16_ram, 1) char min(char a , char b) __bank(cx16_ram, 1) char add(char a , char b)
min: scope:[min] from plus add: scope:[add] from plus
[7] phi() [17] add::return#1 = add::a#0 + add::b#0
to:min::@return to:add::@return
min::@return: scope:[min] from min add::@return: scope:[add] from add
[8] return [18] return
to:@return to:@return

View File

@ -7,47 +7,56 @@ main: scope:[main] from __start
plus::a#0 = '0' plus::a#0 = '0'
plus::b#0 = 7 plus::b#0 = 7
call plus call plus
plus::return#0 = plus::return#2 plus::return#0 = plus::return#3
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
plus::return#3 = phi( main/plus::return#0 ) plus::return#4 = phi( main/plus::return#0 )
main::$0 = plus::return#3 main::$0 = plus::return#4
SCREEN[0] = main::$0 SCREEN[0] = main::$0
plus::a#1 = '1'
plus::b#1 = 6
call plus
plus::return#1 = plus::return#3
to:main::@2
main::@2: scope:[main] from main::@1
plus::return#5 = phi( main::@1/plus::return#1 )
main::$1 = plus::return#5
SCREEN[1] = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
return return
to:@return to:@return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
plus::b#1 = phi( main/plus::b#0 ) plus::b#2 = phi( main/plus::b#0, main::@1/plus::b#1 )
plus::a#1 = phi( main/plus::a#0 ) plus::a#2 = phi( main/plus::a#0, main::@1/plus::a#1 )
min::a#0 = plus::a#1 add::a#0 = plus::a#2
min::b#0 = plus::b#1 add::b#0 = plus::b#2
call min call add
min::return#0 = min::return#2 add::return#0 = add::return#2
to:plus::@1 to:plus::@1
plus::@1: scope:[plus] from plus plus::@1: scope:[plus] from plus
min::return#3 = phi( plus/min::return#0 ) add::return#3 = phi( plus/add::return#0 )
plus::$0 = min::return#3 plus::$0 = add::return#3
plus::return#1 = plus::$0 plus::return#2 = plus::$0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus::@1 plus::@return: scope:[plus] from plus::@1
plus::return#4 = phi( plus::@1/plus::return#1 ) plus::return#6 = phi( plus::@1/plus::return#2 )
plus::return#2 = plus::return#4 plus::return#3 = plus::return#6
return return
to:@return to:@return
__bank(cx16_ram, 1) char min(char a , char b) __bank(cx16_ram, 1) char add(char a , char b)
min: scope:[min] from plus add: scope:[add] from plus
min::b#1 = phi( plus/min::b#0 ) add::b#1 = phi( plus/add::b#0 )
min::a#1 = phi( plus/min::a#0 ) add::a#1 = phi( plus/add::a#0 )
min::$0 = min::a#1 + min::b#1 add::$0 = add::a#1 + add::b#1
min::return#1 = min::$0 add::return#1 = add::$0
to:min::@return to:add::@return
min::@return: scope:[min] from min add::@return: scope:[add] from add
min::return#4 = phi( min/min::return#1 ) add::return#4 = phi( add/add::return#1 )
min::return#2 = min::return#4 add::return#2 = add::return#4
return return
to:@return to:@return
@ -64,64 +73,74 @@ __start::@return: scope:[__start] from __start::@1
SYMBOL TABLE SSA SYMBOL TABLE SSA
__constant char * const SCREEN = (char *)$400 __constant char * const SCREEN = (char *)$400
void __start() void __start()
__bank(cx16_ram, 1) char add(char a , char b)
char add::$0
char add::a
char add::a#0
char add::a#1
char add::b
char add::b#0
char add::b#1
char add::return
char add::return#0
char add::return#1
char add::return#2
char add::return#3
char add::return#4
void main() void main()
char main::$0 char main::$0
__bank(cx16_ram, 1) char min(char a , char b) char main::$1
char min::$0
char min::a
char min::a#0
char min::a#1
char min::b
char min::b#0
char min::b#1
char min::return
char min::return#0
char min::return#1
char min::return#2
char min::return#3
char min::return#4
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::$0 char plus::$0
char plus::a char plus::a
char plus::a#0 char plus::a#0
char plus::a#1 char plus::a#1
char plus::a#2
char plus::b char plus::b
char plus::b#0 char plus::b#0
char plus::b#1 char plus::b#1
char plus::b#2
char plus::return char plus::return
char plus::return#0 char plus::return#0
char plus::return#1 char plus::return#1
char plus::return#2 char plus::return#2
char plus::return#3 char plus::return#3
char plus::return#4 char plus::return#4
char plus::return#5
char plus::return#6
Adding number conversion cast (unumber) 7 in plus::b#0 = 7 Adding number conversion cast (unumber) 7 in plus::b#0 = 7
Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0 Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0
Adding number conversion cast (unumber) 6 in plus::b#1 = 6
Adding number conversion cast (unumber) 1 in SCREEN[1] = main::$1
Successful SSA optimization PassNAddNumberTypeConversions Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast plus::b#0 = (unumber)7 Inlining cast plus::b#0 = (unumber)7
Inlining cast plus::b#1 = (unumber)6
Successful SSA optimization Pass2InlineCast Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (char *) 1024 Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast 7 Simplifying constant integer cast 7
Simplifying constant integer cast 0 Simplifying constant integer cast 0
Simplifying constant integer cast 6
Simplifying constant integer cast 1
Successful SSA optimization PassNCastSimplification Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 7 Finalized unsigned number type (char) 7
Finalized unsigned number type (char) 0 Finalized unsigned number type (char) 0
Finalized unsigned number type (char) 6
Finalized unsigned number type (char) 1
Successful SSA optimization PassNFinalizeNumberTypeConversions Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias plus::return#0 = plus::return#3 Alias plus::return#0 = plus::return#4
Alias min::return#0 = min::return#3 Alias plus::return#1 = plus::return#5
Alias plus::return#1 = plus::$0 plus::return#4 plus::return#2 Alias add::return#0 = add::return#3
Alias min::return#1 = min::$0 min::return#4 min::return#2 Alias plus::return#2 = plus::$0 plus::return#6 plus::return#3
Alias add::return#1 = add::$0 add::return#4 add::return#2
Successful SSA optimization Pass2AliasElimination Successful SSA optimization Pass2AliasElimination
Identical Phi Values plus::a#1 plus::a#0 Identical Phi Values add::a#1 add::a#0
Identical Phi Values plus::b#1 plus::b#0 Identical Phi Values add::b#1 add::b#0
Identical Phi Values min::a#1 min::a#0
Identical Phi Values min::b#1 min::b#0
Successful SSA optimization Pass2IdenticalPhiElimination Successful SSA optimization Pass2IdenticalPhiElimination
Constant plus::a#0 = '0' Constant plus::a#0 = '0'
Constant plus::b#0 = 7 Constant plus::b#0 = 7
Successful SSA optimization Pass2ConstantIdentification Constant plus::a#1 = '1'
Constant min::a#0 = plus::a#0 Constant plus::b#1 = 6
Constant min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantIdentification Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0 Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0
Successful SSA optimization PassNSimplifyExpressionWithZero Successful SSA optimization PassNSimplifyExpressionWithZero
@ -130,40 +149,25 @@ Removing unused procedure block __start
Removing unused procedure block __start::@1 Removing unused procedure block __start::@1
Removing unused procedure block __start::@return Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart Successful SSA optimization PassNEliminateEmptyStart
Constant right-side identified [9] min::return#1 = min::a#0 + min::b#0 Inlining constant with var siblings plus::a#0
Successful SSA optimization Pass2ConstantRValueConsolidation Inlining constant with var siblings plus::b#0
Constant min::return#1 = min::a#0+min::b#0 Inlining constant with var siblings plus::a#1
Successful SSA optimization Pass2ConstantIdentification Inlining constant with var siblings plus::b#1
Constant min::return#0 = min::return#1 Constant inlined plus::b#1 = 6
Successful SSA optimization Pass2ConstantIdentification Constant inlined plus::b#0 = 7
Constant plus::return#1 = min::return#0 Constant inlined plus::a#1 = '1'
Successful SSA optimization Pass2ConstantIdentification Constant inlined plus::a#0 = '0'
Constant plus::return#0 = plus::return#1
Successful SSA optimization Pass2ConstantIdentification
Constant main::$0 = plus::return#0
Successful SSA optimization Pass2ConstantIdentification
Inlining constant with different constant siblings min::return#0
Constant inlined plus::return#0 = min::return#1
Constant inlined main::$0 = min::return#1
Constant inlined plus::return#1 = min::return#1
Constant inlined min::a#0 = plus::a#0
Constant inlined min::return#0 = min::return#1
Constant inlined min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantInlining Successful SSA optimization Pass2ConstantInlining
Consolidated array index constant in *(SCREEN+1)
Successful SSA optimization Pass2ConstantAdditionElimination
Adding NOP phi() at start of main Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of plus::@1
Adding NOP phi() at start of min
CALL GRAPH CALL GRAPH
Calls in [main] to plus:1 Calls in [main] to plus:1 plus:5
Calls in [plus] to min:5 Calls in [plus] to add:13
Created 0 initial phi equivalence classes Created 2 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes Coalesced down to 2 phi equivalence classes
Culled Empty Block label plus::@1
Adding NOP phi() at start of main Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of min
FINAL CONTROL FLOW GRAPH FINAL CONTROL FLOW GRAPH
@ -171,59 +175,141 @@ void main()
main: scope:[main] from main: scope:[main] from
[0] phi() [0] phi()
[1] call plus [1] call plus
[2] plus::return#0 = plus::return#2
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
[2] *SCREEN = min::return#1 [3] main::$0 = plus::return#0
[4] *SCREEN = main::$0
[5] call plus
[6] plus::return#1 = plus::return#2
to:main::@2
main::@2: scope:[main] from main::@1
[7] main::$1 = plus::return#1
[8] *(SCREEN+1) = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
[3] return [9] return
to:@return to:@return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
[4] phi() [10] plus::b#2 = phi( main/7, main::@1/6 )
[5] call min [10] plus::a#2 = phi( main/'0', main::@1/'1' )
[11] add::a#0 = plus::a#2
[12] add::b#0 = plus::b#2
[13] call add
[14] add::return#0 = add::return#1
to:plus::@1
plus::@1: scope:[plus] from plus
[15] plus::return#2 = add::return#0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus::@1
[6] return [16] return
to:@return to:@return
__bank(cx16_ram, 1) char min(char a , char b) __bank(cx16_ram, 1) char add(char a , char b)
min: scope:[min] from plus add: scope:[add] from plus
[7] phi() [17] add::return#1 = add::a#0 + add::b#0
to:min::@return to:add::@return
min::@return: scope:[min] from min add::@return: scope:[add] from add
[8] return [18] return
to:@return to:@return
VARIABLE REGISTER WEIGHTS VARIABLE REGISTER WEIGHTS
__bank(cx16_ram, 1) char add(char a , char b)
char add::a
char add::a#0 // 56.0
char add::b
char add::b#0 // 112.0
char add::return
char add::return#0 // 22.0
char add::return#1 // 37.33333333333333
void main() void main()
__bank(cx16_ram, 1) char min(char a , char b) char main::$0 // 4.0
char min::a char main::$1 // 4.0
char min::b
char min::return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::a char plus::a
char plus::a#2 // 11.0
char plus::b char plus::b
char plus::b#2 // 5.5
char plus::return char plus::return
char plus::return#0 // 4.0
char plus::return#1 // 4.0
char plus::return#2 // 3.75
Initial phi equivalence classes Initial phi equivalence classes
[ plus::a#2 ]
[ plus::b#2 ]
Added variable plus::return#0 to live range equivalence class [ plus::return#0 ]
Added variable main::$0 to live range equivalence class [ main::$0 ]
Added variable plus::return#1 to live range equivalence class [ plus::return#1 ]
Added variable main::$1 to live range equivalence class [ main::$1 ]
Added variable add::a#0 to live range equivalence class [ add::a#0 ]
Added variable add::b#0 to live range equivalence class [ add::b#0 ]
Added variable add::return#0 to live range equivalence class [ add::return#0 ]
Added variable plus::return#2 to live range equivalence class [ plus::return#2 ]
Added variable add::return#1 to live range equivalence class [ add::return#1 ]
Complete equivalence classes Complete equivalence classes
[ plus::a#2 ]
[ plus::b#2 ]
[ plus::return#0 ]
[ main::$0 ]
[ plus::return#1 ]
[ main::$1 ]
[ add::a#0 ]
[ add::b#0 ]
[ add::return#0 ]
[ plus::return#2 ]
[ add::return#1 ]
Allocated zp[1]:2 [ add::b#0 ]
Allocated zp[1]:3 [ add::a#0 ]
Allocated zp[1]:4 [ add::return#1 ]
Allocated zp[1]:5 [ add::return#0 ]
Allocated zp[1]:6 [ plus::a#2 ]
Allocated zp[1]:7 [ plus::b#2 ]
Allocated zp[1]:8 [ plus::return#0 ]
Allocated zp[1]:9 [ main::$0 ]
Allocated zp[1]:10 [ plus::return#1 ]
Allocated zp[1]:11 [ main::$1 ]
Allocated zp[1]:12 [ plus::return#2 ]
REGISTER UPLIFT POTENTIAL REGISTERS REGISTER UPLIFT POTENTIAL REGISTERS
Statement [1] call plus [ ] ( [ ] { } ) always clobbers reg byte a Statement [1] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#0 = plus::return#2 } } ) always clobbers reg byte a
Statement [2] *SCREEN = min::return#1 [ ] ( [ ] { } ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:12 [ plus::return#2 ]
Statement [5] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#1 = plus::return#2 } } ) always clobbers reg byte a
Statement [17] add::return#1 = add::a#0 + add::b#0 [ add::return#1 ] ( plus:1::add:13 [ add::return#1 ] { { plus::return#0 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } plus:5::add:13 [ add::return#1 ] { { plus::return#1 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } ) always clobbers reg byte a
Statement [1] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#0 = plus::return#2 } } ) always clobbers reg byte a
Statement [5] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#1 = plus::return#2 } } ) always clobbers reg byte a
Statement [17] add::return#1 = add::a#0 + add::b#0 [ add::return#1 ] ( plus:1::add:13 [ add::return#1 ] { { plus::return#0 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } plus:5::add:13 [ add::return#1 ] { { plus::return#1 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } ) always clobbers reg byte a
Potential registers zp[1]:6 [ plus::a#2 ] : zp[1]:6 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:7 [ plus::b#2 ] : zp[1]:7 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:8 [ plus::return#0 ] : zp[1]:8 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:9 [ main::$0 ] : zp[1]:9 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:10 [ plus::return#1 ] : zp[1]:10 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:11 [ main::$1 ] : zp[1]:11 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:3 [ add::a#0 ] : zp[1]:3 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:2 [ add::b#0 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:5 [ add::return#0 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:12 [ plus::return#2 ] : zp[1]:12 , reg byte x , reg byte y ,
Potential registers zp[1]:4 [ add::return#1 ] : zp[1]:4 , reg byte a , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES REGISTER UPLIFT SCOPES
Uplift Scope [main] Uplift Scope [add] 112: zp[1]:2 [ add::b#0 ] 56: zp[1]:3 [ add::a#0 ] 37.33: zp[1]:4 [ add::return#1 ] 22: zp[1]:5 [ add::return#0 ]
Uplift Scope [plus] Uplift Scope [plus] 11: zp[1]:6 [ plus::a#2 ] 5.5: zp[1]:7 [ plus::b#2 ] 4: zp[1]:8 [ plus::return#0 ] 4: zp[1]:10 [ plus::return#1 ] 3.75: zp[1]:12 [ plus::return#2 ]
Uplift Scope [min] Uplift Scope [main] 4: zp[1]:9 [ main::$0 ] 4: zp[1]:11 [ main::$1 ]
Uplift Scope [] Uplift Scope []
Uplifting [main] best 93 combination Uplifting [add] best 189 combination reg byte a [ add::b#0 ] zp[1]:3 [ add::a#0 ] reg byte a [ add::return#1 ] reg byte a [ add::return#0 ]
Uplifting [plus] best 93 combination Limited combination testing to 100 combinations of 256 possible.
Uplifting [min] best 93 combination Uplifting [plus] best 161 combination reg byte a [ plus::a#2 ] reg byte x [ plus::b#2 ] reg byte a [ plus::return#0 ] reg byte a [ plus::return#1 ] zp[1]:12 [ plus::return#2 ]
Uplifting [] best 93 combination Limited combination testing to 100 combinations of 768 possible.
Uplifting [main] best 149 combination reg byte a [ main::$0 ] reg byte a [ main::$1 ]
Uplifting [] best 149 combination
Attempting to uplift remaining variables inzp[1]:3 [ add::a#0 ]
Uplifting [add] best 149 combination zp[1]:3 [ add::a#0 ]
Attempting to uplift remaining variables inzp[1]:12 [ plus::return#2 ]
Uplifting [plus] best 146 combination reg byte x [ plus::return#2 ]
Allocated (was zp[1]:3) zp[1]:2 [ add::a#0 ]
ASSEMBLER BEFORE OPTIMIZATION ASSEMBLER BEFORE OPTIMIZATION
// File Comments // File Comments
@ -275,90 +361,159 @@ ASSEMBLER BEFORE OPTIMIZATION
// main // main
main: { main: {
// [1] call plus // [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_phi_close_cx16_ram // [10] phi from main to plus [phi:main->plus]
plus_from_main: plus_from_main:
// [10] phi plus::b#2 = 7 [phi:main->plus#0] -- vbuxx=vbuc1
ldx #7
// [10] phi plus::a#2 = '0' [phi:main->plus#1] -- call_phi_close_cx16_ram
lda #'0'
sta.z $ff
lda.z 0 lda.z 0
pha pha
lda #1 lda #1
sta.z 0 sta.z 0
lda.z $ff
jsr plus jsr plus
sta.z $ff
pla pla
sta.z 0 sta.z 0
lda.z $ff
// [2] plus::return#0 = plus::return#2 -- vbuaa=vbuxx
txa
jmp __b1 jmp __b1
// main::@1 // main::@1
__b1: __b1:
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2 // [3] main::$0 = plus::return#0
lda #min.return // [4] *SCREEN = main::$0 -- _deref_pbuc1=vbuaa
sta SCREEN sta SCREEN
// [5] call plus
// [10] phi from main::@1 to plus [phi:main::@1->plus]
plus_from___b1:
// [10] phi plus::b#2 = 6 [phi:main::@1->plus#0] -- vbuxx=vbuc1
ldx #6
// [10] phi plus::a#2 = '1' [phi:main::@1->plus#1] -- call_phi_close_cx16_ram
lda #'1'
sta.z $ff
lda.z 0
pha
lda #1
sta.z 0
lda.z $ff
jsr plus
sta.z $ff
pla
sta.z 0
lda.z $ff
// [6] plus::return#1 = plus::return#2 -- vbuaa=vbuxx
txa
jmp __b2
// main::@2
__b2:
// [7] main::$1 = plus::return#1
// [8] *(SCREEN+1) = main::$1 -- _deref_pbuc1=vbuaa
// close call
sta SCREEN+1
jmp __breturn jmp __breturn
// main::@return // main::@return
__breturn: __breturn:
// [3] return // [9] return
rts rts
} }
.segment RAM_Bank1 .segment RAM_Bank1
// plus // plus
// char plus(char a, char b) // __register(X) char plus(__register(A) char a, __register(X) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
plus: { plus: {
.label a = '0' // [11] add::a#0 = plus::a#2 -- vbuz1=vbuaa
.label b = 7 sta.z add.a
// [5] call min // [12] add::b#0 = plus::b#2 -- vbuaa=vbuxx
// [7] phi from plus to min [phi:plus->min] txa
min_from_plus: // [13] call add
jsr min jsr add
// [14] add::return#0 = add::return#1
jmp __b1
// plus::@1
__b1:
// [15] plus::return#2 = add::return#0 -- vbuxx=vbuaa
tax
jmp __breturn jmp __breturn
// plus::@return // plus::@return
__breturn: __breturn:
// [6] return // [16] return
rts rts
} }
// min // add
// char min(char a, char b) // __register(A) char add(__zp(2) char a, __register(A) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
min: { add: {
.label return = plus.a+plus.b .label a = 2
// [17] add::return#1 = add::a#0 + add::b#0 -- vbuaa=vbuz1_plus_vbuaa
clc
adc.z a
jmp __breturn jmp __breturn
// min::@return // add::@return
__breturn: __breturn:
// [8] return // [18] return
rts rts
} }
// File Data // File Data
ASSEMBLER OPTIMIZATIONS ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1 Removing instruction jmp __b1
Removing instruction jmp __b2
Removing instruction jmp __breturn Removing instruction jmp __breturn
Removing instruction jmp __b1
Removing instruction jmp __breturn Removing instruction jmp __breturn
Removing instruction jmp __breturn Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination Succesful ASM optimization Pass5NextJumpElimination
Removing instruction plus_from_main: Removing instruction plus_from_main:
Removing instruction __b1: Removing instruction __b1:
Removing instruction plus_from___b1:
Removing instruction __b2:
Removing instruction __breturn: Removing instruction __breturn:
Removing instruction min_from_plus: Removing instruction __b1:
Removing instruction __breturn: Removing instruction __breturn:
Removing instruction __breturn: Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE FINAL SYMBOL TABLE
__constant char * const SCREEN = (char *) 1024 __constant char * const SCREEN = (char *) 1024
__bank(cx16_ram, 1) char add(char a , char b)
char add::a
char add::a#0 // a zp[1]:2 56.0
char add::b
char add::b#0 // reg byte a 112.0
char add::return
char add::return#0 // reg byte a 22.0
char add::return#1 // reg byte a 37.33333333333333
void main() void main()
__bank(cx16_ram, 1) char min(char a , char b) char main::$0 // reg byte a 4.0
char min::a char main::$1 // reg byte a 4.0
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::a char plus::a
__constant char plus::a#0 = '0' // a char plus::a#2 // reg byte a 11.0
char plus::b char plus::b
__constant char plus::b#0 = 7 // b char plus::b#2 // reg byte x 5.5
char plus::return char plus::return
char plus::return#0 // reg byte a 4.0
char plus::return#1 // reg byte a 4.0
char plus::return#2 // reg byte x 3.75
reg byte a [ plus::a#2 ]
reg byte x [ plus::b#2 ]
reg byte a [ plus::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ plus::return#1 ]
reg byte a [ main::$1 ]
zp[1]:2 [ add::a#0 ]
reg byte a [ add::b#0 ]
reg byte a [ add::return#0 ]
reg byte x [ plus::return#2 ]
reg byte a [ add::return#1 ]
FINAL ASSEMBLER FINAL ASSEMBLER
Score: 54 Score: 128
// File Comments // File Comments
/** /**
@ -410,47 +565,95 @@ Score: 54
main: { main: {
// plus('0', 7) // plus('0', 7)
// [1] call plus // [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_phi_close_cx16_ram // [10] phi from main to plus [phi:main->plus]
// [10] phi plus::b#2 = 7 [phi:main->plus#0] -- vbuxx=vbuc1
ldx #7
// [10] phi plus::a#2 = '0' [phi:main->plus#1] -- call_phi_close_cx16_ram
lda #'0'
sta.z $ff
lda.z 0 lda.z 0
pha pha
lda #1 lda #1
sta.z 0 sta.z 0
lda.z $ff
jsr plus jsr plus
sta.z $ff
pla pla
sta.z 0 sta.z 0
lda.z $ff
// plus('0', 7)
// [2] plus::return#0 = plus::return#2 -- vbuaa=vbuxx
txa
// main::@1 // main::@1
// [3] main::$0 = plus::return#0
// SCREEN[0] = plus('0', 7) // SCREEN[0] = plus('0', 7)
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2 // [4] *SCREEN = main::$0 -- _deref_pbuc1=vbuaa
lda #min.return
sta SCREEN sta SCREEN
// plus('1', 6)
// [5] call plus
// [10] phi from main::@1 to plus [phi:main::@1->plus]
// [10] phi plus::b#2 = 6 [phi:main::@1->plus#0] -- vbuxx=vbuc1
ldx #6
// [10] phi plus::a#2 = '1' [phi:main::@1->plus#1] -- call_phi_close_cx16_ram
lda #'1'
sta.z $ff
lda.z 0
pha
lda #1
sta.z 0
lda.z $ff
jsr plus
sta.z $ff
pla
sta.z 0
lda.z $ff
// plus('1', 6)
// [6] plus::return#1 = plus::return#2 -- vbuaa=vbuxx
txa
// main::@2
// [7] main::$1 = plus::return#1
// SCREEN[1] = plus('1', 6)
// [8] *(SCREEN+1) = main::$1 -- _deref_pbuc1=vbuaa
// close call
sta SCREEN+1
// main::@return // main::@return
// } // }
// [3] return // [9] return
rts rts
} }
.segment RAM_Bank1 .segment RAM_Bank1
// plus // plus
// char plus(char a, char b) // __register(X) char plus(__register(A) char a, __register(X) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
plus: { plus: {
.label a = '0' // add(a, b)
.label b = 7 // [11] add::a#0 = plus::a#2 -- vbuz1=vbuaa
// min(a, b) sta.z add.a
// [5] call min // [12] add::b#0 = plus::b#2 -- vbuaa=vbuxx
// [7] phi from plus to min [phi:plus->min] txa
jsr min // [13] call add
jsr add
// [14] add::return#0 = add::return#1
// plus::@1
// [15] plus::return#2 = add::return#0 -- vbuxx=vbuaa
tax
// plus::@return // plus::@return
// } // }
// [6] return // [16] return
rts rts
} }
// min // add
// char min(char a, char b) // __register(A) char add(__zp(2) char a, __register(A) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
min: { add: {
.label return = plus.a+plus.b .label a = 2
// min::@return // a+b
// [8] return // [17] add::return#1 = add::a#0 + add::b#0 -- vbuaa=vbuz1_plus_vbuaa
clc
adc.z a
// add::@return
// }
// [18] return
rts rts
} }
// File Data // File Data

View File

@ -1,14 +1,33 @@
__constant char * const SCREEN = (char *) 1024 __constant char * const SCREEN = (char *) 1024
__bank(cx16_ram, 1) char add(char a , char b)
char add::a
char add::a#0 // a zp[1]:2 56.0
char add::b
char add::b#0 // reg byte a 112.0
char add::return
char add::return#0 // reg byte a 22.0
char add::return#1 // reg byte a 37.33333333333333
void main() void main()
__bank(cx16_ram, 1) char min(char a , char b) char main::$0 // reg byte a 4.0
char min::a char main::$1 // reg byte a 4.0
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::a char plus::a
__constant char plus::a#0 = '0' // a char plus::a#2 // reg byte a 11.0
char plus::b char plus::b
__constant char plus::b#0 = 7 // b char plus::b#2 // reg byte x 5.5
char plus::return char plus::return
char plus::return#0 // reg byte a 4.0
char plus::return#1 // reg byte a 4.0
char plus::return#2 // reg byte x 3.75
reg byte a [ plus::a#2 ]
reg byte x [ plus::b#2 ]
reg byte a [ plus::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ plus::return#1 ]
reg byte a [ main::$1 ]
zp[1]:2 [ add::a#0 ]
reg byte a [ add::b#0 ]
reg byte a [ add::return#0 ]
reg byte x [ plus::return#2 ]
reg byte a [ add::return#1 ]

View File

@ -43,37 +43,68 @@
.segment Code .segment Code
main: { main: {
// plus('0', 7) // plus('0', 7)
ldx #7
lda #'0'
sta.z $ff
lda.z 0 lda.z 0
pha pha
lda #1 lda #1
sta.z 0 sta.z 0
lda.z $ff
jsr plus jsr plus
sta.z $ff
pla pla
sta.z 0 sta.z 0
lda.z $ff
// plus('0', 7)
txa
// SCREEN[0] = plus('0', 7) // SCREEN[0] = plus('0', 7)
lda #min.return
sta SCREEN sta SCREEN
// plus('1', 6)
ldx #6
lda #'1'
sta.z $ff
lda.z 0
pha
lda #1
sta.z 0
lda.z $ff
jsr plus
sta.z $ff
pla
sta.z 0
lda.z $ff
// plus('1', 6)
txa
// SCREEN[1] = plus('1', 6)
// close call
sta SCREEN+1
// } // }
rts rts
} }
.segment RAM_Bank1 .segment RAM_Bank1
// char plus(char a, char b) // __register(X) char plus(__register(A) char a, __register(X) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
plus: { plus: {
.label a = '0' // add(a, b)
.label b = 7 sta.z add.a
// min(a, b) txa
jsr $ff6e jsr $ff6e
.byte <min .byte <add
.byte >min .byte >add
.byte 2 .byte 2
tax
// } // }
rts rts
} }
.segment RAM_Bank2 .segment RAM_Bank2
// char min(char a, char b) // __register(A) char add(__zp(2) char a, __register(A) char b)
// __bank(cx16_ram, 2) // __bank(cx16_ram, 2)
min: { add: {
.label return = plus.a+plus.b .label a = 2
// a+b
clc
adc.z a
// }
rts rts
} }

View File

@ -3,27 +3,42 @@ void main()
main: scope:[main] from main: scope:[main] from
[0] phi() [0] phi()
[1] call plus [1] call plus
[2] plus::return#0 = plus::return#2
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
[2] *SCREEN = min::return#1 [3] main::$0 = plus::return#0
[4] *SCREEN = main::$0
[5] call plus
[6] plus::return#1 = plus::return#2
to:main::@2
main::@2: scope:[main] from main::@1
[7] main::$1 = plus::return#1
[8] *(SCREEN+1) = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
[3] return [9] return
to:@return to:@return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
[4] phi() [10] plus::b#2 = phi( main/7, main::@1/6 )
[5] call min [10] plus::a#2 = phi( main/'0', main::@1/'1' )
[11] add::a#0 = plus::a#2
[12] add::b#0 = plus::b#2
[13] call add
[14] add::return#0 = add::return#1
to:plus::@1
plus::@1: scope:[plus] from plus
[15] plus::return#2 = add::return#0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus::@1
[6] return [16] return
to:@return to:@return
__bank(cx16_ram, 2) char min(char a , char b) __bank(cx16_ram, 2) char add(char a , char b)
min: scope:[min] from plus add: scope:[add] from plus
[7] phi() [17] add::return#1 = add::a#0 + add::b#0
to:min::@return to:add::@return
min::@return: scope:[min] from min add::@return: scope:[add] from add
[8] return [18] return
to:@return to:@return

View File

@ -7,47 +7,56 @@ main: scope:[main] from __start
plus::a#0 = '0' plus::a#0 = '0'
plus::b#0 = 7 plus::b#0 = 7
call plus call plus
plus::return#0 = plus::return#2 plus::return#0 = plus::return#3
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
plus::return#3 = phi( main/plus::return#0 ) plus::return#4 = phi( main/plus::return#0 )
main::$0 = plus::return#3 main::$0 = plus::return#4
SCREEN[0] = main::$0 SCREEN[0] = main::$0
plus::a#1 = '1'
plus::b#1 = 6
call plus
plus::return#1 = plus::return#3
to:main::@2
main::@2: scope:[main] from main::@1
plus::return#5 = phi( main::@1/plus::return#1 )
main::$1 = plus::return#5
SCREEN[1] = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
return return
to:@return to:@return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
plus::b#1 = phi( main/plus::b#0 ) plus::b#2 = phi( main/plus::b#0, main::@1/plus::b#1 )
plus::a#1 = phi( main/plus::a#0 ) plus::a#2 = phi( main/plus::a#0, main::@1/plus::a#1 )
min::a#0 = plus::a#1 add::a#0 = plus::a#2
min::b#0 = plus::b#1 add::b#0 = plus::b#2
call min call add
min::return#0 = min::return#2 add::return#0 = add::return#2
to:plus::@1 to:plus::@1
plus::@1: scope:[plus] from plus plus::@1: scope:[plus] from plus
min::return#3 = phi( plus/min::return#0 ) add::return#3 = phi( plus/add::return#0 )
plus::$0 = min::return#3 plus::$0 = add::return#3
plus::return#1 = plus::$0 plus::return#2 = plus::$0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus::@1 plus::@return: scope:[plus] from plus::@1
plus::return#4 = phi( plus::@1/plus::return#1 ) plus::return#6 = phi( plus::@1/plus::return#2 )
plus::return#2 = plus::return#4 plus::return#3 = plus::return#6
return return
to:@return to:@return
__bank(cx16_ram, 2) char min(char a , char b) __bank(cx16_ram, 2) char add(char a , char b)
min: scope:[min] from plus add: scope:[add] from plus
min::b#1 = phi( plus/min::b#0 ) add::b#1 = phi( plus/add::b#0 )
min::a#1 = phi( plus/min::a#0 ) add::a#1 = phi( plus/add::a#0 )
min::$0 = min::a#1 + min::b#1 add::$0 = add::a#1 + add::b#1
min::return#1 = min::$0 add::return#1 = add::$0
to:min::@return to:add::@return
min::@return: scope:[min] from min add::@return: scope:[add] from add
min::return#4 = phi( min/min::return#1 ) add::return#4 = phi( add/add::return#1 )
min::return#2 = min::return#4 add::return#2 = add::return#4
return return
to:@return to:@return
@ -64,64 +73,74 @@ __start::@return: scope:[__start] from __start::@1
SYMBOL TABLE SSA SYMBOL TABLE SSA
__constant char * const SCREEN = (char *)$400 __constant char * const SCREEN = (char *)$400
void __start() void __start()
__bank(cx16_ram, 2) char add(char a , char b)
char add::$0
char add::a
char add::a#0
char add::a#1
char add::b
char add::b#0
char add::b#1
char add::return
char add::return#0
char add::return#1
char add::return#2
char add::return#3
char add::return#4
void main() void main()
char main::$0 char main::$0
__bank(cx16_ram, 2) char min(char a , char b) char main::$1
char min::$0
char min::a
char min::a#0
char min::a#1
char min::b
char min::b#0
char min::b#1
char min::return
char min::return#0
char min::return#1
char min::return#2
char min::return#3
char min::return#4
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::$0 char plus::$0
char plus::a char plus::a
char plus::a#0 char plus::a#0
char plus::a#1 char plus::a#1
char plus::a#2
char plus::b char plus::b
char plus::b#0 char plus::b#0
char plus::b#1 char plus::b#1
char plus::b#2
char plus::return char plus::return
char plus::return#0 char plus::return#0
char plus::return#1 char plus::return#1
char plus::return#2 char plus::return#2
char plus::return#3 char plus::return#3
char plus::return#4 char plus::return#4
char plus::return#5
char plus::return#6
Adding number conversion cast (unumber) 7 in plus::b#0 = 7 Adding number conversion cast (unumber) 7 in plus::b#0 = 7
Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0 Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0
Adding number conversion cast (unumber) 6 in plus::b#1 = 6
Adding number conversion cast (unumber) 1 in SCREEN[1] = main::$1
Successful SSA optimization PassNAddNumberTypeConversions Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast plus::b#0 = (unumber)7 Inlining cast plus::b#0 = (unumber)7
Inlining cast plus::b#1 = (unumber)6
Successful SSA optimization Pass2InlineCast Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (char *) 1024 Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast 7 Simplifying constant integer cast 7
Simplifying constant integer cast 0 Simplifying constant integer cast 0
Simplifying constant integer cast 6
Simplifying constant integer cast 1
Successful SSA optimization PassNCastSimplification Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 7 Finalized unsigned number type (char) 7
Finalized unsigned number type (char) 0 Finalized unsigned number type (char) 0
Finalized unsigned number type (char) 6
Finalized unsigned number type (char) 1
Successful SSA optimization PassNFinalizeNumberTypeConversions Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias plus::return#0 = plus::return#3 Alias plus::return#0 = plus::return#4
Alias min::return#0 = min::return#3 Alias plus::return#1 = plus::return#5
Alias plus::return#1 = plus::$0 plus::return#4 plus::return#2 Alias add::return#0 = add::return#3
Alias min::return#1 = min::$0 min::return#4 min::return#2 Alias plus::return#2 = plus::$0 plus::return#6 plus::return#3
Alias add::return#1 = add::$0 add::return#4 add::return#2
Successful SSA optimization Pass2AliasElimination Successful SSA optimization Pass2AliasElimination
Identical Phi Values plus::a#1 plus::a#0 Identical Phi Values add::a#1 add::a#0
Identical Phi Values plus::b#1 plus::b#0 Identical Phi Values add::b#1 add::b#0
Identical Phi Values min::a#1 min::a#0
Identical Phi Values min::b#1 min::b#0
Successful SSA optimization Pass2IdenticalPhiElimination Successful SSA optimization Pass2IdenticalPhiElimination
Constant plus::a#0 = '0' Constant plus::a#0 = '0'
Constant plus::b#0 = 7 Constant plus::b#0 = 7
Successful SSA optimization Pass2ConstantIdentification Constant plus::a#1 = '1'
Constant min::a#0 = plus::a#0 Constant plus::b#1 = 6
Constant min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantIdentification Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0 Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0
Successful SSA optimization PassNSimplifyExpressionWithZero Successful SSA optimization PassNSimplifyExpressionWithZero
@ -130,40 +149,25 @@ Removing unused procedure block __start
Removing unused procedure block __start::@1 Removing unused procedure block __start::@1
Removing unused procedure block __start::@return Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart Successful SSA optimization PassNEliminateEmptyStart
Constant right-side identified [9] min::return#1 = min::a#0 + min::b#0 Inlining constant with var siblings plus::a#0
Successful SSA optimization Pass2ConstantRValueConsolidation Inlining constant with var siblings plus::b#0
Constant min::return#1 = min::a#0+min::b#0 Inlining constant with var siblings plus::a#1
Successful SSA optimization Pass2ConstantIdentification Inlining constant with var siblings plus::b#1
Constant min::return#0 = min::return#1 Constant inlined plus::b#1 = 6
Successful SSA optimization Pass2ConstantIdentification Constant inlined plus::b#0 = 7
Constant plus::return#1 = min::return#0 Constant inlined plus::a#1 = '1'
Successful SSA optimization Pass2ConstantIdentification Constant inlined plus::a#0 = '0'
Constant plus::return#0 = plus::return#1
Successful SSA optimization Pass2ConstantIdentification
Constant main::$0 = plus::return#0
Successful SSA optimization Pass2ConstantIdentification
Inlining constant with different constant siblings min::return#0
Constant inlined plus::return#0 = min::return#1
Constant inlined main::$0 = min::return#1
Constant inlined plus::return#1 = min::return#1
Constant inlined min::a#0 = plus::a#0
Constant inlined min::return#0 = min::return#1
Constant inlined min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantInlining Successful SSA optimization Pass2ConstantInlining
Consolidated array index constant in *(SCREEN+1)
Successful SSA optimization Pass2ConstantAdditionElimination
Adding NOP phi() at start of main Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of plus::@1
Adding NOP phi() at start of min
CALL GRAPH CALL GRAPH
Calls in [main] to plus:1 Calls in [main] to plus:1 plus:5
Calls in [plus] to min:5 Calls in [plus] to add:13
Created 0 initial phi equivalence classes Created 2 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes Coalesced down to 2 phi equivalence classes
Culled Empty Block label plus::@1
Adding NOP phi() at start of main Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of min
FINAL CONTROL FLOW GRAPH FINAL CONTROL FLOW GRAPH
@ -171,59 +175,141 @@ void main()
main: scope:[main] from main: scope:[main] from
[0] phi() [0] phi()
[1] call plus [1] call plus
[2] plus::return#0 = plus::return#2
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
[2] *SCREEN = min::return#1 [3] main::$0 = plus::return#0
[4] *SCREEN = main::$0
[5] call plus
[6] plus::return#1 = plus::return#2
to:main::@2
main::@2: scope:[main] from main::@1
[7] main::$1 = plus::return#1
[8] *(SCREEN+1) = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
[3] return [9] return
to:@return to:@return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
[4] phi() [10] plus::b#2 = phi( main/7, main::@1/6 )
[5] call min [10] plus::a#2 = phi( main/'0', main::@1/'1' )
[11] add::a#0 = plus::a#2
[12] add::b#0 = plus::b#2
[13] call add
[14] add::return#0 = add::return#1
to:plus::@1
plus::@1: scope:[plus] from plus
[15] plus::return#2 = add::return#0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus::@1
[6] return [16] return
to:@return to:@return
__bank(cx16_ram, 2) char min(char a , char b) __bank(cx16_ram, 2) char add(char a , char b)
min: scope:[min] from plus add: scope:[add] from plus
[7] phi() [17] add::return#1 = add::a#0 + add::b#0
to:min::@return to:add::@return
min::@return: scope:[min] from min add::@return: scope:[add] from add
[8] return [18] return
to:@return to:@return
VARIABLE REGISTER WEIGHTS VARIABLE REGISTER WEIGHTS
__bank(cx16_ram, 2) char add(char a , char b)
char add::a
char add::a#0 // 56.0
char add::b
char add::b#0 // 112.0
char add::return
char add::return#0 // 22.0
char add::return#1 // 37.33333333333333
void main() void main()
__bank(cx16_ram, 2) char min(char a , char b) char main::$0 // 4.0
char min::a char main::$1 // 4.0
char min::b
char min::return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::a char plus::a
char plus::a#2 // 11.0
char plus::b char plus::b
char plus::b#2 // 5.5
char plus::return char plus::return
char plus::return#0 // 4.0
char plus::return#1 // 4.0
char plus::return#2 // 3.75
Initial phi equivalence classes Initial phi equivalence classes
[ plus::a#2 ]
[ plus::b#2 ]
Added variable plus::return#0 to live range equivalence class [ plus::return#0 ]
Added variable main::$0 to live range equivalence class [ main::$0 ]
Added variable plus::return#1 to live range equivalence class [ plus::return#1 ]
Added variable main::$1 to live range equivalence class [ main::$1 ]
Added variable add::a#0 to live range equivalence class [ add::a#0 ]
Added variable add::b#0 to live range equivalence class [ add::b#0 ]
Added variable add::return#0 to live range equivalence class [ add::return#0 ]
Added variable plus::return#2 to live range equivalence class [ plus::return#2 ]
Added variable add::return#1 to live range equivalence class [ add::return#1 ]
Complete equivalence classes Complete equivalence classes
[ plus::a#2 ]
[ plus::b#2 ]
[ plus::return#0 ]
[ main::$0 ]
[ plus::return#1 ]
[ main::$1 ]
[ add::a#0 ]
[ add::b#0 ]
[ add::return#0 ]
[ plus::return#2 ]
[ add::return#1 ]
Allocated zp[1]:2 [ add::b#0 ]
Allocated zp[1]:3 [ add::a#0 ]
Allocated zp[1]:4 [ add::return#1 ]
Allocated zp[1]:5 [ add::return#0 ]
Allocated zp[1]:6 [ plus::a#2 ]
Allocated zp[1]:7 [ plus::b#2 ]
Allocated zp[1]:8 [ plus::return#0 ]
Allocated zp[1]:9 [ main::$0 ]
Allocated zp[1]:10 [ plus::return#1 ]
Allocated zp[1]:11 [ main::$1 ]
Allocated zp[1]:12 [ plus::return#2 ]
REGISTER UPLIFT POTENTIAL REGISTERS REGISTER UPLIFT POTENTIAL REGISTERS
Statement [1] call plus [ ] ( [ ] { } ) always clobbers reg byte a Statement [1] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#0 = plus::return#2 } } ) always clobbers reg byte a
Statement [2] *SCREEN = min::return#1 [ ] ( [ ] { } ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:12 [ plus::return#2 ]
Statement [5] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#1 = plus::return#2 } } ) always clobbers reg byte a
Statement [17] add::return#1 = add::a#0 + add::b#0 [ add::return#1 ] ( plus:1::add:13 [ add::return#1 ] { { plus::return#0 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } plus:5::add:13 [ add::return#1 ] { { plus::return#1 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } ) always clobbers reg byte a
Statement [1] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#0 = plus::return#2 } } ) always clobbers reg byte a
Statement [5] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#1 = plus::return#2 } } ) always clobbers reg byte a
Statement [17] add::return#1 = add::a#0 + add::b#0 [ add::return#1 ] ( plus:1::add:13 [ add::return#1 ] { { plus::return#0 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } plus:5::add:13 [ add::return#1 ] { { plus::return#1 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } ) always clobbers reg byte a
Potential registers zp[1]:6 [ plus::a#2 ] : zp[1]:6 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:7 [ plus::b#2 ] : zp[1]:7 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:8 [ plus::return#0 ] : zp[1]:8 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:9 [ main::$0 ] : zp[1]:9 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:10 [ plus::return#1 ] : zp[1]:10 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:11 [ main::$1 ] : zp[1]:11 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:3 [ add::a#0 ] : zp[1]:3 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:2 [ add::b#0 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:5 [ add::return#0 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:12 [ plus::return#2 ] : zp[1]:12 , reg byte x , reg byte y ,
Potential registers zp[1]:4 [ add::return#1 ] : zp[1]:4 , reg byte a , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES REGISTER UPLIFT SCOPES
Uplift Scope [main] Uplift Scope [add] 112: zp[1]:2 [ add::b#0 ] 56: zp[1]:3 [ add::a#0 ] 37.33: zp[1]:4 [ add::return#1 ] 22: zp[1]:5 [ add::return#0 ]
Uplift Scope [plus] Uplift Scope [plus] 11: zp[1]:6 [ plus::a#2 ] 5.5: zp[1]:7 [ plus::b#2 ] 4: zp[1]:8 [ plus::return#0 ] 4: zp[1]:10 [ plus::return#1 ] 3.75: zp[1]:12 [ plus::return#2 ]
Uplift Scope [min] Uplift Scope [main] 4: zp[1]:9 [ main::$0 ] 4: zp[1]:11 [ main::$1 ]
Uplift Scope [] Uplift Scope []
Uplifting [main] best 93 combination Uplifting [add] best 189 combination reg byte a [ add::b#0 ] zp[1]:3 [ add::a#0 ] reg byte a [ add::return#1 ] reg byte a [ add::return#0 ]
Uplifting [plus] best 93 combination Limited combination testing to 100 combinations of 256 possible.
Uplifting [min] best 93 combination Uplifting [plus] best 161 combination reg byte a [ plus::a#2 ] reg byte x [ plus::b#2 ] reg byte a [ plus::return#0 ] reg byte a [ plus::return#1 ] zp[1]:12 [ plus::return#2 ]
Uplifting [] best 93 combination Limited combination testing to 100 combinations of 768 possible.
Uplifting [main] best 149 combination reg byte a [ main::$0 ] reg byte a [ main::$1 ]
Uplifting [] best 149 combination
Attempting to uplift remaining variables inzp[1]:3 [ add::a#0 ]
Uplifting [add] best 149 combination zp[1]:3 [ add::a#0 ]
Attempting to uplift remaining variables inzp[1]:12 [ plus::return#2 ]
Uplifting [plus] best 146 combination reg byte x [ plus::return#2 ]
Allocated (was zp[1]:3) zp[1]:2 [ add::a#0 ]
ASSEMBLER BEFORE OPTIMIZATION ASSEMBLER BEFORE OPTIMIZATION
// File Comments // File Comments
@ -275,94 +361,163 @@ ASSEMBLER BEFORE OPTIMIZATION
// main // main
main: { main: {
// [1] call plus // [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_phi_close_cx16_ram // [10] phi from main to plus [phi:main->plus]
plus_from_main: plus_from_main:
// [10] phi plus::b#2 = 7 [phi:main->plus#0] -- vbuxx=vbuc1
ldx #7
// [10] phi plus::a#2 = '0' [phi:main->plus#1] -- call_phi_close_cx16_ram
lda #'0'
sta.z $ff
lda.z 0 lda.z 0
pha pha
lda #1 lda #1
sta.z 0 sta.z 0
lda.z $ff
jsr plus jsr plus
sta.z $ff
pla pla
sta.z 0 sta.z 0
lda.z $ff
// [2] plus::return#0 = plus::return#2 -- vbuaa=vbuxx
txa
jmp __b1 jmp __b1
// main::@1 // main::@1
__b1: __b1:
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2 // [3] main::$0 = plus::return#0
lda #min.return // [4] *SCREEN = main::$0 -- _deref_pbuc1=vbuaa
sta SCREEN sta SCREEN
// [5] call plus
// [10] phi from main::@1 to plus [phi:main::@1->plus]
plus_from___b1:
// [10] phi plus::b#2 = 6 [phi:main::@1->plus#0] -- vbuxx=vbuc1
ldx #6
// [10] phi plus::a#2 = '1' [phi:main::@1->plus#1] -- call_phi_close_cx16_ram
lda #'1'
sta.z $ff
lda.z 0
pha
lda #1
sta.z 0
lda.z $ff
jsr plus
sta.z $ff
pla
sta.z 0
lda.z $ff
// [6] plus::return#1 = plus::return#2 -- vbuaa=vbuxx
txa
jmp __b2
// main::@2
__b2:
// [7] main::$1 = plus::return#1
// [8] *(SCREEN+1) = main::$1 -- _deref_pbuc1=vbuaa
// close call
sta SCREEN+1
jmp __breturn jmp __breturn
// main::@return // main::@return
__breturn: __breturn:
// [3] return // [9] return
rts rts
} }
.segment RAM_Bank1 .segment RAM_Bank1
// plus // plus
// char plus(char a, char b) // __register(X) char plus(__register(A) char a, __register(X) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
plus: { plus: {
.label a = '0' // [11] add::a#0 = plus::a#2 -- vbuz1=vbuaa
.label b = 7 sta.z add.a
// [5] call min // [12] add::b#0 = plus::b#2 -- vbuaa=vbuxx
// [7] phi from plus to min [phi:plus->min] -- call_phi_far_cx16_ram txa
min_from_plus: // [13] call add -- call_phi_far_cx16_ram
jsr $ff6e jsr $ff6e
.byte <min .byte <add
.byte >min .byte >add
.byte 2 .byte 2
// [14] add::return#0 = add::return#1
jmp __b1
// plus::@1
__b1:
// [15] plus::return#2 = add::return#0 -- vbuxx=vbuaa
tax
jmp __breturn jmp __breturn
// plus::@return // plus::@return
__breturn: __breturn:
// [6] return // [16] return
rts rts
} }
.segment RAM_Bank2 .segment RAM_Bank2
// min // add
// char min(char a, char b) // __register(A) char add(__zp(2) char a, __register(A) char b)
// __bank(cx16_ram, 2) // __bank(cx16_ram, 2)
min: { add: {
.label return = plus.a+plus.b .label a = 2
// [17] add::return#1 = add::a#0 + add::b#0 -- vbuaa=vbuz1_plus_vbuaa
clc
adc.z a
jmp __breturn jmp __breturn
// min::@return // add::@return
__breturn: __breturn:
// [8] return // [18] return
rts rts
} }
// File Data // File Data
ASSEMBLER OPTIMIZATIONS ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1 Removing instruction jmp __b1
Removing instruction jmp __b2
Removing instruction jmp __breturn Removing instruction jmp __breturn
Removing instruction jmp __b1
Removing instruction jmp __breturn Removing instruction jmp __breturn
Removing instruction jmp __breturn Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination Succesful ASM optimization Pass5NextJumpElimination
Removing instruction plus_from_main: Removing instruction plus_from_main:
Removing instruction __b1: Removing instruction __b1:
Removing instruction plus_from___b1:
Removing instruction __b2:
Removing instruction __breturn: Removing instruction __breturn:
Removing instruction min_from_plus: Removing instruction __b1:
Removing instruction __breturn: Removing instruction __breturn:
Removing instruction __breturn: Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE FINAL SYMBOL TABLE
__constant char * const SCREEN = (char *) 1024 __constant char * const SCREEN = (char *) 1024
__bank(cx16_ram, 2) char add(char a , char b)
char add::a
char add::a#0 // a zp[1]:2 56.0
char add::b
char add::b#0 // reg byte a 112.0
char add::return
char add::return#0 // reg byte a 22.0
char add::return#1 // reg byte a 37.33333333333333
void main() void main()
__bank(cx16_ram, 2) char min(char a , char b) char main::$0 // reg byte a 4.0
char min::a char main::$1 // reg byte a 4.0
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::a char plus::a
__constant char plus::a#0 = '0' // a char plus::a#2 // reg byte a 11.0
char plus::b char plus::b
__constant char plus::b#0 = 7 // b char plus::b#2 // reg byte x 5.5
char plus::return char plus::return
char plus::return#0 // reg byte a 4.0
char plus::return#1 // reg byte a 4.0
char plus::return#2 // reg byte x 3.75
reg byte a [ plus::a#2 ]
reg byte x [ plus::b#2 ]
reg byte a [ plus::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ plus::return#1 ]
reg byte a [ main::$1 ]
zp[1]:2 [ add::a#0 ]
reg byte a [ add::b#0 ]
reg byte a [ add::return#0 ]
reg byte x [ plus::return#2 ]
reg byte a [ add::return#1 ]
FINAL ASSEMBLER FINAL ASSEMBLER
Score: 54 Score: 128
// File Comments // File Comments
/** /**
@ -414,51 +569,99 @@ Score: 54
main: { main: {
// plus('0', 7) // plus('0', 7)
// [1] call plus // [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_phi_close_cx16_ram // [10] phi from main to plus [phi:main->plus]
// [10] phi plus::b#2 = 7 [phi:main->plus#0] -- vbuxx=vbuc1
ldx #7
// [10] phi plus::a#2 = '0' [phi:main->plus#1] -- call_phi_close_cx16_ram
lda #'0'
sta.z $ff
lda.z 0 lda.z 0
pha pha
lda #1 lda #1
sta.z 0 sta.z 0
lda.z $ff
jsr plus jsr plus
sta.z $ff
pla pla
sta.z 0 sta.z 0
lda.z $ff
// plus('0', 7)
// [2] plus::return#0 = plus::return#2 -- vbuaa=vbuxx
txa
// main::@1 // main::@1
// [3] main::$0 = plus::return#0
// SCREEN[0] = plus('0', 7) // SCREEN[0] = plus('0', 7)
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2 // [4] *SCREEN = main::$0 -- _deref_pbuc1=vbuaa
lda #min.return
sta SCREEN sta SCREEN
// plus('1', 6)
// [5] call plus
// [10] phi from main::@1 to plus [phi:main::@1->plus]
// [10] phi plus::b#2 = 6 [phi:main::@1->plus#0] -- vbuxx=vbuc1
ldx #6
// [10] phi plus::a#2 = '1' [phi:main::@1->plus#1] -- call_phi_close_cx16_ram
lda #'1'
sta.z $ff
lda.z 0
pha
lda #1
sta.z 0
lda.z $ff
jsr plus
sta.z $ff
pla
sta.z 0
lda.z $ff
// plus('1', 6)
// [6] plus::return#1 = plus::return#2 -- vbuaa=vbuxx
txa
// main::@2
// [7] main::$1 = plus::return#1
// SCREEN[1] = plus('1', 6)
// [8] *(SCREEN+1) = main::$1 -- _deref_pbuc1=vbuaa
// close call
sta SCREEN+1
// main::@return // main::@return
// } // }
// [3] return // [9] return
rts rts
} }
.segment RAM_Bank1 .segment RAM_Bank1
// plus // plus
// char plus(char a, char b) // __register(X) char plus(__register(A) char a, __register(X) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
plus: { plus: {
.label a = '0' // add(a, b)
.label b = 7 // [11] add::a#0 = plus::a#2 -- vbuz1=vbuaa
// min(a, b) sta.z add.a
// [5] call min // [12] add::b#0 = plus::b#2 -- vbuaa=vbuxx
// [7] phi from plus to min [phi:plus->min] -- call_phi_far_cx16_ram txa
// [13] call add -- call_phi_far_cx16_ram
jsr $ff6e jsr $ff6e
.byte <min .byte <add
.byte >min .byte >add
.byte 2 .byte 2
// [14] add::return#0 = add::return#1
// plus::@1
// [15] plus::return#2 = add::return#0 -- vbuxx=vbuaa
tax
// plus::@return // plus::@return
// } // }
// [6] return // [16] return
rts rts
} }
.segment RAM_Bank2 .segment RAM_Bank2
// min // add
// char min(char a, char b) // __register(A) char add(__zp(2) char a, __register(A) char b)
// __bank(cx16_ram, 2) // __bank(cx16_ram, 2)
min: { add: {
.label return = plus.a+plus.b .label a = 2
// min::@return // a+b
// [8] return // [17] add::return#1 = add::a#0 + add::b#0 -- vbuaa=vbuz1_plus_vbuaa
clc
adc.z a
// add::@return
// }
// [18] return
rts rts
} }
// File Data // File Data

View File

@ -1,14 +1,33 @@
__constant char * const SCREEN = (char *) 1024 __constant char * const SCREEN = (char *) 1024
__bank(cx16_ram, 2) char add(char a , char b)
char add::a
char add::a#0 // a zp[1]:2 56.0
char add::b
char add::b#0 // reg byte a 112.0
char add::return
char add::return#0 // reg byte a 22.0
char add::return#1 // reg byte a 37.33333333333333
void main() void main()
__bank(cx16_ram, 2) char min(char a , char b) char main::$0 // reg byte a 4.0
char min::a char main::$1 // reg byte a 4.0
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::a char plus::a
__constant char plus::a#0 = '0' // a char plus::a#2 // reg byte a 11.0
char plus::b char plus::b
__constant char plus::b#0 = 7 // b char plus::b#2 // reg byte x 5.5
char plus::return char plus::return
char plus::return#0 // reg byte a 4.0
char plus::return#1 // reg byte a 4.0
char plus::return#2 // reg byte x 3.75
reg byte a [ plus::a#2 ]
reg byte x [ plus::b#2 ]
reg byte a [ plus::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ plus::return#1 ]
reg byte a [ main::$1 ]
zp[1]:2 [ add::a#0 ]
reg byte a [ add::b#0 ]
reg byte a [ add::return#0 ]
reg byte x [ plus::return#2 ]
reg byte a [ add::return#1 ]

View File

@ -43,37 +43,68 @@
.segment Code .segment Code
main: { main: {
// plus('0', 7) // plus('0', 7)
ldx #7
lda #'0'
sta.z $ff
lda.z 0 lda.z 0
pha pha
lda #1 lda #1
sta.z 0 sta.z 0
lda.z $ff
jsr plus jsr plus
sta.z $ff
pla pla
sta.z 0 sta.z 0
lda.z $ff
// plus('0', 7)
txa
// SCREEN[0] = plus('0', 7) // SCREEN[0] = plus('0', 7)
lda #min.return
sta SCREEN sta SCREEN
// plus('1', 6)
ldx #6
lda #'1'
sta.z $ff
lda.z 0
pha
lda #1
sta.z 0
lda.z $ff
jsr plus
sta.z $ff
pla
sta.z 0
lda.z $ff
// plus('1', 6)
txa
// SCREEN[1] = plus('1', 6)
// close call
sta SCREEN+1
// } // }
rts rts
} }
.segment RAM_Bank1 .segment RAM_Bank1
// char plus(char a, char b) // __register(X) char plus(__register(A) char a, __register(X) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
plus: { plus: {
.label a = '0' // add(a, b)
.label b = 7 sta.z add.a
// min(a, b) txa
jsr $ff6e jsr $ff6e
.byte <min .byte <add
.byte >min .byte >add
.byte 2 .byte 2
tax
// } // }
rts rts
} }
.segment RAM_Bank2 .segment RAM_Bank2
// char min(char a, char b) // __register(A) char add(__zp(2) char a, __register(A) char b)
// __bank(cx16_ram, 2) // __bank(cx16_ram, 2)
min: { add: {
.label return = plus.a+plus.b .label a = 2
// a+b
clc
adc.z a
// }
rts rts
} }

View File

@ -3,27 +3,42 @@ void main()
main: scope:[main] from main: scope:[main] from
[0] phi() [0] phi()
[1] call plus [1] call plus
[2] plus::return#0 = plus::return#2
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
[2] *SCREEN = min::return#1 [3] main::$0 = plus::return#0
[4] *SCREEN = main::$0
[5] call plus
[6] plus::return#1 = plus::return#2
to:main::@2
main::@2: scope:[main] from main::@1
[7] main::$1 = plus::return#1
[8] *(SCREEN+1) = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
[3] return [9] return
to:@return to:@return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
[4] phi() [10] plus::b#2 = phi( main/7, main::@1/6 )
[5] call min [10] plus::a#2 = phi( main/'0', main::@1/'1' )
[11] add::a#0 = plus::a#2
[12] add::b#0 = plus::b#2
[13] call add
[14] add::return#0 = add::return#1
to:plus::@1
plus::@1: scope:[plus] from plus
[15] plus::return#2 = add::return#0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus::@1
[6] return [16] return
to:@return to:@return
__bank(cx16_ram, 2) char min(char a , char b) __bank(cx16_ram, 2) char add(char a , char b)
min: scope:[min] from plus add: scope:[add] from plus
[7] phi() [17] add::return#1 = add::a#0 + add::b#0
to:min::@return to:add::@return
min::@return: scope:[min] from min add::@return: scope:[add] from add
[8] return [18] return
to:@return to:@return

View File

@ -7,47 +7,56 @@ main: scope:[main] from __start
plus::a#0 = '0' plus::a#0 = '0'
plus::b#0 = 7 plus::b#0 = 7
call plus call plus
plus::return#0 = plus::return#2 plus::return#0 = plus::return#3
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
plus::return#3 = phi( main/plus::return#0 ) plus::return#4 = phi( main/plus::return#0 )
main::$0 = plus::return#3 main::$0 = plus::return#4
SCREEN[0] = main::$0 SCREEN[0] = main::$0
plus::a#1 = '1'
plus::b#1 = 6
call plus
plus::return#1 = plus::return#3
to:main::@2
main::@2: scope:[main] from main::@1
plus::return#5 = phi( main::@1/plus::return#1 )
main::$1 = plus::return#5
SCREEN[1] = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
return return
to:@return to:@return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
plus::b#1 = phi( main/plus::b#0 ) plus::b#2 = phi( main/plus::b#0, main::@1/plus::b#1 )
plus::a#1 = phi( main/plus::a#0 ) plus::a#2 = phi( main/plus::a#0, main::@1/plus::a#1 )
min::a#0 = plus::a#1 add::a#0 = plus::a#2
min::b#0 = plus::b#1 add::b#0 = plus::b#2
call min call add
min::return#0 = min::return#2 add::return#0 = add::return#2
to:plus::@1 to:plus::@1
plus::@1: scope:[plus] from plus plus::@1: scope:[plus] from plus
min::return#3 = phi( plus/min::return#0 ) add::return#3 = phi( plus/add::return#0 )
plus::$0 = min::return#3 plus::$0 = add::return#3
plus::return#1 = plus::$0 plus::return#2 = plus::$0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus::@1 plus::@return: scope:[plus] from plus::@1
plus::return#4 = phi( plus::@1/plus::return#1 ) plus::return#6 = phi( plus::@1/plus::return#2 )
plus::return#2 = plus::return#4 plus::return#3 = plus::return#6
return return
to:@return to:@return
__bank(cx16_ram, 2) char min(char a , char b) __bank(cx16_ram, 2) char add(char a , char b)
min: scope:[min] from plus add: scope:[add] from plus
min::b#1 = phi( plus/min::b#0 ) add::b#1 = phi( plus/add::b#0 )
min::a#1 = phi( plus/min::a#0 ) add::a#1 = phi( plus/add::a#0 )
min::$0 = min::a#1 + min::b#1 add::$0 = add::a#1 + add::b#1
min::return#1 = min::$0 add::return#1 = add::$0
to:min::@return to:add::@return
min::@return: scope:[min] from min add::@return: scope:[add] from add
min::return#4 = phi( min/min::return#1 ) add::return#4 = phi( add/add::return#1 )
min::return#2 = min::return#4 add::return#2 = add::return#4
return return
to:@return to:@return
@ -64,64 +73,74 @@ __start::@return: scope:[__start] from __start::@1
SYMBOL TABLE SSA SYMBOL TABLE SSA
__constant char * const SCREEN = (char *)$400 __constant char * const SCREEN = (char *)$400
void __start() void __start()
__bank(cx16_ram, 2) char add(char a , char b)
char add::$0
char add::a
char add::a#0
char add::a#1
char add::b
char add::b#0
char add::b#1
char add::return
char add::return#0
char add::return#1
char add::return#2
char add::return#3
char add::return#4
void main() void main()
char main::$0 char main::$0
__bank(cx16_ram, 2) char min(char a , char b) char main::$1
char min::$0
char min::a
char min::a#0
char min::a#1
char min::b
char min::b#0
char min::b#1
char min::return
char min::return#0
char min::return#1
char min::return#2
char min::return#3
char min::return#4
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::$0 char plus::$0
char plus::a char plus::a
char plus::a#0 char plus::a#0
char plus::a#1 char plus::a#1
char plus::a#2
char plus::b char plus::b
char plus::b#0 char plus::b#0
char plus::b#1 char plus::b#1
char plus::b#2
char plus::return char plus::return
char plus::return#0 char plus::return#0
char plus::return#1 char plus::return#1
char plus::return#2 char plus::return#2
char plus::return#3 char plus::return#3
char plus::return#4 char plus::return#4
char plus::return#5
char plus::return#6
Adding number conversion cast (unumber) 7 in plus::b#0 = 7 Adding number conversion cast (unumber) 7 in plus::b#0 = 7
Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0 Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0
Adding number conversion cast (unumber) 6 in plus::b#1 = 6
Adding number conversion cast (unumber) 1 in SCREEN[1] = main::$1
Successful SSA optimization PassNAddNumberTypeConversions Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast plus::b#0 = (unumber)7 Inlining cast plus::b#0 = (unumber)7
Inlining cast plus::b#1 = (unumber)6
Successful SSA optimization Pass2InlineCast Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (char *) 1024 Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast 7 Simplifying constant integer cast 7
Simplifying constant integer cast 0 Simplifying constant integer cast 0
Simplifying constant integer cast 6
Simplifying constant integer cast 1
Successful SSA optimization PassNCastSimplification Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 7 Finalized unsigned number type (char) 7
Finalized unsigned number type (char) 0 Finalized unsigned number type (char) 0
Finalized unsigned number type (char) 6
Finalized unsigned number type (char) 1
Successful SSA optimization PassNFinalizeNumberTypeConversions Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias plus::return#0 = plus::return#3 Alias plus::return#0 = plus::return#4
Alias min::return#0 = min::return#3 Alias plus::return#1 = plus::return#5
Alias plus::return#1 = plus::$0 plus::return#4 plus::return#2 Alias add::return#0 = add::return#3
Alias min::return#1 = min::$0 min::return#4 min::return#2 Alias plus::return#2 = plus::$0 plus::return#6 plus::return#3
Alias add::return#1 = add::$0 add::return#4 add::return#2
Successful SSA optimization Pass2AliasElimination Successful SSA optimization Pass2AliasElimination
Identical Phi Values plus::a#1 plus::a#0 Identical Phi Values add::a#1 add::a#0
Identical Phi Values plus::b#1 plus::b#0 Identical Phi Values add::b#1 add::b#0
Identical Phi Values min::a#1 min::a#0
Identical Phi Values min::b#1 min::b#0
Successful SSA optimization Pass2IdenticalPhiElimination Successful SSA optimization Pass2IdenticalPhiElimination
Constant plus::a#0 = '0' Constant plus::a#0 = '0'
Constant plus::b#0 = 7 Constant plus::b#0 = 7
Successful SSA optimization Pass2ConstantIdentification Constant plus::a#1 = '1'
Constant min::a#0 = plus::a#0 Constant plus::b#1 = 6
Constant min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantIdentification Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0 Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0
Successful SSA optimization PassNSimplifyExpressionWithZero Successful SSA optimization PassNSimplifyExpressionWithZero
@ -130,40 +149,25 @@ Removing unused procedure block __start
Removing unused procedure block __start::@1 Removing unused procedure block __start::@1
Removing unused procedure block __start::@return Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart Successful SSA optimization PassNEliminateEmptyStart
Constant right-side identified [9] min::return#1 = min::a#0 + min::b#0 Inlining constant with var siblings plus::a#0
Successful SSA optimization Pass2ConstantRValueConsolidation Inlining constant with var siblings plus::b#0
Constant min::return#1 = min::a#0+min::b#0 Inlining constant with var siblings plus::a#1
Successful SSA optimization Pass2ConstantIdentification Inlining constant with var siblings plus::b#1
Constant min::return#0 = min::return#1 Constant inlined plus::b#1 = 6
Successful SSA optimization Pass2ConstantIdentification Constant inlined plus::b#0 = 7
Constant plus::return#1 = min::return#0 Constant inlined plus::a#1 = '1'
Successful SSA optimization Pass2ConstantIdentification Constant inlined plus::a#0 = '0'
Constant plus::return#0 = plus::return#1
Successful SSA optimization Pass2ConstantIdentification
Constant main::$0 = plus::return#0
Successful SSA optimization Pass2ConstantIdentification
Inlining constant with different constant siblings min::return#0
Constant inlined plus::return#0 = min::return#1
Constant inlined main::$0 = min::return#1
Constant inlined plus::return#1 = min::return#1
Constant inlined min::a#0 = plus::a#0
Constant inlined min::return#0 = min::return#1
Constant inlined min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantInlining Successful SSA optimization Pass2ConstantInlining
Consolidated array index constant in *(SCREEN+1)
Successful SSA optimization Pass2ConstantAdditionElimination
Adding NOP phi() at start of main Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of plus::@1
Adding NOP phi() at start of min
CALL GRAPH CALL GRAPH
Calls in [main] to plus:1 Calls in [main] to plus:1 plus:5
Calls in [plus] to min:5 Calls in [plus] to add:13
Created 0 initial phi equivalence classes Created 2 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes Coalesced down to 2 phi equivalence classes
Culled Empty Block label plus::@1
Adding NOP phi() at start of main Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of min
FINAL CONTROL FLOW GRAPH FINAL CONTROL FLOW GRAPH
@ -171,59 +175,141 @@ void main()
main: scope:[main] from main: scope:[main] from
[0] phi() [0] phi()
[1] call plus [1] call plus
[2] plus::return#0 = plus::return#2
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
[2] *SCREEN = min::return#1 [3] main::$0 = plus::return#0
[4] *SCREEN = main::$0
[5] call plus
[6] plus::return#1 = plus::return#2
to:main::@2
main::@2: scope:[main] from main::@1
[7] main::$1 = plus::return#1
[8] *(SCREEN+1) = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
[3] return [9] return
to:@return to:@return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
[4] phi() [10] plus::b#2 = phi( main/7, main::@1/6 )
[5] call min [10] plus::a#2 = phi( main/'0', main::@1/'1' )
[11] add::a#0 = plus::a#2
[12] add::b#0 = plus::b#2
[13] call add
[14] add::return#0 = add::return#1
to:plus::@1
plus::@1: scope:[plus] from plus
[15] plus::return#2 = add::return#0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus::@1
[6] return [16] return
to:@return to:@return
__bank(cx16_ram, 2) char min(char a , char b) __bank(cx16_ram, 2) char add(char a , char b)
min: scope:[min] from plus add: scope:[add] from plus
[7] phi() [17] add::return#1 = add::a#0 + add::b#0
to:min::@return to:add::@return
min::@return: scope:[min] from min add::@return: scope:[add] from add
[8] return [18] return
to:@return to:@return
VARIABLE REGISTER WEIGHTS VARIABLE REGISTER WEIGHTS
__bank(cx16_ram, 2) char add(char a , char b)
char add::a
char add::a#0 // 56.0
char add::b
char add::b#0 // 112.0
char add::return
char add::return#0 // 22.0
char add::return#1 // 37.33333333333333
void main() void main()
__bank(cx16_ram, 2) char min(char a , char b) char main::$0 // 4.0
char min::a char main::$1 // 4.0
char min::b
char min::return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::a char plus::a
char plus::a#2 // 11.0
char plus::b char plus::b
char plus::b#2 // 5.5
char plus::return char plus::return
char plus::return#0 // 4.0
char plus::return#1 // 4.0
char plus::return#2 // 3.75
Initial phi equivalence classes Initial phi equivalence classes
[ plus::a#2 ]
[ plus::b#2 ]
Added variable plus::return#0 to live range equivalence class [ plus::return#0 ]
Added variable main::$0 to live range equivalence class [ main::$0 ]
Added variable plus::return#1 to live range equivalence class [ plus::return#1 ]
Added variable main::$1 to live range equivalence class [ main::$1 ]
Added variable add::a#0 to live range equivalence class [ add::a#0 ]
Added variable add::b#0 to live range equivalence class [ add::b#0 ]
Added variable add::return#0 to live range equivalence class [ add::return#0 ]
Added variable plus::return#2 to live range equivalence class [ plus::return#2 ]
Added variable add::return#1 to live range equivalence class [ add::return#1 ]
Complete equivalence classes Complete equivalence classes
[ plus::a#2 ]
[ plus::b#2 ]
[ plus::return#0 ]
[ main::$0 ]
[ plus::return#1 ]
[ main::$1 ]
[ add::a#0 ]
[ add::b#0 ]
[ add::return#0 ]
[ plus::return#2 ]
[ add::return#1 ]
Allocated zp[1]:2 [ add::b#0 ]
Allocated zp[1]:3 [ add::a#0 ]
Allocated zp[1]:4 [ add::return#1 ]
Allocated zp[1]:5 [ add::return#0 ]
Allocated zp[1]:6 [ plus::a#2 ]
Allocated zp[1]:7 [ plus::b#2 ]
Allocated zp[1]:8 [ plus::return#0 ]
Allocated zp[1]:9 [ main::$0 ]
Allocated zp[1]:10 [ plus::return#1 ]
Allocated zp[1]:11 [ main::$1 ]
Allocated zp[1]:12 [ plus::return#2 ]
REGISTER UPLIFT POTENTIAL REGISTERS REGISTER UPLIFT POTENTIAL REGISTERS
Statement [1] call plus [ ] ( [ ] { } ) always clobbers reg byte a Statement [1] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#0 = plus::return#2 } } ) always clobbers reg byte a
Statement [2] *SCREEN = min::return#1 [ ] ( [ ] { } ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:12 [ plus::return#2 ]
Statement [5] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#1 = plus::return#2 } } ) always clobbers reg byte a
Statement [17] add::return#1 = add::a#0 + add::b#0 [ add::return#1 ] ( plus:1::add:13 [ add::return#1 ] { { plus::return#0 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } plus:5::add:13 [ add::return#1 ] { { plus::return#1 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } ) always clobbers reg byte a
Statement [1] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#0 = plus::return#2 } } ) always clobbers reg byte a
Statement [5] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#1 = plus::return#2 } } ) always clobbers reg byte a
Statement [17] add::return#1 = add::a#0 + add::b#0 [ add::return#1 ] ( plus:1::add:13 [ add::return#1 ] { { plus::return#0 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } plus:5::add:13 [ add::return#1 ] { { plus::return#1 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } ) always clobbers reg byte a
Potential registers zp[1]:6 [ plus::a#2 ] : zp[1]:6 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:7 [ plus::b#2 ] : zp[1]:7 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:8 [ plus::return#0 ] : zp[1]:8 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:9 [ main::$0 ] : zp[1]:9 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:10 [ plus::return#1 ] : zp[1]:10 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:11 [ main::$1 ] : zp[1]:11 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:3 [ add::a#0 ] : zp[1]:3 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:2 [ add::b#0 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:5 [ add::return#0 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:12 [ plus::return#2 ] : zp[1]:12 , reg byte x , reg byte y ,
Potential registers zp[1]:4 [ add::return#1 ] : zp[1]:4 , reg byte a , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES REGISTER UPLIFT SCOPES
Uplift Scope [main] Uplift Scope [add] 112: zp[1]:2 [ add::b#0 ] 56: zp[1]:3 [ add::a#0 ] 37.33: zp[1]:4 [ add::return#1 ] 22: zp[1]:5 [ add::return#0 ]
Uplift Scope [plus] Uplift Scope [plus] 11: zp[1]:6 [ plus::a#2 ] 5.5: zp[1]:7 [ plus::b#2 ] 4: zp[1]:8 [ plus::return#0 ] 4: zp[1]:10 [ plus::return#1 ] 3.75: zp[1]:12 [ plus::return#2 ]
Uplift Scope [min] Uplift Scope [main] 4: zp[1]:9 [ main::$0 ] 4: zp[1]:11 [ main::$1 ]
Uplift Scope [] Uplift Scope []
Uplifting [main] best 93 combination Uplifting [add] best 189 combination reg byte a [ add::b#0 ] zp[1]:3 [ add::a#0 ] reg byte a [ add::return#1 ] reg byte a [ add::return#0 ]
Uplifting [plus] best 93 combination Limited combination testing to 100 combinations of 256 possible.
Uplifting [min] best 93 combination Uplifting [plus] best 161 combination reg byte a [ plus::a#2 ] reg byte x [ plus::b#2 ] reg byte a [ plus::return#0 ] reg byte a [ plus::return#1 ] zp[1]:12 [ plus::return#2 ]
Uplifting [] best 93 combination Limited combination testing to 100 combinations of 768 possible.
Uplifting [main] best 149 combination reg byte a [ main::$0 ] reg byte a [ main::$1 ]
Uplifting [] best 149 combination
Attempting to uplift remaining variables inzp[1]:3 [ add::a#0 ]
Uplifting [add] best 149 combination zp[1]:3 [ add::a#0 ]
Attempting to uplift remaining variables inzp[1]:12 [ plus::return#2 ]
Uplifting [plus] best 146 combination reg byte x [ plus::return#2 ]
Allocated (was zp[1]:3) zp[1]:2 [ add::a#0 ]
ASSEMBLER BEFORE OPTIMIZATION ASSEMBLER BEFORE OPTIMIZATION
// File Comments // File Comments
@ -275,94 +361,163 @@ ASSEMBLER BEFORE OPTIMIZATION
// main // main
main: { main: {
// [1] call plus // [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_phi_close_cx16_ram // [10] phi from main to plus [phi:main->plus]
plus_from_main: plus_from_main:
// [10] phi plus::b#2 = 7 [phi:main->plus#0] -- vbuxx=vbuc1
ldx #7
// [10] phi plus::a#2 = '0' [phi:main->plus#1] -- call_phi_close_cx16_ram
lda #'0'
sta.z $ff
lda.z 0 lda.z 0
pha pha
lda #1 lda #1
sta.z 0 sta.z 0
lda.z $ff
jsr plus jsr plus
sta.z $ff
pla pla
sta.z 0 sta.z 0
lda.z $ff
// [2] plus::return#0 = plus::return#2 -- vbuaa=vbuxx
txa
jmp __b1 jmp __b1
// main::@1 // main::@1
__b1: __b1:
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2 // [3] main::$0 = plus::return#0
lda #min.return // [4] *SCREEN = main::$0 -- _deref_pbuc1=vbuaa
sta SCREEN sta SCREEN
// [5] call plus
// [10] phi from main::@1 to plus [phi:main::@1->plus]
plus_from___b1:
// [10] phi plus::b#2 = 6 [phi:main::@1->plus#0] -- vbuxx=vbuc1
ldx #6
// [10] phi plus::a#2 = '1' [phi:main::@1->plus#1] -- call_phi_close_cx16_ram
lda #'1'
sta.z $ff
lda.z 0
pha
lda #1
sta.z 0
lda.z $ff
jsr plus
sta.z $ff
pla
sta.z 0
lda.z $ff
// [6] plus::return#1 = plus::return#2 -- vbuaa=vbuxx
txa
jmp __b2
// main::@2
__b2:
// [7] main::$1 = plus::return#1
// [8] *(SCREEN+1) = main::$1 -- _deref_pbuc1=vbuaa
// close call
sta SCREEN+1
jmp __breturn jmp __breturn
// main::@return // main::@return
__breturn: __breturn:
// [3] return // [9] return
rts rts
} }
.segment RAM_Bank1 .segment RAM_Bank1
// plus // plus
// char plus(char a, char b) // __register(X) char plus(__register(A) char a, __register(X) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
plus: { plus: {
.label a = '0' // [11] add::a#0 = plus::a#2 -- vbuz1=vbuaa
.label b = 7 sta.z add.a
// [5] call min // [12] add::b#0 = plus::b#2 -- vbuaa=vbuxx
// [7] phi from plus to min [phi:plus->min] -- call_phi_far_cx16_ram txa
min_from_plus: // [13] call add -- call_phi_far_cx16_ram
jsr $ff6e jsr $ff6e
.byte <min .byte <add
.byte >min .byte >add
.byte 2 .byte 2
// [14] add::return#0 = add::return#1
jmp __b1
// plus::@1
__b1:
// [15] plus::return#2 = add::return#0 -- vbuxx=vbuaa
tax
jmp __breturn jmp __breturn
// plus::@return // plus::@return
__breturn: __breturn:
// [6] return // [16] return
rts rts
} }
.segment RAM_Bank2 .segment RAM_Bank2
// min // add
// char min(char a, char b) // __register(A) char add(__zp(2) char a, __register(A) char b)
// __bank(cx16_ram, 2) // __bank(cx16_ram, 2)
min: { add: {
.label return = plus.a+plus.b .label a = 2
// [17] add::return#1 = add::a#0 + add::b#0 -- vbuaa=vbuz1_plus_vbuaa
clc
adc.z a
jmp __breturn jmp __breturn
// min::@return // add::@return
__breturn: __breturn:
// [8] return // [18] return
rts rts
} }
// File Data // File Data
ASSEMBLER OPTIMIZATIONS ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1 Removing instruction jmp __b1
Removing instruction jmp __b2
Removing instruction jmp __breturn Removing instruction jmp __breturn
Removing instruction jmp __b1
Removing instruction jmp __breturn Removing instruction jmp __breturn
Removing instruction jmp __breturn Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination Succesful ASM optimization Pass5NextJumpElimination
Removing instruction plus_from_main: Removing instruction plus_from_main:
Removing instruction __b1: Removing instruction __b1:
Removing instruction plus_from___b1:
Removing instruction __b2:
Removing instruction __breturn: Removing instruction __breturn:
Removing instruction min_from_plus: Removing instruction __b1:
Removing instruction __breturn: Removing instruction __breturn:
Removing instruction __breturn: Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE FINAL SYMBOL TABLE
__constant char * const SCREEN = (char *) 1024 __constant char * const SCREEN = (char *) 1024
__bank(cx16_ram, 2) char add(char a , char b)
char add::a
char add::a#0 // a zp[1]:2 56.0
char add::b
char add::b#0 // reg byte a 112.0
char add::return
char add::return#0 // reg byte a 22.0
char add::return#1 // reg byte a 37.33333333333333
void main() void main()
__bank(cx16_ram, 2) char min(char a , char b) char main::$0 // reg byte a 4.0
char min::a char main::$1 // reg byte a 4.0
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::a char plus::a
__constant char plus::a#0 = '0' // a char plus::a#2 // reg byte a 11.0
char plus::b char plus::b
__constant char plus::b#0 = 7 // b char plus::b#2 // reg byte x 5.5
char plus::return char plus::return
char plus::return#0 // reg byte a 4.0
char plus::return#1 // reg byte a 4.0
char plus::return#2 // reg byte x 3.75
reg byte a [ plus::a#2 ]
reg byte x [ plus::b#2 ]
reg byte a [ plus::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ plus::return#1 ]
reg byte a [ main::$1 ]
zp[1]:2 [ add::a#0 ]
reg byte a [ add::b#0 ]
reg byte a [ add::return#0 ]
reg byte x [ plus::return#2 ]
reg byte a [ add::return#1 ]
FINAL ASSEMBLER FINAL ASSEMBLER
Score: 54 Score: 128
// File Comments // File Comments
/** /**
@ -414,51 +569,99 @@ Score: 54
main: { main: {
// plus('0', 7) // plus('0', 7)
// [1] call plus // [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_phi_close_cx16_ram // [10] phi from main to plus [phi:main->plus]
// [10] phi plus::b#2 = 7 [phi:main->plus#0] -- vbuxx=vbuc1
ldx #7
// [10] phi plus::a#2 = '0' [phi:main->plus#1] -- call_phi_close_cx16_ram
lda #'0'
sta.z $ff
lda.z 0 lda.z 0
pha pha
lda #1 lda #1
sta.z 0 sta.z 0
lda.z $ff
jsr plus jsr plus
sta.z $ff
pla pla
sta.z 0 sta.z 0
lda.z $ff
// plus('0', 7)
// [2] plus::return#0 = plus::return#2 -- vbuaa=vbuxx
txa
// main::@1 // main::@1
// [3] main::$0 = plus::return#0
// SCREEN[0] = plus('0', 7) // SCREEN[0] = plus('0', 7)
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2 // [4] *SCREEN = main::$0 -- _deref_pbuc1=vbuaa
lda #min.return
sta SCREEN sta SCREEN
// plus('1', 6)
// [5] call plus
// [10] phi from main::@1 to plus [phi:main::@1->plus]
// [10] phi plus::b#2 = 6 [phi:main::@1->plus#0] -- vbuxx=vbuc1
ldx #6
// [10] phi plus::a#2 = '1' [phi:main::@1->plus#1] -- call_phi_close_cx16_ram
lda #'1'
sta.z $ff
lda.z 0
pha
lda #1
sta.z 0
lda.z $ff
jsr plus
sta.z $ff
pla
sta.z 0
lda.z $ff
// plus('1', 6)
// [6] plus::return#1 = plus::return#2 -- vbuaa=vbuxx
txa
// main::@2
// [7] main::$1 = plus::return#1
// SCREEN[1] = plus('1', 6)
// [8] *(SCREEN+1) = main::$1 -- _deref_pbuc1=vbuaa
// close call
sta SCREEN+1
// main::@return // main::@return
// } // }
// [3] return // [9] return
rts rts
} }
.segment RAM_Bank1 .segment RAM_Bank1
// plus // plus
// char plus(char a, char b) // __register(X) char plus(__register(A) char a, __register(X) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
plus: { plus: {
.label a = '0' // add(a, b)
.label b = 7 // [11] add::a#0 = plus::a#2 -- vbuz1=vbuaa
// min(a, b) sta.z add.a
// [5] call min // [12] add::b#0 = plus::b#2 -- vbuaa=vbuxx
// [7] phi from plus to min [phi:plus->min] -- call_phi_far_cx16_ram txa
// [13] call add -- call_phi_far_cx16_ram
jsr $ff6e jsr $ff6e
.byte <min .byte <add
.byte >min .byte >add
.byte 2 .byte 2
// [14] add::return#0 = add::return#1
// plus::@1
// [15] plus::return#2 = add::return#0 -- vbuxx=vbuaa
tax
// plus::@return // plus::@return
// } // }
// [6] return // [16] return
rts rts
} }
.segment RAM_Bank2 .segment RAM_Bank2
// min // add
// char min(char a, char b) // __register(A) char add(__zp(2) char a, __register(A) char b)
// __bank(cx16_ram, 2) // __bank(cx16_ram, 2)
min: { add: {
.label return = plus.a+plus.b .label a = 2
// min::@return // a+b
// [8] return // [17] add::return#1 = add::a#0 + add::b#0 -- vbuaa=vbuz1_plus_vbuaa
clc
adc.z a
// add::@return
// }
// [18] return
rts rts
} }
// File Data // File Data

View File

@ -1,14 +1,33 @@
__constant char * const SCREEN = (char *) 1024 __constant char * const SCREEN = (char *) 1024
__bank(cx16_ram, 2) char add(char a , char b)
char add::a
char add::a#0 // a zp[1]:2 56.0
char add::b
char add::b#0 // reg byte a 112.0
char add::return
char add::return#0 // reg byte a 22.0
char add::return#1 // reg byte a 37.33333333333333
void main() void main()
__bank(cx16_ram, 2) char min(char a , char b) char main::$0 // reg byte a 4.0
char min::a char main::$1 // reg byte a 4.0
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::a char plus::a
__constant char plus::a#0 = '0' // a char plus::a#2 // reg byte a 11.0
char plus::b char plus::b
__constant char plus::b#0 = 7 // b char plus::b#2 // reg byte x 5.5
char plus::return char plus::return
char plus::return#0 // reg byte a 4.0
char plus::return#1 // reg byte a 4.0
char plus::return#2 // reg byte x 3.75
reg byte a [ plus::a#2 ]
reg byte x [ plus::b#2 ]
reg byte a [ plus::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ plus::return#1 ]
reg byte a [ main::$1 ]
zp[1]:2 [ add::a#0 ]
reg byte a [ add::b#0 ]
reg byte a [ add::return#0 ]
reg byte x [ plus::return#2 ]
reg byte a [ add::return#1 ]

View File

@ -43,40 +43,77 @@
.segment Code .segment Code
main: { main: {
// plus('0', 7) // plus('0', 7)
ldx #7
lda #'0'
sta.z $ff
lda.z 0 lda.z 0
pha pha
lda #1 lda #1
sta.z 0 sta.z 0
lda.z $ff
jsr plus jsr plus
sta.z $ff
pla pla
sta.z 0 sta.z 0
lda.z $ff
// plus('0', 7)
txa
// SCREEN[0] = plus('0', 7) // SCREEN[0] = plus('0', 7)
lda #min.return
sta SCREEN sta SCREEN
// plus('1', 6)
ldx #6
lda #'1'
sta.z $ff
lda.z 0
pha
lda #1
sta.z 0
lda.z $ff
jsr plus
sta.z $ff
pla
sta.z 0
lda.z $ff
// plus('1', 6)
txa
// SCREEN[1] = plus('1', 6)
// close call
sta SCREEN+1
// } // }
rts rts
} }
.segment RAM_Bank1 .segment RAM_Bank1
// char plus(char a, char b) // __register(X) char plus(__register(A) char a, __register(X) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
plus: { plus: {
.label a = '0' // add(a, b)
.label b = 7 sta.z add.a
// min(a, b) txa
sta.z $ff
lda.z 1 lda.z 1
pha pha
lda #1 lda #1
sta.z 1 sta.z 1
jsr min lda.z $ff
jsr add
sta.z $ff
pla pla
sta.z 1 sta.z 1
lda.z $ff
txa
tax
// } // }
rts rts
} }
.segment ROM_Bank1 .segment ROM_Bank1
// char min(char a, char b) // __register(X) char add(__zp(2) char a, __register(A) char b)
// __bank(cx16_rom, 1) // __bank(cx16_rom, 1)
min: { add: {
.label return = plus.a+plus.b .label a = 2
// a+b
clc
adc.z a
tax
// }
rts rts
} }

View File

@ -3,27 +3,42 @@ void main()
main: scope:[main] from main: scope:[main] from
[0] phi() [0] phi()
[1] call plus [1] call plus
[2] plus::return#0 = plus::return#2
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
[2] *SCREEN = min::return#1 [3] main::$0 = plus::return#0
[4] *SCREEN = main::$0
[5] call plus
[6] plus::return#1 = plus::return#2
to:main::@2
main::@2: scope:[main] from main::@1
[7] main::$1 = plus::return#1
[8] *(SCREEN+1) = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
[3] return [9] return
to:@return to:@return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
[4] phi() [10] plus::b#2 = phi( main/7, main::@1/6 )
[5] call min [10] plus::a#2 = phi( main/'0', main::@1/'1' )
[11] add::a#0 = plus::a#2
[12] add::b#0 = plus::b#2
[13] call add
[14] add::return#0 = add::return#1
to:plus::@1
plus::@1: scope:[plus] from plus
[15] plus::return#2 = add::return#0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus::@1
[6] return [16] return
to:@return to:@return
__bank(cx16_rom, 1) char min(char a , char b) __bank(cx16_rom, 1) char add(char a , char b)
min: scope:[min] from plus add: scope:[add] from plus
[7] phi() [17] add::return#1 = add::a#0 + add::b#0
to:min::@return to:add::@return
min::@return: scope:[min] from min add::@return: scope:[add] from add
[8] return [18] return
to:@return to:@return

View File

@ -7,47 +7,56 @@ main: scope:[main] from __start
plus::a#0 = '0' plus::a#0 = '0'
plus::b#0 = 7 plus::b#0 = 7
call plus call plus
plus::return#0 = plus::return#2 plus::return#0 = plus::return#3
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
plus::return#3 = phi( main/plus::return#0 ) plus::return#4 = phi( main/plus::return#0 )
main::$0 = plus::return#3 main::$0 = plus::return#4
SCREEN[0] = main::$0 SCREEN[0] = main::$0
plus::a#1 = '1'
plus::b#1 = 6
call plus
plus::return#1 = plus::return#3
to:main::@2
main::@2: scope:[main] from main::@1
plus::return#5 = phi( main::@1/plus::return#1 )
main::$1 = plus::return#5
SCREEN[1] = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
return return
to:@return to:@return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
plus::b#1 = phi( main/plus::b#0 ) plus::b#2 = phi( main/plus::b#0, main::@1/plus::b#1 )
plus::a#1 = phi( main/plus::a#0 ) plus::a#2 = phi( main/plus::a#0, main::@1/plus::a#1 )
min::a#0 = plus::a#1 add::a#0 = plus::a#2
min::b#0 = plus::b#1 add::b#0 = plus::b#2
call min call add
min::return#0 = min::return#2 add::return#0 = add::return#2
to:plus::@1 to:plus::@1
plus::@1: scope:[plus] from plus plus::@1: scope:[plus] from plus
min::return#3 = phi( plus/min::return#0 ) add::return#3 = phi( plus/add::return#0 )
plus::$0 = min::return#3 plus::$0 = add::return#3
plus::return#1 = plus::$0 plus::return#2 = plus::$0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus::@1 plus::@return: scope:[plus] from plus::@1
plus::return#4 = phi( plus::@1/plus::return#1 ) plus::return#6 = phi( plus::@1/plus::return#2 )
plus::return#2 = plus::return#4 plus::return#3 = plus::return#6
return return
to:@return to:@return
__bank(cx16_rom, 1) char min(char a , char b) __bank(cx16_rom, 1) char add(char a , char b)
min: scope:[min] from plus add: scope:[add] from plus
min::b#1 = phi( plus/min::b#0 ) add::b#1 = phi( plus/add::b#0 )
min::a#1 = phi( plus/min::a#0 ) add::a#1 = phi( plus/add::a#0 )
min::$0 = min::a#1 + min::b#1 add::$0 = add::a#1 + add::b#1
min::return#1 = min::$0 add::return#1 = add::$0
to:min::@return to:add::@return
min::@return: scope:[min] from min add::@return: scope:[add] from add
min::return#4 = phi( min/min::return#1 ) add::return#4 = phi( add/add::return#1 )
min::return#2 = min::return#4 add::return#2 = add::return#4
return return
to:@return to:@return
@ -64,64 +73,74 @@ __start::@return: scope:[__start] from __start::@1
SYMBOL TABLE SSA SYMBOL TABLE SSA
__constant char * const SCREEN = (char *)$400 __constant char * const SCREEN = (char *)$400
void __start() void __start()
__bank(cx16_rom, 1) char add(char a , char b)
char add::$0
char add::a
char add::a#0
char add::a#1
char add::b
char add::b#0
char add::b#1
char add::return
char add::return#0
char add::return#1
char add::return#2
char add::return#3
char add::return#4
void main() void main()
char main::$0 char main::$0
__bank(cx16_rom, 1) char min(char a , char b) char main::$1
char min::$0
char min::a
char min::a#0
char min::a#1
char min::b
char min::b#0
char min::b#1
char min::return
char min::return#0
char min::return#1
char min::return#2
char min::return#3
char min::return#4
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::$0 char plus::$0
char plus::a char plus::a
char plus::a#0 char plus::a#0
char plus::a#1 char plus::a#1
char plus::a#2
char plus::b char plus::b
char plus::b#0 char plus::b#0
char plus::b#1 char plus::b#1
char plus::b#2
char plus::return char plus::return
char plus::return#0 char plus::return#0
char plus::return#1 char plus::return#1
char plus::return#2 char plus::return#2
char plus::return#3 char plus::return#3
char plus::return#4 char plus::return#4
char plus::return#5
char plus::return#6
Adding number conversion cast (unumber) 7 in plus::b#0 = 7 Adding number conversion cast (unumber) 7 in plus::b#0 = 7
Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0 Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0
Adding number conversion cast (unumber) 6 in plus::b#1 = 6
Adding number conversion cast (unumber) 1 in SCREEN[1] = main::$1
Successful SSA optimization PassNAddNumberTypeConversions Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast plus::b#0 = (unumber)7 Inlining cast plus::b#0 = (unumber)7
Inlining cast plus::b#1 = (unumber)6
Successful SSA optimization Pass2InlineCast Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (char *) 1024 Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast 7 Simplifying constant integer cast 7
Simplifying constant integer cast 0 Simplifying constant integer cast 0
Simplifying constant integer cast 6
Simplifying constant integer cast 1
Successful SSA optimization PassNCastSimplification Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 7 Finalized unsigned number type (char) 7
Finalized unsigned number type (char) 0 Finalized unsigned number type (char) 0
Finalized unsigned number type (char) 6
Finalized unsigned number type (char) 1
Successful SSA optimization PassNFinalizeNumberTypeConversions Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias plus::return#0 = plus::return#3 Alias plus::return#0 = plus::return#4
Alias min::return#0 = min::return#3 Alias plus::return#1 = plus::return#5
Alias plus::return#1 = plus::$0 plus::return#4 plus::return#2 Alias add::return#0 = add::return#3
Alias min::return#1 = min::$0 min::return#4 min::return#2 Alias plus::return#2 = plus::$0 plus::return#6 plus::return#3
Alias add::return#1 = add::$0 add::return#4 add::return#2
Successful SSA optimization Pass2AliasElimination Successful SSA optimization Pass2AliasElimination
Identical Phi Values plus::a#1 plus::a#0 Identical Phi Values add::a#1 add::a#0
Identical Phi Values plus::b#1 plus::b#0 Identical Phi Values add::b#1 add::b#0
Identical Phi Values min::a#1 min::a#0
Identical Phi Values min::b#1 min::b#0
Successful SSA optimization Pass2IdenticalPhiElimination Successful SSA optimization Pass2IdenticalPhiElimination
Constant plus::a#0 = '0' Constant plus::a#0 = '0'
Constant plus::b#0 = 7 Constant plus::b#0 = 7
Successful SSA optimization Pass2ConstantIdentification Constant plus::a#1 = '1'
Constant min::a#0 = plus::a#0 Constant plus::b#1 = 6
Constant min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantIdentification Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0 Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0
Successful SSA optimization PassNSimplifyExpressionWithZero Successful SSA optimization PassNSimplifyExpressionWithZero
@ -130,40 +149,25 @@ Removing unused procedure block __start
Removing unused procedure block __start::@1 Removing unused procedure block __start::@1
Removing unused procedure block __start::@return Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart Successful SSA optimization PassNEliminateEmptyStart
Constant right-side identified [9] min::return#1 = min::a#0 + min::b#0 Inlining constant with var siblings plus::a#0
Successful SSA optimization Pass2ConstantRValueConsolidation Inlining constant with var siblings plus::b#0
Constant min::return#1 = min::a#0+min::b#0 Inlining constant with var siblings plus::a#1
Successful SSA optimization Pass2ConstantIdentification Inlining constant with var siblings plus::b#1
Constant min::return#0 = min::return#1 Constant inlined plus::b#1 = 6
Successful SSA optimization Pass2ConstantIdentification Constant inlined plus::b#0 = 7
Constant plus::return#1 = min::return#0 Constant inlined plus::a#1 = '1'
Successful SSA optimization Pass2ConstantIdentification Constant inlined plus::a#0 = '0'
Constant plus::return#0 = plus::return#1
Successful SSA optimization Pass2ConstantIdentification
Constant main::$0 = plus::return#0
Successful SSA optimization Pass2ConstantIdentification
Inlining constant with different constant siblings min::return#0
Constant inlined plus::return#0 = min::return#1
Constant inlined main::$0 = min::return#1
Constant inlined plus::return#1 = min::return#1
Constant inlined min::a#0 = plus::a#0
Constant inlined min::return#0 = min::return#1
Constant inlined min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantInlining Successful SSA optimization Pass2ConstantInlining
Consolidated array index constant in *(SCREEN+1)
Successful SSA optimization Pass2ConstantAdditionElimination
Adding NOP phi() at start of main Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of plus::@1
Adding NOP phi() at start of min
CALL GRAPH CALL GRAPH
Calls in [main] to plus:1 Calls in [main] to plus:1 plus:5
Calls in [plus] to min:5 Calls in [plus] to add:13
Created 0 initial phi equivalence classes Created 2 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes Coalesced down to 2 phi equivalence classes
Culled Empty Block label plus::@1
Adding NOP phi() at start of main Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of min
FINAL CONTROL FLOW GRAPH FINAL CONTROL FLOW GRAPH
@ -171,60 +175,144 @@ void main()
main: scope:[main] from main: scope:[main] from
[0] phi() [0] phi()
[1] call plus [1] call plus
[2] plus::return#0 = plus::return#2
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
[2] *SCREEN = min::return#1 [3] main::$0 = plus::return#0
[4] *SCREEN = main::$0
[5] call plus
[6] plus::return#1 = plus::return#2
to:main::@2
main::@2: scope:[main] from main::@1
[7] main::$1 = plus::return#1
[8] *(SCREEN+1) = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
[3] return [9] return
to:@return to:@return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
[4] phi() [10] plus::b#2 = phi( main/7, main::@1/6 )
[5] call min [10] plus::a#2 = phi( main/'0', main::@1/'1' )
[11] add::a#0 = plus::a#2
[12] add::b#0 = plus::b#2
[13] call add
[14] add::return#0 = add::return#1
to:plus::@1
plus::@1: scope:[plus] from plus
[15] plus::return#2 = add::return#0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus::@1
[6] return [16] return
to:@return to:@return
__bank(cx16_rom, 1) char min(char a , char b) __bank(cx16_rom, 1) char add(char a , char b)
min: scope:[min] from plus add: scope:[add] from plus
[7] phi() [17] add::return#1 = add::a#0 + add::b#0
to:min::@return to:add::@return
min::@return: scope:[min] from min add::@return: scope:[add] from add
[8] return [18] return
to:@return to:@return
VARIABLE REGISTER WEIGHTS VARIABLE REGISTER WEIGHTS
__bank(cx16_rom, 1) char add(char a , char b)
char add::a
char add::a#0 // 56.0
char add::b
char add::b#0 // 112.0
char add::return
char add::return#0 // 22.0
char add::return#1 // 37.33333333333333
void main() void main()
__bank(cx16_rom, 1) char min(char a , char b) char main::$0 // 4.0
char min::a char main::$1 // 4.0
char min::b
char min::return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::a char plus::a
char plus::a#2 // 11.0
char plus::b char plus::b
char plus::b#2 // 5.5
char plus::return char plus::return
char plus::return#0 // 4.0
char plus::return#1 // 4.0
char plus::return#2 // 3.75
Initial phi equivalence classes Initial phi equivalence classes
[ plus::a#2 ]
[ plus::b#2 ]
Added variable plus::return#0 to live range equivalence class [ plus::return#0 ]
Added variable main::$0 to live range equivalence class [ main::$0 ]
Added variable plus::return#1 to live range equivalence class [ plus::return#1 ]
Added variable main::$1 to live range equivalence class [ main::$1 ]
Added variable add::a#0 to live range equivalence class [ add::a#0 ]
Added variable add::b#0 to live range equivalence class [ add::b#0 ]
Added variable add::return#0 to live range equivalence class [ add::return#0 ]
Added variable plus::return#2 to live range equivalence class [ plus::return#2 ]
Added variable add::return#1 to live range equivalence class [ add::return#1 ]
Complete equivalence classes Complete equivalence classes
[ plus::a#2 ]
[ plus::b#2 ]
[ plus::return#0 ]
[ main::$0 ]
[ plus::return#1 ]
[ main::$1 ]
[ add::a#0 ]
[ add::b#0 ]
[ add::return#0 ]
[ plus::return#2 ]
[ add::return#1 ]
Allocated zp[1]:2 [ add::b#0 ]
Allocated zp[1]:3 [ add::a#0 ]
Allocated zp[1]:4 [ add::return#1 ]
Allocated zp[1]:5 [ add::return#0 ]
Allocated zp[1]:6 [ plus::a#2 ]
Allocated zp[1]:7 [ plus::b#2 ]
Allocated zp[1]:8 [ plus::return#0 ]
Allocated zp[1]:9 [ main::$0 ]
Allocated zp[1]:10 [ plus::return#1 ]
Allocated zp[1]:11 [ main::$1 ]
Allocated zp[1]:12 [ plus::return#2 ]
REGISTER UPLIFT POTENTIAL REGISTERS REGISTER UPLIFT POTENTIAL REGISTERS
Statement [1] call plus [ ] ( [ ] { } ) always clobbers reg byte a Statement [1] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#0 = plus::return#2 } } ) always clobbers reg byte a
Statement [2] *SCREEN = min::return#1 [ ] ( [ ] { } ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:12 [ plus::return#2 ]
Statement [5] call min [ ] ( plus:1 [ ] { } ) always clobbers reg byte a Statement [5] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#1 = plus::return#2 } } ) always clobbers reg byte a
Statement [13] call add [ add::return#1 ] ( plus:1 [ add::return#1 ] { { plus::return#0 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } plus:5 [ add::return#1 ] { { plus::return#1 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp[1]:4 [ add::return#1 ]
Statement [17] add::return#1 = add::a#0 + add::b#0 [ add::return#1 ] ( plus:1::add:13 [ add::return#1 ] { { plus::return#0 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } plus:5::add:13 [ add::return#1 ] { { plus::return#1 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } ) always clobbers reg byte a
Statement [1] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#0 = plus::return#2 } } ) always clobbers reg byte a
Statement [5] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#1 = plus::return#2 } } ) always clobbers reg byte a
Statement [13] call add [ add::return#1 ] ( plus:1 [ add::return#1 ] { { plus::return#0 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } plus:5 [ add::return#1 ] { { plus::return#1 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } ) always clobbers reg byte a
Statement [17] add::return#1 = add::a#0 + add::b#0 [ add::return#1 ] ( plus:1::add:13 [ add::return#1 ] { { plus::return#0 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } plus:5::add:13 [ add::return#1 ] { { plus::return#1 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } ) always clobbers reg byte a
Potential registers zp[1]:6 [ plus::a#2 ] : zp[1]:6 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:7 [ plus::b#2 ] : zp[1]:7 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:8 [ plus::return#0 ] : zp[1]:8 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:9 [ main::$0 ] : zp[1]:9 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:10 [ plus::return#1 ] : zp[1]:10 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:11 [ main::$1 ] : zp[1]:11 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:3 [ add::a#0 ] : zp[1]:3 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:2 [ add::b#0 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:5 [ add::return#0 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:12 [ plus::return#2 ] : zp[1]:12 , reg byte x , reg byte y ,
Potential registers zp[1]:4 [ add::return#1 ] : zp[1]:4 , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES REGISTER UPLIFT SCOPES
Uplift Scope [main] Uplift Scope [add] 112: zp[1]:2 [ add::b#0 ] 56: zp[1]:3 [ add::a#0 ] 37.33: zp[1]:4 [ add::return#1 ] 22: zp[1]:5 [ add::return#0 ]
Uplift Scope [plus] Uplift Scope [plus] 11: zp[1]:6 [ plus::a#2 ] 5.5: zp[1]:7 [ plus::b#2 ] 4: zp[1]:8 [ plus::return#0 ] 4: zp[1]:10 [ plus::return#1 ] 3.75: zp[1]:12 [ plus::return#2 ]
Uplift Scope [min] Uplift Scope [main] 4: zp[1]:9 [ main::$0 ] 4: zp[1]:11 [ main::$1 ]
Uplift Scope [] Uplift Scope []
Uplifting [main] best 111 combination Uplifting [add] best 223 combination reg byte a [ add::b#0 ] zp[1]:3 [ add::a#0 ] reg byte x [ add::return#1 ] reg byte a [ add::return#0 ]
Uplifting [plus] best 111 combination Limited combination testing to 100 combinations of 192 possible.
Uplifting [min] best 111 combination Uplifting [plus] best 195 combination reg byte a [ plus::a#2 ] reg byte x [ plus::b#2 ] reg byte a [ plus::return#0 ] reg byte a [ plus::return#1 ] zp[1]:12 [ plus::return#2 ]
Uplifting [] best 111 combination Limited combination testing to 100 combinations of 768 possible.
Uplifting [main] best 183 combination reg byte a [ main::$0 ] reg byte a [ main::$1 ]
Uplifting [] best 183 combination
Attempting to uplift remaining variables inzp[1]:3 [ add::a#0 ]
Uplifting [add] best 183 combination zp[1]:3 [ add::a#0 ]
Attempting to uplift remaining variables inzp[1]:12 [ plus::return#2 ]
Uplifting [plus] best 180 combination reg byte x [ plus::return#2 ]
Allocated (was zp[1]:3) zp[1]:2 [ add::a#0 ]
ASSEMBLER BEFORE OPTIMIZATION ASSEMBLER BEFORE OPTIMIZATION
// File Comments // File Comments
@ -276,97 +364,172 @@ ASSEMBLER BEFORE OPTIMIZATION
// main // main
main: { main: {
// [1] call plus // [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_phi_close_cx16_ram // [10] phi from main to plus [phi:main->plus]
plus_from_main: plus_from_main:
// [10] phi plus::b#2 = 7 [phi:main->plus#0] -- vbuxx=vbuc1
ldx #7
// [10] phi plus::a#2 = '0' [phi:main->plus#1] -- call_phi_close_cx16_ram
lda #'0'
sta.z $ff
lda.z 0 lda.z 0
pha pha
lda #1 lda #1
sta.z 0 sta.z 0
lda.z $ff
jsr plus jsr plus
sta.z $ff
pla pla
sta.z 0 sta.z 0
lda.z $ff
// [2] plus::return#0 = plus::return#2 -- vbuaa=vbuxx
txa
jmp __b1 jmp __b1
// main::@1 // main::@1
__b1: __b1:
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2 // [3] main::$0 = plus::return#0
lda #min.return // [4] *SCREEN = main::$0 -- _deref_pbuc1=vbuaa
sta SCREEN sta SCREEN
// [5] call plus
// [10] phi from main::@1 to plus [phi:main::@1->plus]
plus_from___b1:
// [10] phi plus::b#2 = 6 [phi:main::@1->plus#0] -- vbuxx=vbuc1
ldx #6
// [10] phi plus::a#2 = '1' [phi:main::@1->plus#1] -- call_phi_close_cx16_ram
lda #'1'
sta.z $ff
lda.z 0
pha
lda #1
sta.z 0
lda.z $ff
jsr plus
sta.z $ff
pla
sta.z 0
lda.z $ff
// [6] plus::return#1 = plus::return#2 -- vbuaa=vbuxx
txa
jmp __b2
// main::@2
__b2:
// [7] main::$1 = plus::return#1
// [8] *(SCREEN+1) = main::$1 -- _deref_pbuc1=vbuaa
// close call
sta SCREEN+1
jmp __breturn jmp __breturn
// main::@return // main::@return
__breturn: __breturn:
// [3] return // [9] return
rts rts
} }
.segment RAM_Bank1 .segment RAM_Bank1
// plus // plus
// char plus(char a, char b) // __register(X) char plus(__register(A) char a, __register(X) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
plus: { plus: {
.label a = '0' // [11] add::a#0 = plus::a#2 -- vbuz1=vbuaa
.label b = 7 sta.z add.a
// [5] call min // [12] add::b#0 = plus::b#2 -- vbuaa=vbuxx
// [7] phi from plus to min [phi:plus->min] -- call_phi_close_cx16_rom txa
min_from_plus: // [13] call add -- call_phi_close_cx16_rom
sta.z $ff
lda.z 1 lda.z 1
pha pha
lda #1 lda #1
sta.z 1 sta.z 1
jsr min lda.z $ff
jsr add
sta.z $ff
pla pla
sta.z 1 sta.z 1
lda.z $ff
// [14] add::return#0 = add::return#1 -- vbuaa=vbuxx
txa
jmp __b1
// plus::@1
__b1:
// [15] plus::return#2 = add::return#0 -- vbuxx=vbuaa
tax
jmp __breturn jmp __breturn
// plus::@return // plus::@return
__breturn: __breturn:
// [6] return // [16] return
rts rts
} }
.segment ROM_Bank1 .segment ROM_Bank1
// min // add
// char min(char a, char b) // __register(X) char add(__zp(2) char a, __register(A) char b)
// __bank(cx16_rom, 1) // __bank(cx16_rom, 1)
min: { add: {
.label return = plus.a+plus.b .label a = 2
// [17] add::return#1 = add::a#0 + add::b#0 -- vbuxx=vbuz1_plus_vbuaa
clc
adc.z a
tax
jmp __breturn jmp __breturn
// min::@return // add::@return
__breturn: __breturn:
// [8] return // [18] return
rts rts
} }
// File Data // File Data
ASSEMBLER OPTIMIZATIONS ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1 Removing instruction jmp __b1
Removing instruction jmp __b2
Removing instruction jmp __breturn Removing instruction jmp __breturn
Removing instruction jmp __b1
Removing instruction jmp __breturn Removing instruction jmp __breturn
Removing instruction jmp __breturn Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination Succesful ASM optimization Pass5NextJumpElimination
Removing instruction plus_from_main: Removing instruction plus_from_main:
Removing instruction __b1: Removing instruction __b1:
Removing instruction plus_from___b1:
Removing instruction __b2:
Removing instruction __breturn: Removing instruction __breturn:
Removing instruction min_from_plus: Removing instruction __b1:
Removing instruction __breturn: Removing instruction __breturn:
Removing instruction __breturn: Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE FINAL SYMBOL TABLE
__constant char * const SCREEN = (char *) 1024 __constant char * const SCREEN = (char *) 1024
__bank(cx16_rom, 1) char add(char a , char b)
char add::a
char add::a#0 // a zp[1]:2 56.0
char add::b
char add::b#0 // reg byte a 112.0
char add::return
char add::return#0 // reg byte a 22.0
char add::return#1 // reg byte x 37.33333333333333
void main() void main()
__bank(cx16_rom, 1) char min(char a , char b) char main::$0 // reg byte a 4.0
char min::a char main::$1 // reg byte a 4.0
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::a char plus::a
__constant char plus::a#0 = '0' // a char plus::a#2 // reg byte a 11.0
char plus::b char plus::b
__constant char plus::b#0 = 7 // b char plus::b#2 // reg byte x 5.5
char plus::return char plus::return
char plus::return#0 // reg byte a 4.0
char plus::return#1 // reg byte a 4.0
char plus::return#2 // reg byte x 3.75
reg byte a [ plus::a#2 ]
reg byte x [ plus::b#2 ]
reg byte a [ plus::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ plus::return#1 ]
reg byte a [ main::$1 ]
zp[1]:2 [ add::a#0 ]
reg byte a [ add::b#0 ]
reg byte a [ add::return#0 ]
reg byte x [ plus::return#2 ]
reg byte x [ add::return#1 ]
FINAL ASSEMBLER FINAL ASSEMBLER
Score: 72 Score: 162
// File Comments // File Comments
/** /**
@ -418,54 +581,108 @@ Score: 72
main: { main: {
// plus('0', 7) // plus('0', 7)
// [1] call plus // [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_phi_close_cx16_ram // [10] phi from main to plus [phi:main->plus]
// [10] phi plus::b#2 = 7 [phi:main->plus#0] -- vbuxx=vbuc1
ldx #7
// [10] phi plus::a#2 = '0' [phi:main->plus#1] -- call_phi_close_cx16_ram
lda #'0'
sta.z $ff
lda.z 0 lda.z 0
pha pha
lda #1 lda #1
sta.z 0 sta.z 0
lda.z $ff
jsr plus jsr plus
sta.z $ff
pla pla
sta.z 0 sta.z 0
lda.z $ff
// plus('0', 7)
// [2] plus::return#0 = plus::return#2 -- vbuaa=vbuxx
txa
// main::@1 // main::@1
// [3] main::$0 = plus::return#0
// SCREEN[0] = plus('0', 7) // SCREEN[0] = plus('0', 7)
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2 // [4] *SCREEN = main::$0 -- _deref_pbuc1=vbuaa
lda #min.return
sta SCREEN sta SCREEN
// plus('1', 6)
// [5] call plus
// [10] phi from main::@1 to plus [phi:main::@1->plus]
// [10] phi plus::b#2 = 6 [phi:main::@1->plus#0] -- vbuxx=vbuc1
ldx #6
// [10] phi plus::a#2 = '1' [phi:main::@1->plus#1] -- call_phi_close_cx16_ram
lda #'1'
sta.z $ff
lda.z 0
pha
lda #1
sta.z 0
lda.z $ff
jsr plus
sta.z $ff
pla
sta.z 0
lda.z $ff
// plus('1', 6)
// [6] plus::return#1 = plus::return#2 -- vbuaa=vbuxx
txa
// main::@2
// [7] main::$1 = plus::return#1
// SCREEN[1] = plus('1', 6)
// [8] *(SCREEN+1) = main::$1 -- _deref_pbuc1=vbuaa
// close call
sta SCREEN+1
// main::@return // main::@return
// } // }
// [3] return // [9] return
rts rts
} }
.segment RAM_Bank1 .segment RAM_Bank1
// plus // plus
// char plus(char a, char b) // __register(X) char plus(__register(A) char a, __register(X) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
plus: { plus: {
.label a = '0' // add(a, b)
.label b = 7 // [11] add::a#0 = plus::a#2 -- vbuz1=vbuaa
// min(a, b) sta.z add.a
// [5] call min // [12] add::b#0 = plus::b#2 -- vbuaa=vbuxx
// [7] phi from plus to min [phi:plus->min] -- call_phi_close_cx16_rom txa
// [13] call add -- call_phi_close_cx16_rom
sta.z $ff
lda.z 1 lda.z 1
pha pha
lda #1 lda #1
sta.z 1 sta.z 1
jsr min lda.z $ff
jsr add
sta.z $ff
pla pla
sta.z 1 sta.z 1
lda.z $ff
// [14] add::return#0 = add::return#1 -- vbuaa=vbuxx
txa
// plus::@1
// [15] plus::return#2 = add::return#0 -- vbuxx=vbuaa
tax
// plus::@return // plus::@return
// } // }
// [6] return // [16] return
rts rts
} }
.segment ROM_Bank1 .segment ROM_Bank1
// min // add
// char min(char a, char b) // __register(X) char add(__zp(2) char a, __register(A) char b)
// __bank(cx16_rom, 1) // __bank(cx16_rom, 1)
min: { add: {
.label return = plus.a+plus.b .label a = 2
// min::@return // a+b
// [8] return // [17] add::return#1 = add::a#0 + add::b#0 -- vbuxx=vbuz1_plus_vbuaa
clc
adc.z a
tax
// add::@return
// }
// [18] return
rts rts
} }
// File Data // File Data

View File

@ -1,14 +1,33 @@
__constant char * const SCREEN = (char *) 1024 __constant char * const SCREEN = (char *) 1024
__bank(cx16_rom, 1) char add(char a , char b)
char add::a
char add::a#0 // a zp[1]:2 56.0
char add::b
char add::b#0 // reg byte a 112.0
char add::return
char add::return#0 // reg byte a 22.0
char add::return#1 // reg byte x 37.33333333333333
void main() void main()
__bank(cx16_rom, 1) char min(char a , char b) char main::$0 // reg byte a 4.0
char min::a char main::$1 // reg byte a 4.0
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::a char plus::a
__constant char plus::a#0 = '0' // a char plus::a#2 // reg byte a 11.0
char plus::b char plus::b
__constant char plus::b#0 = 7 // b char plus::b#2 // reg byte x 5.5
char plus::return char plus::return
char plus::return#0 // reg byte a 4.0
char plus::return#1 // reg byte a 4.0
char plus::return#2 // reg byte x 3.75
reg byte a [ plus::a#2 ]
reg byte x [ plus::b#2 ]
reg byte a [ plus::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ plus::return#1 ]
reg byte a [ main::$1 ]
zp[1]:2 [ add::a#0 ]
reg byte a [ add::b#0 ]
reg byte a [ add::return#0 ]
reg byte x [ plus::return#2 ]
reg byte x [ add::return#1 ]

View File

@ -43,40 +43,77 @@
.segment Code .segment Code
main: { main: {
// plus('0', 7) // plus('0', 7)
ldx #7
lda #'0'
sta.z $ff
lda.z 0 lda.z 0
pha pha
lda #1 lda #1
sta.z 0 sta.z 0
lda.z $ff
jsr plus jsr plus
sta.z $ff
pla pla
sta.z 0 sta.z 0
lda.z $ff
// plus('0', 7)
txa
// SCREEN[0] = plus('0', 7) // SCREEN[0] = plus('0', 7)
lda #min.return
sta SCREEN sta SCREEN
// plus('1', 6)
ldx #6
lda #'1'
sta.z $ff
lda.z 0
pha
lda #1
sta.z 0
lda.z $ff
jsr plus
sta.z $ff
pla
sta.z 0
lda.z $ff
// plus('1', 6)
txa
// SCREEN[1] = plus('1', 6)
// close call
sta SCREEN+1
// } // }
rts rts
} }
.segment RAM_Bank1 .segment RAM_Bank1
// char plus(char a, char b) // __register(X) char plus(__register(A) char a, __register(X) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
plus: { plus: {
.label a = '0' // add(a, b)
.label b = 7 sta.z add.a
// min(a, b) txa
sta.z $ff
lda.z 1 lda.z 1
pha pha
lda #1 lda #1
sta.z 1 sta.z 1
jsr min lda.z $ff
jsr add
sta.z $ff
pla pla
sta.z 1 sta.z 1
lda.z $ff
txa
tax
// } // }
rts rts
} }
.segment ROM_Bank1 .segment ROM_Bank1
// char min(char a, char b) // __register(X) char add(__zp(2) char a, __register(A) char b)
// __bank(cx16_rom, 1) // __bank(cx16_rom, 1)
min: { add: {
.label return = plus.a+plus.b .label a = 2
// a+b
clc
adc.z a
tax
// }
rts rts
} }

View File

@ -3,27 +3,42 @@ void main()
main: scope:[main] from main: scope:[main] from
[0] phi() [0] phi()
[1] call plus [1] call plus
[2] plus::return#0 = plus::return#2
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
[2] *SCREEN = min::return#1 [3] main::$0 = plus::return#0
[4] *SCREEN = main::$0
[5] call plus
[6] plus::return#1 = plus::return#2
to:main::@2
main::@2: scope:[main] from main::@1
[7] main::$1 = plus::return#1
[8] *(SCREEN+1) = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
[3] return [9] return
to:@return to:@return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
[4] phi() [10] plus::b#2 = phi( main/7, main::@1/6 )
[5] call min [10] plus::a#2 = phi( main/'0', main::@1/'1' )
[11] add::a#0 = plus::a#2
[12] add::b#0 = plus::b#2
[13] call add
[14] add::return#0 = add::return#1
to:plus::@1
plus::@1: scope:[plus] from plus
[15] plus::return#2 = add::return#0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus::@1
[6] return [16] return
to:@return to:@return
__bank(cx16_rom, 1) char min(char a , char b) __bank(cx16_rom, 1) char add(char a , char b)
min: scope:[min] from plus add: scope:[add] from plus
[7] phi() [17] add::return#1 = add::a#0 + add::b#0
to:min::@return to:add::@return
min::@return: scope:[min] from min add::@return: scope:[add] from add
[8] return [18] return
to:@return to:@return

View File

@ -7,47 +7,56 @@ main: scope:[main] from __start
plus::a#0 = '0' plus::a#0 = '0'
plus::b#0 = 7 plus::b#0 = 7
call plus call plus
plus::return#0 = plus::return#2 plus::return#0 = plus::return#3
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
plus::return#3 = phi( main/plus::return#0 ) plus::return#4 = phi( main/plus::return#0 )
main::$0 = plus::return#3 main::$0 = plus::return#4
SCREEN[0] = main::$0 SCREEN[0] = main::$0
plus::a#1 = '1'
plus::b#1 = 6
call plus
plus::return#1 = plus::return#3
to:main::@2
main::@2: scope:[main] from main::@1
plus::return#5 = phi( main::@1/plus::return#1 )
main::$1 = plus::return#5
SCREEN[1] = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
return return
to:@return to:@return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
plus::b#1 = phi( main/plus::b#0 ) plus::b#2 = phi( main/plus::b#0, main::@1/plus::b#1 )
plus::a#1 = phi( main/plus::a#0 ) plus::a#2 = phi( main/plus::a#0, main::@1/plus::a#1 )
min::a#0 = plus::a#1 add::a#0 = plus::a#2
min::b#0 = plus::b#1 add::b#0 = plus::b#2
call min call add
min::return#0 = min::return#2 add::return#0 = add::return#2
to:plus::@1 to:plus::@1
plus::@1: scope:[plus] from plus plus::@1: scope:[plus] from plus
min::return#3 = phi( plus/min::return#0 ) add::return#3 = phi( plus/add::return#0 )
plus::$0 = min::return#3 plus::$0 = add::return#3
plus::return#1 = plus::$0 plus::return#2 = plus::$0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus::@1 plus::@return: scope:[plus] from plus::@1
plus::return#4 = phi( plus::@1/plus::return#1 ) plus::return#6 = phi( plus::@1/plus::return#2 )
plus::return#2 = plus::return#4 plus::return#3 = plus::return#6
return return
to:@return to:@return
__bank(cx16_rom, 1) char min(char a , char b) __bank(cx16_rom, 1) char add(char a , char b)
min: scope:[min] from plus add: scope:[add] from plus
min::b#1 = phi( plus/min::b#0 ) add::b#1 = phi( plus/add::b#0 )
min::a#1 = phi( plus/min::a#0 ) add::a#1 = phi( plus/add::a#0 )
min::$0 = min::a#1 + min::b#1 add::$0 = add::a#1 + add::b#1
min::return#1 = min::$0 add::return#1 = add::$0
to:min::@return to:add::@return
min::@return: scope:[min] from min add::@return: scope:[add] from add
min::return#4 = phi( min/min::return#1 ) add::return#4 = phi( add/add::return#1 )
min::return#2 = min::return#4 add::return#2 = add::return#4
return return
to:@return to:@return
@ -64,64 +73,74 @@ __start::@return: scope:[__start] from __start::@1
SYMBOL TABLE SSA SYMBOL TABLE SSA
__constant char * const SCREEN = (char *)$400 __constant char * const SCREEN = (char *)$400
void __start() void __start()
__bank(cx16_rom, 1) char add(char a , char b)
char add::$0
char add::a
char add::a#0
char add::a#1
char add::b
char add::b#0
char add::b#1
char add::return
char add::return#0
char add::return#1
char add::return#2
char add::return#3
char add::return#4
void main() void main()
char main::$0 char main::$0
__bank(cx16_rom, 1) char min(char a , char b) char main::$1
char min::$0
char min::a
char min::a#0
char min::a#1
char min::b
char min::b#0
char min::b#1
char min::return
char min::return#0
char min::return#1
char min::return#2
char min::return#3
char min::return#4
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::$0 char plus::$0
char plus::a char plus::a
char plus::a#0 char plus::a#0
char plus::a#1 char plus::a#1
char plus::a#2
char plus::b char plus::b
char plus::b#0 char plus::b#0
char plus::b#1 char plus::b#1
char plus::b#2
char plus::return char plus::return
char plus::return#0 char plus::return#0
char plus::return#1 char plus::return#1
char plus::return#2 char plus::return#2
char plus::return#3 char plus::return#3
char plus::return#4 char plus::return#4
char plus::return#5
char plus::return#6
Adding number conversion cast (unumber) 7 in plus::b#0 = 7 Adding number conversion cast (unumber) 7 in plus::b#0 = 7
Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0 Adding number conversion cast (unumber) 0 in SCREEN[0] = main::$0
Adding number conversion cast (unumber) 6 in plus::b#1 = 6
Adding number conversion cast (unumber) 1 in SCREEN[1] = main::$1
Successful SSA optimization PassNAddNumberTypeConversions Successful SSA optimization PassNAddNumberTypeConversions
Inlining cast plus::b#0 = (unumber)7 Inlining cast plus::b#0 = (unumber)7
Inlining cast plus::b#1 = (unumber)6
Successful SSA optimization Pass2InlineCast Successful SSA optimization Pass2InlineCast
Simplifying constant pointer cast (char *) 1024 Simplifying constant pointer cast (char *) 1024
Simplifying constant integer cast 7 Simplifying constant integer cast 7
Simplifying constant integer cast 0 Simplifying constant integer cast 0
Simplifying constant integer cast 6
Simplifying constant integer cast 1
Successful SSA optimization PassNCastSimplification Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (char) 7 Finalized unsigned number type (char) 7
Finalized unsigned number type (char) 0 Finalized unsigned number type (char) 0
Finalized unsigned number type (char) 6
Finalized unsigned number type (char) 1
Successful SSA optimization PassNFinalizeNumberTypeConversions Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias plus::return#0 = plus::return#3 Alias plus::return#0 = plus::return#4
Alias min::return#0 = min::return#3 Alias plus::return#1 = plus::return#5
Alias plus::return#1 = plus::$0 plus::return#4 plus::return#2 Alias add::return#0 = add::return#3
Alias min::return#1 = min::$0 min::return#4 min::return#2 Alias plus::return#2 = plus::$0 plus::return#6 plus::return#3
Alias add::return#1 = add::$0 add::return#4 add::return#2
Successful SSA optimization Pass2AliasElimination Successful SSA optimization Pass2AliasElimination
Identical Phi Values plus::a#1 plus::a#0 Identical Phi Values add::a#1 add::a#0
Identical Phi Values plus::b#1 plus::b#0 Identical Phi Values add::b#1 add::b#0
Identical Phi Values min::a#1 min::a#0
Identical Phi Values min::b#1 min::b#0
Successful SSA optimization Pass2IdenticalPhiElimination Successful SSA optimization Pass2IdenticalPhiElimination
Constant plus::a#0 = '0' Constant plus::a#0 = '0'
Constant plus::b#0 = 7 Constant plus::b#0 = 7
Successful SSA optimization Pass2ConstantIdentification Constant plus::a#1 = '1'
Constant min::a#0 = plus::a#0 Constant plus::b#1 = 6
Constant min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantIdentification Successful SSA optimization Pass2ConstantIdentification
Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0 Simplifying expression containing zero SCREEN in [5] SCREEN[0] = main::$0
Successful SSA optimization PassNSimplifyExpressionWithZero Successful SSA optimization PassNSimplifyExpressionWithZero
@ -130,40 +149,25 @@ Removing unused procedure block __start
Removing unused procedure block __start::@1 Removing unused procedure block __start::@1
Removing unused procedure block __start::@return Removing unused procedure block __start::@return
Successful SSA optimization PassNEliminateEmptyStart Successful SSA optimization PassNEliminateEmptyStart
Constant right-side identified [9] min::return#1 = min::a#0 + min::b#0 Inlining constant with var siblings plus::a#0
Successful SSA optimization Pass2ConstantRValueConsolidation Inlining constant with var siblings plus::b#0
Constant min::return#1 = min::a#0+min::b#0 Inlining constant with var siblings plus::a#1
Successful SSA optimization Pass2ConstantIdentification Inlining constant with var siblings plus::b#1
Constant min::return#0 = min::return#1 Constant inlined plus::b#1 = 6
Successful SSA optimization Pass2ConstantIdentification Constant inlined plus::b#0 = 7
Constant plus::return#1 = min::return#0 Constant inlined plus::a#1 = '1'
Successful SSA optimization Pass2ConstantIdentification Constant inlined plus::a#0 = '0'
Constant plus::return#0 = plus::return#1
Successful SSA optimization Pass2ConstantIdentification
Constant main::$0 = plus::return#0
Successful SSA optimization Pass2ConstantIdentification
Inlining constant with different constant siblings min::return#0
Constant inlined plus::return#0 = min::return#1
Constant inlined main::$0 = min::return#1
Constant inlined plus::return#1 = min::return#1
Constant inlined min::a#0 = plus::a#0
Constant inlined min::return#0 = min::return#1
Constant inlined min::b#0 = plus::b#0
Successful SSA optimization Pass2ConstantInlining Successful SSA optimization Pass2ConstantInlining
Consolidated array index constant in *(SCREEN+1)
Successful SSA optimization Pass2ConstantAdditionElimination
Adding NOP phi() at start of main Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of plus::@1
Adding NOP phi() at start of min
CALL GRAPH CALL GRAPH
Calls in [main] to plus:1 Calls in [main] to plus:1 plus:5
Calls in [plus] to min:5 Calls in [plus] to add:13
Created 0 initial phi equivalence classes Created 2 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes Coalesced down to 2 phi equivalence classes
Culled Empty Block label plus::@1
Adding NOP phi() at start of main Adding NOP phi() at start of main
Adding NOP phi() at start of plus
Adding NOP phi() at start of min
FINAL CONTROL FLOW GRAPH FINAL CONTROL FLOW GRAPH
@ -171,60 +175,144 @@ void main()
main: scope:[main] from main: scope:[main] from
[0] phi() [0] phi()
[1] call plus [1] call plus
[2] plus::return#0 = plus::return#2
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
[2] *SCREEN = min::return#1 [3] main::$0 = plus::return#0
[4] *SCREEN = main::$0
[5] call plus
[6] plus::return#1 = plus::return#2
to:main::@2
main::@2: scope:[main] from main::@1
[7] main::$1 = plus::return#1
[8] *(SCREEN+1) = main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@2
[3] return [9] return
to:@return to:@return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
plus: scope:[plus] from main plus: scope:[plus] from main main::@1
[4] phi() [10] plus::b#2 = phi( main/7, main::@1/6 )
[5] call min [10] plus::a#2 = phi( main/'0', main::@1/'1' )
[11] add::a#0 = plus::a#2
[12] add::b#0 = plus::b#2
[13] call add
[14] add::return#0 = add::return#1
to:plus::@1
plus::@1: scope:[plus] from plus
[15] plus::return#2 = add::return#0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus::@1
[6] return [16] return
to:@return to:@return
__bank(cx16_rom, 1) char min(char a , char b) __bank(cx16_rom, 1) char add(char a , char b)
min: scope:[min] from plus add: scope:[add] from plus
[7] phi() [17] add::return#1 = add::a#0 + add::b#0
to:min::@return to:add::@return
min::@return: scope:[min] from min add::@return: scope:[add] from add
[8] return [18] return
to:@return to:@return
VARIABLE REGISTER WEIGHTS VARIABLE REGISTER WEIGHTS
__bank(cx16_rom, 1) char add(char a , char b)
char add::a
char add::a#0 // 56.0
char add::b
char add::b#0 // 112.0
char add::return
char add::return#0 // 22.0
char add::return#1 // 37.33333333333333
void main() void main()
__bank(cx16_rom, 1) char min(char a , char b) char main::$0 // 4.0
char min::a char main::$1 // 4.0
char min::b
char min::return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::a char plus::a
char plus::a#2 // 11.0
char plus::b char plus::b
char plus::b#2 // 5.5
char plus::return char plus::return
char plus::return#0 // 4.0
char plus::return#1 // 4.0
char plus::return#2 // 3.75
Initial phi equivalence classes Initial phi equivalence classes
[ plus::a#2 ]
[ plus::b#2 ]
Added variable plus::return#0 to live range equivalence class [ plus::return#0 ]
Added variable main::$0 to live range equivalence class [ main::$0 ]
Added variable plus::return#1 to live range equivalence class [ plus::return#1 ]
Added variable main::$1 to live range equivalence class [ main::$1 ]
Added variable add::a#0 to live range equivalence class [ add::a#0 ]
Added variable add::b#0 to live range equivalence class [ add::b#0 ]
Added variable add::return#0 to live range equivalence class [ add::return#0 ]
Added variable plus::return#2 to live range equivalence class [ plus::return#2 ]
Added variable add::return#1 to live range equivalence class [ add::return#1 ]
Complete equivalence classes Complete equivalence classes
[ plus::a#2 ]
[ plus::b#2 ]
[ plus::return#0 ]
[ main::$0 ]
[ plus::return#1 ]
[ main::$1 ]
[ add::a#0 ]
[ add::b#0 ]
[ add::return#0 ]
[ plus::return#2 ]
[ add::return#1 ]
Allocated zp[1]:2 [ add::b#0 ]
Allocated zp[1]:3 [ add::a#0 ]
Allocated zp[1]:4 [ add::return#1 ]
Allocated zp[1]:5 [ add::return#0 ]
Allocated zp[1]:6 [ plus::a#2 ]
Allocated zp[1]:7 [ plus::b#2 ]
Allocated zp[1]:8 [ plus::return#0 ]
Allocated zp[1]:9 [ main::$0 ]
Allocated zp[1]:10 [ plus::return#1 ]
Allocated zp[1]:11 [ main::$1 ]
Allocated zp[1]:12 [ plus::return#2 ]
REGISTER UPLIFT POTENTIAL REGISTERS REGISTER UPLIFT POTENTIAL REGISTERS
Statement [1] call plus [ ] ( [ ] { } ) always clobbers reg byte a Statement [1] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#0 = plus::return#2 } } ) always clobbers reg byte a
Statement [2] *SCREEN = min::return#1 [ ] ( [ ] { } ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:12 [ plus::return#2 ]
Statement [5] call min [ ] ( plus:1 [ ] { } ) always clobbers reg byte a Statement [5] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#1 = plus::return#2 } } ) always clobbers reg byte a
Statement [13] call add [ add::return#1 ] ( plus:1 [ add::return#1 ] { { plus::return#0 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } plus:5 [ add::return#1 ] { { plus::return#1 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp[1]:4 [ add::return#1 ]
Statement [17] add::return#1 = add::a#0 + add::b#0 [ add::return#1 ] ( plus:1::add:13 [ add::return#1 ] { { plus::return#0 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } plus:5::add:13 [ add::return#1 ] { { plus::return#1 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } ) always clobbers reg byte a
Statement [1] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#0 = plus::return#2 } } ) always clobbers reg byte a
Statement [5] call plus [ plus::return#2 ] ( [ plus::return#2 ] { { plus::return#1 = plus::return#2 } } ) always clobbers reg byte a
Statement [13] call add [ add::return#1 ] ( plus:1 [ add::return#1 ] { { plus::return#0 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } plus:5 [ add::return#1 ] { { plus::return#1 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } ) always clobbers reg byte a
Statement [17] add::return#1 = add::a#0 + add::b#0 [ add::return#1 ] ( plus:1::add:13 [ add::return#1 ] { { plus::return#0 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } plus:5::add:13 [ add::return#1 ] { { plus::return#1 = plus::return#2 } { add::a#0 = plus::a#2 } { add::b#0 = plus::b#2 } { add::return#0 = add::return#1 } } ) always clobbers reg byte a
Potential registers zp[1]:6 [ plus::a#2 ] : zp[1]:6 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:7 [ plus::b#2 ] : zp[1]:7 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:8 [ plus::return#0 ] : zp[1]:8 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:9 [ main::$0 ] : zp[1]:9 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:10 [ plus::return#1 ] : zp[1]:10 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:11 [ main::$1 ] : zp[1]:11 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:3 [ add::a#0 ] : zp[1]:3 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:2 [ add::b#0 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:5 [ add::return#0 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:12 [ plus::return#2 ] : zp[1]:12 , reg byte x , reg byte y ,
Potential registers zp[1]:4 [ add::return#1 ] : zp[1]:4 , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES REGISTER UPLIFT SCOPES
Uplift Scope [main] Uplift Scope [add] 112: zp[1]:2 [ add::b#0 ] 56: zp[1]:3 [ add::a#0 ] 37.33: zp[1]:4 [ add::return#1 ] 22: zp[1]:5 [ add::return#0 ]
Uplift Scope [plus] Uplift Scope [plus] 11: zp[1]:6 [ plus::a#2 ] 5.5: zp[1]:7 [ plus::b#2 ] 4: zp[1]:8 [ plus::return#0 ] 4: zp[1]:10 [ plus::return#1 ] 3.75: zp[1]:12 [ plus::return#2 ]
Uplift Scope [min] Uplift Scope [main] 4: zp[1]:9 [ main::$0 ] 4: zp[1]:11 [ main::$1 ]
Uplift Scope [] Uplift Scope []
Uplifting [main] best 111 combination Uplifting [add] best 223 combination reg byte a [ add::b#0 ] zp[1]:3 [ add::a#0 ] reg byte x [ add::return#1 ] reg byte a [ add::return#0 ]
Uplifting [plus] best 111 combination Limited combination testing to 100 combinations of 192 possible.
Uplifting [min] best 111 combination Uplifting [plus] best 195 combination reg byte a [ plus::a#2 ] reg byte x [ plus::b#2 ] reg byte a [ plus::return#0 ] reg byte a [ plus::return#1 ] zp[1]:12 [ plus::return#2 ]
Uplifting [] best 111 combination Limited combination testing to 100 combinations of 768 possible.
Uplifting [main] best 183 combination reg byte a [ main::$0 ] reg byte a [ main::$1 ]
Uplifting [] best 183 combination
Attempting to uplift remaining variables inzp[1]:3 [ add::a#0 ]
Uplifting [add] best 183 combination zp[1]:3 [ add::a#0 ]
Attempting to uplift remaining variables inzp[1]:12 [ plus::return#2 ]
Uplifting [plus] best 180 combination reg byte x [ plus::return#2 ]
Allocated (was zp[1]:3) zp[1]:2 [ add::a#0 ]
ASSEMBLER BEFORE OPTIMIZATION ASSEMBLER BEFORE OPTIMIZATION
// File Comments // File Comments
@ -276,97 +364,172 @@ ASSEMBLER BEFORE OPTIMIZATION
// main // main
main: { main: {
// [1] call plus // [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_phi_close_cx16_ram // [10] phi from main to plus [phi:main->plus]
plus_from_main: plus_from_main:
// [10] phi plus::b#2 = 7 [phi:main->plus#0] -- vbuxx=vbuc1
ldx #7
// [10] phi plus::a#2 = '0' [phi:main->plus#1] -- call_phi_close_cx16_ram
lda #'0'
sta.z $ff
lda.z 0 lda.z 0
pha pha
lda #1 lda #1
sta.z 0 sta.z 0
lda.z $ff
jsr plus jsr plus
sta.z $ff
pla pla
sta.z 0 sta.z 0
lda.z $ff
// [2] plus::return#0 = plus::return#2 -- vbuaa=vbuxx
txa
jmp __b1 jmp __b1
// main::@1 // main::@1
__b1: __b1:
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2 // [3] main::$0 = plus::return#0
lda #min.return // [4] *SCREEN = main::$0 -- _deref_pbuc1=vbuaa
sta SCREEN sta SCREEN
// [5] call plus
// [10] phi from main::@1 to plus [phi:main::@1->plus]
plus_from___b1:
// [10] phi plus::b#2 = 6 [phi:main::@1->plus#0] -- vbuxx=vbuc1
ldx #6
// [10] phi plus::a#2 = '1' [phi:main::@1->plus#1] -- call_phi_close_cx16_ram
lda #'1'
sta.z $ff
lda.z 0
pha
lda #1
sta.z 0
lda.z $ff
jsr plus
sta.z $ff
pla
sta.z 0
lda.z $ff
// [6] plus::return#1 = plus::return#2 -- vbuaa=vbuxx
txa
jmp __b2
// main::@2
__b2:
// [7] main::$1 = plus::return#1
// [8] *(SCREEN+1) = main::$1 -- _deref_pbuc1=vbuaa
// close call
sta SCREEN+1
jmp __breturn jmp __breturn
// main::@return // main::@return
__breturn: __breturn:
// [3] return // [9] return
rts rts
} }
.segment RAM_Bank1 .segment RAM_Bank1
// plus // plus
// char plus(char a, char b) // __register(X) char plus(__register(A) char a, __register(X) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
plus: { plus: {
.label a = '0' // [11] add::a#0 = plus::a#2 -- vbuz1=vbuaa
.label b = 7 sta.z add.a
// [5] call min // [12] add::b#0 = plus::b#2 -- vbuaa=vbuxx
// [7] phi from plus to min [phi:plus->min] -- call_phi_close_cx16_rom txa
min_from_plus: // [13] call add -- call_phi_close_cx16_rom
sta.z $ff
lda.z 1 lda.z 1
pha pha
lda #1 lda #1
sta.z 1 sta.z 1
jsr min lda.z $ff
jsr add
sta.z $ff
pla pla
sta.z 1 sta.z 1
lda.z $ff
// [14] add::return#0 = add::return#1 -- vbuaa=vbuxx
txa
jmp __b1
// plus::@1
__b1:
// [15] plus::return#2 = add::return#0 -- vbuxx=vbuaa
tax
jmp __breturn jmp __breturn
// plus::@return // plus::@return
__breturn: __breturn:
// [6] return // [16] return
rts rts
} }
.segment ROM_Bank1 .segment ROM_Bank1
// min // add
// char min(char a, char b) // __register(X) char add(__zp(2) char a, __register(A) char b)
// __bank(cx16_rom, 1) // __bank(cx16_rom, 1)
min: { add: {
.label return = plus.a+plus.b .label a = 2
// [17] add::return#1 = add::a#0 + add::b#0 -- vbuxx=vbuz1_plus_vbuaa
clc
adc.z a
tax
jmp __breturn jmp __breturn
// min::@return // add::@return
__breturn: __breturn:
// [8] return // [18] return
rts rts
} }
// File Data // File Data
ASSEMBLER OPTIMIZATIONS ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1 Removing instruction jmp __b1
Removing instruction jmp __b2
Removing instruction jmp __breturn Removing instruction jmp __breturn
Removing instruction jmp __b1
Removing instruction jmp __breturn Removing instruction jmp __breturn
Removing instruction jmp __breturn Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination Succesful ASM optimization Pass5NextJumpElimination
Removing instruction plus_from_main: Removing instruction plus_from_main:
Removing instruction __b1: Removing instruction __b1:
Removing instruction plus_from___b1:
Removing instruction __b2:
Removing instruction __breturn: Removing instruction __breturn:
Removing instruction min_from_plus: Removing instruction __b1:
Removing instruction __breturn: Removing instruction __breturn:
Removing instruction __breturn: Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE FINAL SYMBOL TABLE
__constant char * const SCREEN = (char *) 1024 __constant char * const SCREEN = (char *) 1024
__bank(cx16_rom, 1) char add(char a , char b)
char add::a
char add::a#0 // a zp[1]:2 56.0
char add::b
char add::b#0 // reg byte a 112.0
char add::return
char add::return#0 // reg byte a 22.0
char add::return#1 // reg byte x 37.33333333333333
void main() void main()
__bank(cx16_rom, 1) char min(char a , char b) char main::$0 // reg byte a 4.0
char min::a char main::$1 // reg byte a 4.0
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::a char plus::a
__constant char plus::a#0 = '0' // a char plus::a#2 // reg byte a 11.0
char plus::b char plus::b
__constant char plus::b#0 = 7 // b char plus::b#2 // reg byte x 5.5
char plus::return char plus::return
char plus::return#0 // reg byte a 4.0
char plus::return#1 // reg byte a 4.0
char plus::return#2 // reg byte x 3.75
reg byte a [ plus::a#2 ]
reg byte x [ plus::b#2 ]
reg byte a [ plus::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ plus::return#1 ]
reg byte a [ main::$1 ]
zp[1]:2 [ add::a#0 ]
reg byte a [ add::b#0 ]
reg byte a [ add::return#0 ]
reg byte x [ plus::return#2 ]
reg byte x [ add::return#1 ]
FINAL ASSEMBLER FINAL ASSEMBLER
Score: 72 Score: 162
// File Comments // File Comments
/** /**
@ -418,54 +581,108 @@ Score: 72
main: { main: {
// plus('0', 7) // plus('0', 7)
// [1] call plus // [1] call plus
// [4] phi from main to plus [phi:main->plus] -- call_phi_close_cx16_ram // [10] phi from main to plus [phi:main->plus]
// [10] phi plus::b#2 = 7 [phi:main->plus#0] -- vbuxx=vbuc1
ldx #7
// [10] phi plus::a#2 = '0' [phi:main->plus#1] -- call_phi_close_cx16_ram
lda #'0'
sta.z $ff
lda.z 0 lda.z 0
pha pha
lda #1 lda #1
sta.z 0 sta.z 0
lda.z $ff
jsr plus jsr plus
sta.z $ff
pla pla
sta.z 0 sta.z 0
lda.z $ff
// plus('0', 7)
// [2] plus::return#0 = plus::return#2 -- vbuaa=vbuxx
txa
// main::@1 // main::@1
// [3] main::$0 = plus::return#0
// SCREEN[0] = plus('0', 7) // SCREEN[0] = plus('0', 7)
// [2] *SCREEN = min::return#1 -- _deref_pbuc1=vbuc2 // [4] *SCREEN = main::$0 -- _deref_pbuc1=vbuaa
lda #min.return
sta SCREEN sta SCREEN
// plus('1', 6)
// [5] call plus
// [10] phi from main::@1 to plus [phi:main::@1->plus]
// [10] phi plus::b#2 = 6 [phi:main::@1->plus#0] -- vbuxx=vbuc1
ldx #6
// [10] phi plus::a#2 = '1' [phi:main::@1->plus#1] -- call_phi_close_cx16_ram
lda #'1'
sta.z $ff
lda.z 0
pha
lda #1
sta.z 0
lda.z $ff
jsr plus
sta.z $ff
pla
sta.z 0
lda.z $ff
// plus('1', 6)
// [6] plus::return#1 = plus::return#2 -- vbuaa=vbuxx
txa
// main::@2
// [7] main::$1 = plus::return#1
// SCREEN[1] = plus('1', 6)
// [8] *(SCREEN+1) = main::$1 -- _deref_pbuc1=vbuaa
// close call
sta SCREEN+1
// main::@return // main::@return
// } // }
// [3] return // [9] return
rts rts
} }
.segment RAM_Bank1 .segment RAM_Bank1
// plus // plus
// char plus(char a, char b) // __register(X) char plus(__register(A) char a, __register(X) char b)
// __bank(cx16_ram, 1) // __bank(cx16_ram, 1)
plus: { plus: {
.label a = '0' // add(a, b)
.label b = 7 // [11] add::a#0 = plus::a#2 -- vbuz1=vbuaa
// min(a, b) sta.z add.a
// [5] call min // [12] add::b#0 = plus::b#2 -- vbuaa=vbuxx
// [7] phi from plus to min [phi:plus->min] -- call_phi_close_cx16_rom txa
// [13] call add -- call_phi_close_cx16_rom
sta.z $ff
lda.z 1 lda.z 1
pha pha
lda #1 lda #1
sta.z 1 sta.z 1
jsr min lda.z $ff
jsr add
sta.z $ff
pla pla
sta.z 1 sta.z 1
lda.z $ff
// [14] add::return#0 = add::return#1 -- vbuaa=vbuxx
txa
// plus::@1
// [15] plus::return#2 = add::return#0 -- vbuxx=vbuaa
tax
// plus::@return // plus::@return
// } // }
// [6] return // [16] return
rts rts
} }
.segment ROM_Bank1 .segment ROM_Bank1
// min // add
// char min(char a, char b) // __register(X) char add(__zp(2) char a, __register(A) char b)
// __bank(cx16_rom, 1) // __bank(cx16_rom, 1)
min: { add: {
.label return = plus.a+plus.b .label a = 2
// min::@return // a+b
// [8] return // [17] add::return#1 = add::a#0 + add::b#0 -- vbuxx=vbuz1_plus_vbuaa
clc
adc.z a
tax
// add::@return
// }
// [18] return
rts rts
} }
// File Data // File Data

View File

@ -1,14 +1,33 @@
__constant char * const SCREEN = (char *) 1024 __constant char * const SCREEN = (char *) 1024
__bank(cx16_rom, 1) char add(char a , char b)
char add::a
char add::a#0 // a zp[1]:2 56.0
char add::b
char add::b#0 // reg byte a 112.0
char add::return
char add::return#0 // reg byte a 22.0
char add::return#1 // reg byte x 37.33333333333333
void main() void main()
__bank(cx16_rom, 1) char min(char a , char b) char main::$0 // reg byte a 4.0
char min::a char main::$1 // reg byte a 4.0
char min::b
char min::return
__constant char min::return#1 = plus::a#0+plus::b#0 // return
__bank(cx16_ram, 1) char plus(char a , char b) __bank(cx16_ram, 1) char plus(char a , char b)
char plus::a char plus::a
__constant char plus::a#0 = '0' // a char plus::a#2 // reg byte a 11.0
char plus::b char plus::b
__constant char plus::b#0 = 7 // b char plus::b#2 // reg byte x 5.5
char plus::return char plus::return
char plus::return#0 // reg byte a 4.0
char plus::return#1 // reg byte a 4.0
char plus::return#2 // reg byte x 3.75
reg byte a [ plus::a#2 ]
reg byte x [ plus::b#2 ]
reg byte a [ plus::return#0 ]
reg byte a [ main::$0 ]
reg byte a [ plus::return#1 ]
reg byte a [ main::$1 ]
zp[1]:2 [ add::a#0 ]
reg byte a [ add::b#0 ]
reg byte a [ add::return#0 ]
reg byte x [ plus::return#2 ]
reg byte x [ add::return#1 ]