1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-02-28 08:29:42 +00:00

Now auto-converting global variables modified inside a __stackcall procedure to load/store.

This commit is contained in:
jespergravgaard 2020-03-08 12:57:32 +01:00
parent d217113afb
commit afe8294cd1
39 changed files with 2017 additions and 2066 deletions

View File

@ -53,6 +53,20 @@ public class Pass1CallStack extends Pass2SsaOptimization {
if(createStackBase) if(createStackBase)
CallingConventionStack.getStackBaseConstant(getScope()); CallingConventionStack.getStackBaseConstant(getScope());
// Set variables modified in STACK_CALL procedures to load/store
for(Procedure procedure : getScope().getAllProcedures(true)) {
if(Procedure.CallingConvention.STACK_CALL.equals(procedure.getCallingConvention())) {
Set<VariableRef> modifiedVars = getProgram().getProcedureModifiedVars().getModifiedVars(procedure.getRef());
for(VariableRef modifiedVar : modifiedVars) {
final Variable variable = getScope().getVariable(modifiedVar);
if(variable.isKindPhiMaster()) {
getLog().append("Converting PHI-variable modified inside __stackcall procedure "+procedure.getFullName()+"() to load/store "+variable.toString(getProgram()));
variable.setKind(Variable.Kind.LOAD_STORE);
}
}
}
}
// Transform STACK_CALL calls to call-prepare, call-execute, call-finalize // Transform STACK_CALL calls to call-prepare, call-execute, call-finalize
for(ControlFlowBlock block : getGraph().getAllBlocks()) { for(ControlFlowBlock block : getGraph().getAllBlocks()) {
ListIterator<Statement> stmtIt = block.getStatements().listIterator(); ListIterator<Statement> stmtIt = block.getStatements().listIterator();

View File

@ -2,7 +2,6 @@
// Returning and passing struct values // Returning and passing struct values
#pragma calling(__stackcall) #pragma calling(__stackcall)
#pragma var_model(ma_zp)
const char* SCREEN = 0x0400; const char* SCREEN = 0x0400;
char idx = 0; char idx = 0;

View File

@ -2,7 +2,6 @@
// Returning and passing struct of struct values // Returning and passing struct of struct values
#pragma calling(__stackcall) #pragma calling(__stackcall)
#pragma var_model(ma_zp)
const char* SCREEN = 0x0400; const char* SCREEN = 0x0400;
char idx = 0; char idx = 0;

View File

@ -2,7 +2,6 @@
// Test that comments are handled correctly // Test that comments are handled correctly
#pragma calling(__stackcall) #pragma calling(__stackcall)
#pragma var_model(ma_zp)
const char* SCREEN = 0x0400; const char* SCREEN = 0x0400;
char idx = 0; char idx = 0;

View File

@ -2,7 +2,6 @@
// Illustrates live ranges for main::val and printline::i // Illustrates live ranges for main::val and printline::i
#pragma calling(__stackcall) #pragma calling(__stackcall)
#pragma var_model(ma_zp)
const char* SCREEN = 0x0400; const char* SCREEN = 0x0400;

View File

@ -2,7 +2,6 @@
// Illustrates live ranges for printline::i and global variable val // Illustrates live ranges for printline::i and global variable val
#pragma calling(__stackcall) #pragma calling(__stackcall)
#pragma var_model(ma_zp)
const char* SCREEN = 0x0400; const char* SCREEN = 0x0400;

View File

@ -2,7 +2,6 @@
// Illustrates live range problem with function variable printother::i and global variable val // Illustrates live range problem with function variable printother::i and global variable val
#pragma calling(__stackcall) #pragma calling(__stackcall)
#pragma var_model(ma_zp)
const char* SCREEN = 0x0400; const char* SCREEN = 0x0400;

View File

@ -4,9 +4,9 @@
:BasicUpstart(__bbegin) :BasicUpstart(__bbegin)
.pc = $80d "Program" .pc = $80d "Program"
.label SCREEN = $400 .label SCREEN = $400
.const OFFSET_STRUCT_POINT_Y = 1
.const STACK_BASE = $103 .const STACK_BASE = $103
.label idx = 2 .const OFFSET_STRUCT_POINT_Y = 1
.label idx = 3
__bbegin: __bbegin:
// idx = 0 // idx = 0
lda #0 lda #0
@ -39,20 +39,14 @@ print: {
// } // }
rts rts
} }
// get(byte register(X) i)
get: { get: {
.const OFFSET_STACK_I = 0 .const OFFSET_STACK_I = 0
.label p = 6
tsx tsx
lda STACK_BASE+OFFSET_STACK_I,x lda STACK_BASE+OFFSET_STACK_I,x
tax tax
// i/2 // i/2
txa txa
lsr lsr
// p = { i, i/2 }
stx.z p
sta p+OFFSET_STRUCT_POINT_Y
// return p;
tay tay
// } // }
txa txa
@ -64,9 +58,7 @@ get: {
rts rts
} }
main: { main: {
.label i = 3 .label i = 2
.label p = 4
// i=0
lda #0 lda #0
sta.z i sta.z i
__b1: __b1:
@ -82,16 +74,15 @@ main: {
pha pha
pha pha
jsr get jsr get
// p = get(i)
pla
tay
pla pla
tax tax
pla
// p = get(i)
stx.z p
sta p+OFFSET_STRUCT_POINT_Y
// print(p) // print(p)
txa tya
pha pha
lda p+OFFSET_STRUCT_POINT_Y txa
pha pha
jsr print jsr print
pla pla

View File

@ -23,40 +23,35 @@ print::@return: scope:[print] from print
__stackcall (struct Point()) get((byte) get::i) __stackcall (struct Point()) get((byte) get::i)
get: scope:[get] from get: scope:[get] from
[11] (byte) get::i#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I) [11] (byte) get::return_x#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I)
[12] (byte~) get::$0 ← (byte) get::i#0 >> (byte) 1 [12] (byte) get::return_y#0 ← (byte) get::return_x#0 >> (byte) 1
[13] *((byte*)&(struct Point) get::p) ← (byte) get::i#0
[14] *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) get::$0
[15] (byte) get::return_x#0 ← *((byte*)&(struct Point) get::p)
[16] (byte) get::return_y#0 ← *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_Y)
to:get::@return to:get::@return
get::@return: scope:[get] from get get::@return: scope:[get] from get
[17] stackidx(byte,(byte) 0) ← (byte) get::return_x#0 [13] stackidx(byte,(byte) 0) ← (byte) get::return_x#0
[18] stackidx(byte,(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_y#0 [14] stackidx(byte,(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_y#0
[19] return [15] return
to:@return to:@return
__stackcall (void()) main() __stackcall (void()) main()
main: scope:[main] from main: scope:[main] from
[20] (byte) main::i ← (byte) 0 [16] phi()
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@2 main::@1: scope:[main] from main main::@2
[21] if((byte) main::i<(byte) 5) goto main::@2 [17] (byte) main::i#2 ← phi( main/(byte) 0 main::@2/(byte) main::i#1 )
[18] if((byte) main::i#2<(byte) 5) goto main::@2
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@1
[22] return [19] return
to:@return to:@return
main::@2: scope:[main] from main::@1 main::@2: scope:[main] from main::@1
[23] stackpush(byte) ← (byte) main::i [20] stackpush(byte) ← (byte) main::i#2
sideeffect stackpushbytes((number) 1) sideeffect stackpushbytes((number) 1)
[25] callexecute get [22] callexecute get
[26] (byte~) main::$1_x ← stackpull(byte) [23] (byte) main::p_x#0 ← stackpull(byte)
[27] (byte~) main::$1_y ← stackpull(byte) [24] (byte) main::p_y#0 ← stackpull(byte)
[28] *((byte*)&(struct Point) main::p) ← (byte~) main::$1_x [25] stackpush(byte) ← (byte) main::p_x#0
[29] *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_y [26] stackpush(byte) ← (byte) main::p_y#0
[30] stackpush(byte) ← *((byte*)&(struct Point) main::p) [27] callexecute print
[31] stackpush(byte) ← *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y)
[32] callexecute print
sideeffect stackpullbytes((number) 2) sideeffect stackpullbytes((number) 2)
[34] (byte) main::i ← ++ (byte) main::i [29] (byte) main::i#1 ← ++ (byte) main::i#2
to:main::@1 to:main::@1

File diff suppressed because it is too large Load Diff

View File

@ -2,31 +2,33 @@
(label) @begin (label) @begin
(label) @end (label) @end
(const byte) OFFSET_STRUCT_POINT_Y = (byte) 1 (const byte) OFFSET_STRUCT_POINT_Y = (byte) 1
(byte) Point::x loadstore (byte) Point::x
(byte) Point::y loadstore (byte) Point::y
(const byte*) SCREEN = (byte*) 1024 (const byte*) SCREEN = (byte*) 1024
(const word) STACK_BASE = (word) $103 (const word) STACK_BASE = (word) $103
__stackcall (struct Point()) get((byte) get::i) __stackcall (struct Point()) get((byte) get::i)
(byte~) get::$0 reg byte a 2.0
(label) get::@return (label) get::@return
(const byte) get::OFFSET_STACK_I = (byte) 0 (const byte) get::OFFSET_STACK_I = (byte) 0
(byte) get::i (byte) get::i
(byte) get::i#0 reg byte x 3.0 (byte) get::p_x
(struct Point) get::p loadstore zp[2]:6 (byte) get::p_y
(struct Point) get::return (struct Point) get::return
(byte) get::return_x (byte) get::return_x
(byte) get::return_x#0 reg byte x 2.0 (byte) get::return_x#0 reg byte x 3.0
(byte) get::return_y (byte) get::return_y
(byte) get::return_y#0 reg byte y 2.0 (byte) get::return_y#0 reg byte y 2.0
(byte) idx loadstore zp[1]:2 0.6086956521739131 (byte) idx loadstore zp[1]:3 0.6363636363636365
__stackcall (void()) main() __stackcall (void()) main()
(byte~) main::$1_x reg byte x 11.0
(byte~) main::$1_y reg byte a 11.0
(label) main::@1 (label) main::@1
(label) main::@2 (label) main::@2
(label) main::@return (label) main::@return
(byte) main::i loadstore zp[1]:3 3.2857142857142856 (byte) main::i
(struct Point) main::p loadstore zp[2]:4 (byte) main::i#1 i zp[1]:2 22.0
(byte) main::i#2 i zp[1]:2 4.0
(byte) main::p_x
(byte) main::p_x#0 reg byte y 11.0
(byte) main::p_y
(byte) main::p_y#0 reg byte x 11.0
__stackcall (void()) print((byte) print::p_x , (byte) print::p_y) __stackcall (void()) print((byte) print::p_x , (byte) print::p_y)
(label) print::@return (label) print::@return
(const byte) print::OFFSET_STACK_P_X = (byte) 1 (const byte) print::OFFSET_STACK_P_X = (byte) 1
@ -36,15 +38,11 @@ __stackcall (void()) print((byte) print::p_x , (byte) print::p_y)
(byte) print::p_y (byte) print::p_y
(byte) print::p_y#0 reg byte x 1.3333333333333333 (byte) print::p_y#0 reg byte x 1.3333333333333333
zp[1]:2 [ idx ] zp[1]:2 [ main::i#2 main::i#1 ]
zp[1]:3 [ idx ]
reg byte y [ print::p_x#0 ] reg byte y [ print::p_x#0 ]
reg byte x [ print::p_y#0 ] reg byte x [ print::p_y#0 ]
reg byte x [ get::i#0 ]
reg byte a [ get::$0 ]
reg byte x [ get::return_x#0 ] reg byte x [ get::return_x#0 ]
reg byte y [ get::return_y#0 ] reg byte y [ get::return_y#0 ]
zp[1]:3 [ main::i ] reg byte y [ main::p_x#0 ]
reg byte x [ main::$1_x ] reg byte x [ main::p_y#0 ]
reg byte a [ main::$1_y ]
zp[2]:4 [ main::p ]
zp[2]:6 [ get::p ]

View File

@ -4,24 +4,24 @@
:BasicUpstart(__bbegin) :BasicUpstart(__bbegin)
.pc = $80d "Program" .pc = $80d "Program"
.label SCREEN = $400 .label SCREEN = $400
.const STACK_BASE = $103
.const OFFSET_STRUCT_POINT_Y = 1 .const OFFSET_STRUCT_POINT_Y = 1
.const OFFSET_STRUCT_VECTOR_P2 = 2 .const OFFSET_STRUCT_VECTOR_P2 = 2
.const STACK_BASE = $103 .label idx = 3
.label idx = 2
__bbegin: __bbegin:
// idx = 0 // idx = 0
lda #0 lda #0
sta.z idx sta.z idx
jsr main jsr main
rts rts
// print(byte register(Y) v_p1_x, byte zp(3) v_p1_y, byte zp(4) v_p2_x, byte register(X) v_p2_y) // print(byte register(Y) v_p1_x, byte zp(4) v_p1_y, byte zp(5) v_p2_x, byte register(X) v_p2_y)
print: { print: {
.const OFFSET_STACK_V_P1_X = 3 .const OFFSET_STACK_V_P1_X = 3
.const OFFSET_STACK_V_P1_Y = 2 .const OFFSET_STACK_V_P1_Y = 2
.const OFFSET_STACK_V_P2_X = 1 .const OFFSET_STACK_V_P2_X = 1
.const OFFSET_STACK_V_P2_Y = 0 .const OFFSET_STACK_V_P2_Y = 0
.label v_p1_y = 3 .label v_p1_y = 4
.label v_p2_x = 4 .label v_p2_x = 5
// } // }
tsx tsx
lda STACK_BASE+OFFSET_STACK_V_P1_X,x lda STACK_BASE+OFFSET_STACK_V_P1_X,x
@ -68,51 +68,33 @@ print: {
// } // }
rts rts
} }
// get(byte register(Y) i)
get: { get: {
.const OFFSET_STACK_I = 0 .const OFFSET_STACK_I = 0
.label __0 = 3 .label return_p1_y = 4
.label __2 = 4 .label return_p2_y = 5
.label v = $10
.label return_p2_x = 6
.label return_p2_y = 7
tsx tsx
lda STACK_BASE+OFFSET_STACK_I,x lda STACK_BASE+OFFSET_STACK_I,x
tay
// i/2
tya
lsr
sta.z __0
// i+1
tya
tax tax
inx // i/2
txa
lsr
sta.z return_p1_y
// i+1
txa
tay
iny
// i*2 // i*2
tya txa
asl asl
sta.z __2
// v = { {i, i/2}, {i+1, i*2} }
sty.z v
lda.z __0
sta v+OFFSET_STRUCT_POINT_Y
stx v+OFFSET_STRUCT_VECTOR_P2
lda.z __2
sta v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y
// return v;
ldx.z v
ldy v+OFFSET_STRUCT_POINT_Y
lda v+OFFSET_STRUCT_VECTOR_P2
sta.z return_p2_x
lda v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y
sta.z return_p2_y sta.z return_p2_y
// } // }
txa txa
tsx tsx
sta STACK_BASE+0,x sta STACK_BASE+0,x
tya lda.z return_p1_y
tsx tsx
sta STACK_BASE+OFFSET_STRUCT_POINT_Y,x sta STACK_BASE+OFFSET_STRUCT_POINT_Y,x
lda.z return_p2_x tya
tsx tsx
sta STACK_BASE+OFFSET_STRUCT_VECTOR_P2,x sta STACK_BASE+OFFSET_STRUCT_VECTOR_P2,x
lda.z return_p2_y lda.z return_p2_y
@ -121,11 +103,9 @@ get: {
rts rts
} }
main: { main: {
.label i = 5 .label v_p2_x = 4
.label v = $c .label v_p2_y = 5
.label __1_p2_x = 6 .label i = 2
.label __1_p2_y = 7
// i=0
lda #0 lda #0
sta.z i sta.z i
__b1: __b1:
@ -143,29 +123,23 @@ main: {
pha pha
pha pha
jsr get jsr get
// v = get(i)
pla pla
tay tay
pla pla
tax tax
pla pla
sta.z __1_p2_x sta.z v_p2_x
pla pla
sta.z __1_p2_y sta.z v_p2_y
// v = get(i)
sty.z v
stx v+OFFSET_STRUCT_POINT_Y
lda.z __1_p2_x
sta v+OFFSET_STRUCT_VECTOR_P2
lda.z __1_p2_y
sta v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y
// print(v) // print(v)
tya tya
pha pha
txa txa
pha pha
lda v+OFFSET_STRUCT_VECTOR_P2 lda.z v_p2_x
pha pha
lda v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y lda.z v_p2_y
pha pha
jsr print jsr print
tsx tsx

View File

@ -31,54 +31,43 @@ print::@return: scope:[print] from print
__stackcall (struct Vector()) get((byte) get::i) __stackcall (struct Vector()) get((byte) get::i)
get: scope:[get] from get: scope:[get] from
[19] (byte) get::i#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I) [19] (byte) get::return_p1_x#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I)
[20] (byte~) get::$0 ← (byte) get::i#0 >> (byte) 1 [20] (byte) get::return_p1_y#0 ← (byte) get::return_p1_x#0 >> (byte) 1
[21] (byte~) get::$1 ← (byte) get::i#0 + (byte) 1 [21] (byte) get::return_p2_x#0 ← (byte) get::return_p1_x#0 + (byte) 1
[22] (byte~) get::$2 ← (byte) get::i#0 << (byte) 1 [22] (byte) get::return_p2_y#0 ← (byte) get::return_p1_x#0 << (byte) 1
[23] *((byte*)(struct Point*)&(struct Vector) get::v) ← (byte) get::i#0
[24] *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) get::$0
[25] *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2) ← (byte~) get::$1
[26] *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) get::$2
[27] (byte) get::return_p1_x#0 ← *((byte*)(struct Point*)&(struct Vector) get::v)
[28] (byte) get::return_p1_y#0 ← *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_POINT_Y)
[29] (byte) get::return_p2_x#0 ← *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2)
[30] (byte) get::return_p2_y#0 ← *((byte*)(struct Point*)&(struct Vector) get::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y)
to:get::@return to:get::@return
get::@return: scope:[get] from get get::@return: scope:[get] from get
[31] stackidx(byte,(byte) 0) ← (byte) get::return_p1_x#0 [23] stackidx(byte,(byte) 0) ← (byte) get::return_p1_x#0
[32] stackidx(byte,(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_p1_y#0 [24] stackidx(byte,(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_p1_y#0
[33] stackidx(byte,(const byte) OFFSET_STRUCT_VECTOR_P2) ← (byte) get::return_p2_x#0 [25] stackidx(byte,(const byte) OFFSET_STRUCT_VECTOR_P2) ← (byte) get::return_p2_x#0
[34] stackidx(byte,(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_p2_y#0 [26] stackidx(byte,(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_p2_y#0
[35] return [27] return
to:@return to:@return
__stackcall (void()) main() __stackcall (void()) main()
main: scope:[main] from main: scope:[main] from
[36] (byte) main::i ← (byte) 0 [28] phi()
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@2 main::@1: scope:[main] from main main::@2
[37] if((byte) main::i<(byte) 5) goto main::@2 [29] (byte) main::i#2 ← phi( main/(byte) 0 main::@2/(byte) main::i#1 )
[30] if((byte) main::i#2<(byte) 5) goto main::@2
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@1
[38] return [31] return
to:@return to:@return
main::@2: scope:[main] from main::@1 main::@2: scope:[main] from main::@1
[39] stackpush(byte) ← (byte) main::i [32] stackpush(byte) ← (byte) main::i#2
sideeffect stackpushbytes((number) 3) sideeffect stackpushbytes((number) 3)
[41] callexecute get [34] callexecute get
[42] (byte~) main::$1_p1_x ← stackpull(byte) [35] (byte) main::v_p1_x#0 ← stackpull(byte)
[43] (byte~) main::$1_p1_y ← stackpull(byte) [36] (byte) main::v_p1_y#0 ← stackpull(byte)
[44] (byte~) main::$1_p2_x ← stackpull(byte) [37] (byte) main::v_p2_x#0 ← stackpull(byte)
[45] (byte~) main::$1_p2_y ← stackpull(byte) [38] (byte) main::v_p2_y#0 ← stackpull(byte)
[46] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte~) main::$1_p1_x [39] stackpush(byte) ← (byte) main::v_p1_x#0
[47] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_p1_y [40] stackpush(byte) ← (byte) main::v_p1_y#0
[48] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2) ← (byte~) main::$1_p2_x [41] stackpush(byte) ← (byte) main::v_p2_x#0
[49] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_p2_y [42] stackpush(byte) ← (byte) main::v_p2_y#0
[50] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v) [43] callexecute print
[51] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y)
[52] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2)
[53] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y)
[54] callexecute print
sideeffect stackpullbytes((number) 4) sideeffect stackpullbytes((number) 4)
[56] (byte) main::i ← ++ (byte) main::i [45] (byte) main::i#1 ← ++ (byte) main::i#2
to:main::@1 to:main::@1

File diff suppressed because it is too large Load Diff

View File

@ -3,43 +3,51 @@
(label) @end (label) @end
(const byte) OFFSET_STRUCT_POINT_Y = (byte) 1 (const byte) OFFSET_STRUCT_POINT_Y = (byte) 1
(const byte) OFFSET_STRUCT_VECTOR_P2 = (byte) 2 (const byte) OFFSET_STRUCT_VECTOR_P2 = (byte) 2
(byte) Point::x loadstore (byte) Point::x
(byte) Point::y loadstore (byte) Point::y
(const byte*) SCREEN = (byte*) 1024 (const byte*) SCREEN = (byte*) 1024
(const word) STACK_BASE = (word) $103 (const word) STACK_BASE = (word) $103
(struct Point) Vector::p1 loadstore zp[2]:8 (struct Point) Vector::p1
(struct Point) Vector::p2 loadstore zp[2]:10 (struct Point) Vector::p2
__stackcall (struct Vector()) get((byte) get::i) __stackcall (struct Vector()) get((byte) get::i)
(byte~) get::$0 zp[1]:3 1.0
(byte~) get::$1 reg byte x 1.0
(byte~) get::$2 zp[1]:4 1.0
(label) get::@return (label) get::@return
(const byte) get::OFFSET_STACK_I = (byte) 0 (const byte) get::OFFSET_STACK_I = (byte) 0
(byte) get::i (byte) get::i
(byte) get::i#0 reg byte y 2.5
(struct Vector) get::return (struct Vector) get::return
(struct Point) get::return_p1 (struct Point) get::return_p1
(byte) get::return_p1_x (byte) get::return_p1_x
(byte) get::return_p1_x#0 reg byte x 1.0 (byte) get::return_p1_x#0 reg byte x 2.5
(byte) get::return_p1_y (byte) get::return_p1_y
(byte) get::return_p1_y#0 reg byte y 1.0 (byte) get::return_p1_y#0 return_p1_y zp[1]:4 1.0
(struct Point) get::return_p2 (struct Point) get::return_p2
(byte) get::return_p2_x (byte) get::return_p2_x
(byte) get::return_p2_x#0 return_p2_x zp[1]:6 1.0 (byte) get::return_p2_x#0 reg byte y 1.0
(byte) get::return_p2_y (byte) get::return_p2_y
(byte) get::return_p2_y#0 return_p2_y zp[1]:7 1.0 (byte) get::return_p2_y#0 return_p2_y zp[1]:5 1.0
(struct Vector) get::v loadstore zp[4]:16 (struct Point) get::v_p1
(byte) idx loadstore zp[1]:2 0.8648648648648649 (byte) get::v_p1_x
(byte) get::v_p1_y
(struct Point) get::v_p2
(byte) get::v_p2_x
(byte) get::v_p2_y
(byte) idx loadstore zp[1]:3 0.9411764705882354
__stackcall (void()) main() __stackcall (void()) main()
(byte~) main::$1_p1_x reg byte y 5.5
(byte~) main::$1_p1_y reg byte x 5.5
(byte~) main::$1_p2_x zp[1]:6 5.5
(byte~) main::$1_p2_y zp[1]:7 5.5
(label) main::@1 (label) main::@1
(label) main::@2 (label) main::@2
(label) main::@return (label) main::@return
(byte) main::i loadstore zp[1]:5 2.3000000000000003 (byte) main::i
(struct Vector) main::v loadstore zp[4]:12 (byte) main::i#1 i zp[1]:2 22.0
(byte) main::i#2 i zp[1]:2 2.933333333333333
(struct Point) main::v_p1
(byte) main::v_p1_x
(byte) main::v_p1_x#0 reg byte y 5.5
(byte) main::v_p1_y
(byte) main::v_p1_y#0 reg byte x 5.5
(struct Point) main::v_p2
(byte) main::v_p2_x
(byte) main::v_p2_x#0 v_p2_x zp[1]:4 5.5
(byte) main::v_p2_y
(byte) main::v_p2_y#0 v_p2_y zp[1]:5 5.5
__stackcall (void()) print((byte) print::v_p1_x , (byte) print::v_p1_y , (byte) print::v_p2_x , (byte) print::v_p2_y) __stackcall (void()) print((byte) print::v_p1_x , (byte) print::v_p1_y , (byte) print::v_p2_x , (byte) print::v_p2_y)
(label) print::@return (label) print::@return
(const byte) print::OFFSET_STACK_V_P1_X = (byte) 3 (const byte) print::OFFSET_STACK_V_P1_X = (byte) 3
@ -50,28 +58,20 @@ __stackcall (void()) print((byte) print::v_p1_x , (byte) print::v_p1_y , (byte)
(byte) print::v_p1_x (byte) print::v_p1_x
(byte) print::v_p1_x#0 reg byte y 1.0 (byte) print::v_p1_x#0 reg byte y 1.0
(byte) print::v_p1_y (byte) print::v_p1_y
(byte) print::v_p1_y#0 v_p1_y zp[1]:3 0.8 (byte) print::v_p1_y#0 v_p1_y zp[1]:4 0.8
(struct Point) print::v_p2 (struct Point) print::v_p2
(byte) print::v_p2_x (byte) print::v_p2_x
(byte) print::v_p2_x#0 v_p2_x zp[1]:4 0.6666666666666666 (byte) print::v_p2_x#0 v_p2_x zp[1]:5 0.6666666666666666
(byte) print::v_p2_y (byte) print::v_p2_y
(byte) print::v_p2_y#0 reg byte x 0.5714285714285714 (byte) print::v_p2_y#0 reg byte x 0.5714285714285714
zp[1]:2 [ idx ] zp[1]:2 [ main::i#2 main::i#1 ]
zp[1]:3 [ idx ]
reg byte y [ print::v_p1_x#0 ] reg byte y [ print::v_p1_x#0 ]
reg byte x [ print::v_p2_y#0 ] reg byte x [ print::v_p2_y#0 ]
reg byte y [ get::i#0 ]
zp[1]:3 [ get::$0 print::v_p1_y#0 ]
reg byte x [ get::$1 ]
zp[1]:4 [ get::$2 print::v_p2_x#0 ]
reg byte x [ get::return_p1_x#0 ] reg byte x [ get::return_p1_x#0 ]
reg byte y [ get::return_p1_y#0 ] reg byte y [ get::return_p2_x#0 ]
zp[1]:5 [ main::i ] reg byte y [ main::v_p1_x#0 ]
reg byte y [ main::$1_p1_x ] reg byte x [ main::v_p1_y#0 ]
reg byte x [ main::$1_p1_y ] zp[1]:4 [ main::v_p2_x#0 get::return_p1_y#0 print::v_p1_y#0 ]
zp[1]:6 [ main::$1_p2_x get::return_p2_x#0 ] zp[1]:5 [ main::v_p2_y#0 get::return_p2_y#0 print::v_p2_x#0 ]
zp[1]:7 [ main::$1_p2_y get::return_p2_y#0 ]
zp[2]:8 [ Vector::p1 ]
zp[2]:10 [ Vector::p2 ]
zp[4]:12 [ main::v ]
zp[4]:16 [ get::v ]

View File

@ -16,7 +16,6 @@ __bbegin:
print: { print: {
.const OFFSET_STACK_STR = 1 .const OFFSET_STACK_STR = 1
.const OFFSET_STACK_SPACING = 0 .const OFFSET_STACK_SPACING = 0
.label c = 6
.label str = 2 .label str = 2
.label spacing = 5 .label spacing = 5
// } // }
@ -48,13 +47,10 @@ print: {
bne !+ bne !+
inc.z str+1 inc.z str+1
!: !:
// c=0 ldx #0
lda #0
sta.z c
__b3: __b3:
// for(char c=0;c<spacing;c++) // for(char c=0;c<spacing;c++)
lda.z c cpx.z spacing
cmp.z spacing
bcc __b4 bcc __b4
jmp __b1 jmp __b1
__b4: __b4:
@ -65,7 +61,7 @@ print: {
// SCREEN[idx++] = ' '; // SCREEN[idx++] = ' ';
inc.z idx inc.z idx
// for(char c=0;c<spacing;c++) // for(char c=0;c<spacing;c++)
inc.z c inx
jmp __b3 jmp __b3
} }
main: { main: {

View File

@ -24,15 +24,15 @@ print::@2: scope:[print] from print::@1
[9] *((const byte*) SCREEN + (byte) idx) ← *((byte*) print::str#2) [9] *((const byte*) SCREEN + (byte) idx) ← *((byte*) print::str#2)
[10] (byte) idx ← ++ (byte) idx [10] (byte) idx ← ++ (byte) idx
[11] (byte*) print::str#1 ← ++ (byte*) print::str#2 [11] (byte*) print::str#1 ← ++ (byte*) print::str#2
[12] (byte) print::c ← (byte) 0
to:print::@3 to:print::@3
print::@3: scope:[print] from print::@2 print::@4 print::@3: scope:[print] from print::@2 print::@4
[13] if((byte) print::c<(byte) print::spacing#0) goto print::@4 [12] (byte) print::c#2 ← phi( print::@2/(byte) 0 print::@4/(byte) print::c#1 )
[13] if((byte) print::c#2<(byte) print::spacing#0) goto print::@4
to:print::@1 to:print::@1
print::@4: scope:[print] from print::@3 print::@4: scope:[print] from print::@3
[14] *((const byte*) SCREEN + (byte) idx) ← (byte) ' ' [14] *((const byte*) SCREEN + (byte) idx) ← (byte) ' '
[15] (byte) idx ← ++ (byte) idx [15] (byte) idx ← ++ (byte) idx
[16] (byte) print::c ← ++ (byte) print::c [16] (byte) print::c#1 ← ++ (byte) print::c#2
to:print::@3 to:print::@3
__stackcall (void()) main() __stackcall (void()) main()

View File

@ -8,6 +8,7 @@ Culled Empty Block (label) print::@6
Culled Empty Block (label) print::@8 Culled Empty Block (label) print::@8
Culled Empty Block (label) print::@9 Culled Empty Block (label) print::@9
Culled Empty Block (label) print::@10 Culled Empty Block (label) print::@10
Converting PHI-variable modified inside __stackcall procedure main() to load/store (byte) idx
Calling convention STACK_CALL adding prepare/execute/finalize for call print (const byte*) main::str (number) 1 Calling convention STACK_CALL adding prepare/execute/finalize for call print (const byte*) main::str (number) 1
Calling convention STACK_CALL adding prepare/execute/finalize for call print (const byte*) main::str1 (number) 2 Calling convention STACK_CALL adding prepare/execute/finalize for call print (const byte*) main::str1 (number) 2
Calling convention STACK_CALL adding prepare/execute/finalize for call main Calling convention STACK_CALL adding prepare/execute/finalize for call main
@ -55,20 +56,22 @@ print::@2: scope:[print] from print::@1
*((const byte*) SCREEN + (byte) idx) ← *((byte*) print::str#3) *((const byte*) SCREEN + (byte) idx) ← *((byte*) print::str#3)
(byte) idx ← ++ (byte) idx (byte) idx ← ++ (byte) idx
(byte*) print::str#1 ← ++ (byte*) print::str#3 (byte*) print::str#1 ← ++ (byte*) print::str#3
(byte) print::c ← (byte) 0 (byte) print::c#0 ← (byte) 0
to:print::@4 to:print::@4
print::@4: scope:[print] from print::@2 print::@5 print::@4: scope:[print] from print::@2 print::@5
(byte*) print::str#4 ← phi( print::@2/(byte*) print::str#1 print::@5/(byte*) print::str#5 ) (byte*) print::str#4 ← phi( print::@2/(byte*) print::str#1 print::@5/(byte*) print::str#5 )
(byte) print::spacing#1 ← phi( print::@2/(byte) print::spacing#2 print::@5/(byte) print::spacing#3 ) (byte) print::spacing#1 ← phi( print::@2/(byte) print::spacing#2 print::@5/(byte) print::spacing#3 )
(bool~) print::$0 ← (byte) print::c < (byte) print::spacing#1 (byte) print::c#2 ← phi( print::@2/(byte) print::c#0 print::@5/(byte) print::c#1 )
(bool~) print::$0 ← (byte) print::c#2 < (byte) print::spacing#1
if((bool~) print::$0) goto print::@5 if((bool~) print::$0) goto print::@5
to:print::@1 to:print::@1
print::@5: scope:[print] from print::@4 print::@5: scope:[print] from print::@4
(byte*) print::str#5 ← phi( print::@4/(byte*) print::str#4 ) (byte*) print::str#5 ← phi( print::@4/(byte*) print::str#4 )
(byte) print::spacing#3 ← phi( print::@4/(byte) print::spacing#1 ) (byte) print::spacing#3 ← phi( print::@4/(byte) print::spacing#1 )
(byte) print::c#3 ← phi( print::@4/(byte) print::c#2 )
*((const byte*) SCREEN + (byte) idx) ← (byte) ' ' *((const byte*) SCREEN + (byte) idx) ← (byte) ' '
(byte) idx ← ++ (byte) idx (byte) idx ← ++ (byte) idx
(byte) print::c ← ++ (byte) print::c (byte) print::c#1 ← ++ (byte) print::c#3
to:print::@4 to:print::@4
print::@return: scope:[print] from print::@1 print::@return: scope:[print] from print::@1
return return
@ -99,7 +102,11 @@ __stackcall (void()) print((byte*) print::str , (byte) print::spacing)
(label) print::@return (label) print::@return
(const byte) print::OFFSET_STACK_SPACING = (byte) 0 (const byte) print::OFFSET_STACK_SPACING = (byte) 0
(const byte) print::OFFSET_STACK_STR = (byte) 1 (const byte) print::OFFSET_STACK_STR = (byte) 1
(byte) print::c loadstore (byte) print::c
(byte) print::c#0
(byte) print::c#1
(byte) print::c#2
(byte) print::c#3
(byte) print::spacing (byte) print::spacing
(byte) print::spacing#0 (byte) print::spacing#0
(byte) print::spacing#1 (byte) print::spacing#1
@ -132,6 +139,7 @@ Finalized unsigned number type (byte) 0
Successful SSA optimization PassNFinalizeNumberTypeConversions Successful SSA optimization PassNFinalizeNumberTypeConversions
Alias (byte*) print::str#2 = (byte*) print::str#3 Alias (byte*) print::str#2 = (byte*) print::str#3
Alias (byte) print::spacing#2 = (byte) print::spacing#4 Alias (byte) print::spacing#2 = (byte) print::spacing#4
Alias (byte) print::c#2 = (byte) print::c#3
Alias (byte) print::spacing#1 = (byte) print::spacing#3 Alias (byte) print::spacing#1 = (byte) print::spacing#3
Alias (byte*) print::str#4 = (byte*) print::str#5 Alias (byte*) print::str#4 = (byte*) print::str#5
Successful SSA optimization Pass2AliasElimination Successful SSA optimization Pass2AliasElimination
@ -141,19 +149,25 @@ Successful SSA optimization Pass2IdenticalPhiElimination
Identical Phi Values (byte) print::spacing#2 (byte) print::spacing#0 Identical Phi Values (byte) print::spacing#2 (byte) print::spacing#0
Successful SSA optimization Pass2IdenticalPhiElimination Successful SSA optimization Pass2IdenticalPhiElimination
Simple Condition (bool~) print::$1 [14] if((byte) 0!=*((byte*) print::str#2)) goto print::@2 Simple Condition (bool~) print::$1 [14] if((byte) 0!=*((byte*) print::str#2)) goto print::@2
Simple Condition (bool~) print::$0 [21] if((byte) print::c<(byte) print::spacing#0) goto print::@5 Simple Condition (bool~) print::$0 [21] if((byte) print::c#2<(byte) print::spacing#0) goto print::@5
Successful SSA optimization Pass2ConditionalJumpSimplification Successful SSA optimization Pass2ConditionalJumpSimplification
Constant (const byte) print::c#0 = 0
Successful SSA optimization Pass2ConstantIdentification
Inlining constant with var siblings (const byte) print::c#0
Constant inlined print::c#0 = (byte) 0
Successful SSA optimization Pass2ConstantInlining
Added new block during phi lifting print::@13(between print::@4 and print::@1) Added new block during phi lifting print::@13(between print::@4 and print::@1)
Adding NOP phi() at start of @2 Adding NOP phi() at start of @2
Adding NOP phi() at start of @end Adding NOP phi() at start of @end
CALL GRAPH CALL GRAPH
Calls in [] to main:2 Calls in [] to main:2
Calls in [main] to print:21 print:25 Calls in [main] to print:22 print:26
Created 1 initial phi equivalence classes Created 2 initial phi equivalence classes
Coalesced [6] print::str#6 ← print::str#0 Coalesced [6] print::str#6 ← print::str#0
Coalesced [15] print::str#7 ← print::str#1 Coalesced [15] print::str#7 ← print::str#1
Coalesced down to 1 phi equivalence classes Coalesced [19] print::c#4 ← print::c#1
Coalesced down to 2 phi equivalence classes
Culled Empty Block (label) print::@13 Culled Empty Block (label) print::@13
Renumbering block @2 to @1 Renumbering block @2 to @1
Renumbering block print::@4 to print::@3 Renumbering block print::@4 to print::@3
@ -188,15 +202,15 @@ print::@2: scope:[print] from print::@1
[9] *((const byte*) SCREEN + (byte) idx) ← *((byte*) print::str#2) [9] *((const byte*) SCREEN + (byte) idx) ← *((byte*) print::str#2)
[10] (byte) idx ← ++ (byte) idx [10] (byte) idx ← ++ (byte) idx
[11] (byte*) print::str#1 ← ++ (byte*) print::str#2 [11] (byte*) print::str#1 ← ++ (byte*) print::str#2
[12] (byte) print::c ← (byte) 0
to:print::@3 to:print::@3
print::@3: scope:[print] from print::@2 print::@4 print::@3: scope:[print] from print::@2 print::@4
[13] if((byte) print::c<(byte) print::spacing#0) goto print::@4 [12] (byte) print::c#2 ← phi( print::@2/(byte) 0 print::@4/(byte) print::c#1 )
[13] if((byte) print::c#2<(byte) print::spacing#0) goto print::@4
to:print::@1 to:print::@1
print::@4: scope:[print] from print::@3 print::@4: scope:[print] from print::@3
[14] *((const byte*) SCREEN + (byte) idx) ← (byte) ' ' [14] *((const byte*) SCREEN + (byte) idx) ← (byte) ' '
[15] (byte) idx ← ++ (byte) idx [15] (byte) idx ← ++ (byte) idx
[16] (byte) print::c ← ++ (byte) print::c [16] (byte) print::c#1 ← ++ (byte) print::c#2
to:print::@3 to:print::@3
__stackcall (void()) main() __stackcall (void()) main()
@ -219,7 +233,9 @@ VARIABLE REGISTER WEIGHTS
(byte) idx loadstore 16.095238095238095 (byte) idx loadstore 16.095238095238095
__stackcall (void()) main() __stackcall (void()) main()
__stackcall (void()) print((byte*) print::str , (byte) print::spacing) __stackcall (void()) print((byte*) print::str , (byte) print::spacing)
(byte) print::c loadstore 62.8 (byte) print::c
(byte) print::c#1 202.0
(byte) print::c#2 75.75
(byte) print::spacing (byte) print::spacing
(byte) print::spacing#0 9.363636363636363 (byte) print::spacing#0 9.363636363636363
(byte*) print::str (byte*) print::str
@ -229,18 +245,18 @@ __stackcall (void()) print((byte*) print::str , (byte) print::spacing)
Initial phi equivalence classes Initial phi equivalence classes
[ print::str#2 print::str#0 print::str#1 ] [ print::str#2 print::str#0 print::str#1 ]
[ print::c#2 print::c#1 ]
Added variable idx to live range equivalence class [ idx ] Added variable idx to live range equivalence class [ idx ]
Added variable print::spacing#0 to live range equivalence class [ print::spacing#0 ] Added variable print::spacing#0 to live range equivalence class [ print::spacing#0 ]
Added variable print::c to live range equivalence class [ print::c ]
Complete equivalence classes Complete equivalence classes
[ print::str#2 print::str#0 print::str#1 ] [ print::str#2 print::str#0 print::str#1 ]
[ print::c#2 print::c#1 ]
[ idx ] [ idx ]
[ print::spacing#0 ] [ print::spacing#0 ]
[ print::c ]
Allocated zp[2]:2 [ print::str#2 print::str#0 print::str#1 ] Allocated zp[2]:2 [ print::str#2 print::str#0 print::str#1 ]
Allocated zp[1]:4 [ idx ] Allocated zp[1]:4 [ print::c#2 print::c#1 ]
Allocated zp[1]:5 [ print::spacing#0 ] Allocated zp[1]:5 [ idx ]
Allocated zp[1]:6 [ print::c ] Allocated zp[1]:6 [ print::spacing#0 ]
INITIAL ASM INITIAL ASM
Target platform is c64basic / MOS6502X Target platform is c64basic / MOS6502X
@ -254,7 +270,7 @@ Target platform is c64basic / MOS6502X
// Global Constants & labels // Global Constants & labels
.label SCREEN = $400 .label SCREEN = $400
.const STACK_BASE = $103 .const STACK_BASE = $103
.label idx = 4 .label idx = 5
// @begin // @begin
__bbegin: __bbegin:
// [0] (byte) idx ← (byte) 0 -- vbuz1=vbuc1 // [0] (byte) idx ← (byte) 0 -- vbuz1=vbuc1
@ -273,13 +289,13 @@ __bend_from___b1:
// @end // @end
__bend: __bend:
// print // print
// print(byte* zp(2) str, byte zp(5) spacing) // print(byte* zp(2) str, byte zp(6) spacing)
print: { print: {
.const OFFSET_STACK_STR = 1 .const OFFSET_STACK_STR = 1
.const OFFSET_STACK_SPACING = 0 .const OFFSET_STACK_SPACING = 0
.label c = 6
.label str = 2 .label str = 2
.label spacing = 5 .label spacing = 6
.label c = 4
// [4] (byte*) print::str#0 ← stackidx(byte*,(const byte) print::OFFSET_STACK_STR) -- pbuz1=_stackidxptr_vbuc1 // [4] (byte*) print::str#0 ← stackidx(byte*,(const byte) print::OFFSET_STACK_STR) -- pbuz1=_stackidxptr_vbuc1
tsx tsx
lda STACK_BASE+OFFSET_STACK_STR,x lda STACK_BASE+OFFSET_STACK_STR,x
@ -321,13 +337,15 @@ print: {
bne !+ bne !+
inc.z str+1 inc.z str+1
!: !:
// [12] (byte) print::c ← (byte) 0 -- vbuz1=vbuc1 // [12] phi from print::@2 to print::@3 [phi:print::@2->print::@3]
__b3_from___b2:
// [12] phi (byte) print::c#2 = (byte) 0 [phi:print::@2->print::@3#0] -- vbuz1=vbuc1
lda #0 lda #0
sta.z c sta.z c
jmp __b3 jmp __b3
// print::@3 // print::@3
__b3: __b3:
// [13] if((byte) print::c<(byte) print::spacing#0) goto print::@4 -- vbuz1_lt_vbuz2_then_la1 // [13] if((byte) print::c#2<(byte) print::spacing#0) goto print::@4 -- vbuz1_lt_vbuz2_then_la1
lda.z c lda.z c
cmp.z spacing cmp.z spacing
bcc __b4 bcc __b4
@ -340,8 +358,11 @@ print: {
sta SCREEN,y sta SCREEN,y
// [15] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1 // [15] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1
inc.z idx inc.z idx
// [16] (byte) print::c ← ++ (byte) print::c -- vbuz1=_inc_vbuz1 // [16] (byte) print::c#1 ← ++ (byte) print::c#2 -- vbuz1=_inc_vbuz1
inc.z c inc.z c
// [12] phi from print::@4 to print::@3 [phi:print::@4->print::@3]
__b3_from___b4:
// [12] phi (byte) print::c#2 = (byte) print::c#1 [phi:print::@4->print::@3#0] -- register_copy
jmp __b3 jmp __b3
} }
// main // main
@ -395,13 +416,13 @@ Statement [0] (byte) idx ← (byte) 0 [ idx ] ( [ idx ] ) always clobbers reg b
Statement [4] (byte*) print::str#0 ← stackidx(byte*,(const byte) print::OFFSET_STACK_STR) [ idx print::str#0 ] ( main:2::print:19 [ idx print::str#0 ] main:2::print:23 [ idx print::str#0 ] ) always clobbers reg byte a reg byte x Statement [4] (byte*) print::str#0 ← stackidx(byte*,(const byte) print::OFFSET_STACK_STR) [ idx print::str#0 ] ( main:2::print:19 [ idx print::str#0 ] main:2::print:23 [ idx print::str#0 ] ) always clobbers reg byte a reg byte x
Statement [5] (byte) print::spacing#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_SPACING) [ idx print::str#0 print::spacing#0 ] ( main:2::print:19 [ idx print::str#0 print::spacing#0 ] main:2::print:23 [ idx print::str#0 print::spacing#0 ] ) always clobbers reg byte a reg byte x Statement [5] (byte) print::spacing#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_SPACING) [ idx print::str#0 print::spacing#0 ] ( main:2::print:19 [ idx print::str#0 print::spacing#0 ] main:2::print:23 [ idx print::str#0 print::spacing#0 ] ) always clobbers reg byte a reg byte x
Statement [7] if((byte) 0!=*((byte*) print::str#2)) goto print::@2 [ idx print::spacing#0 print::str#2 ] ( main:2::print:19 [ idx print::spacing#0 print::str#2 ] main:2::print:23 [ idx print::spacing#0 print::str#2 ] ) always clobbers reg byte a reg byte y Statement [7] if((byte) 0!=*((byte*) print::str#2)) goto print::@2 [ idx print::spacing#0 print::str#2 ] ( main:2::print:19 [ idx print::spacing#0 print::str#2 ] main:2::print:23 [ idx print::spacing#0 print::str#2 ] ) always clobbers reg byte a reg byte y
Removing always clobbered register reg byte a as potential for zp[1]:5 [ print::spacing#0 ] Removing always clobbered register reg byte a as potential for zp[1]:6 [ print::spacing#0 ]
Removing always clobbered register reg byte y as potential for zp[1]:5 [ print::spacing#0 ] Removing always clobbered register reg byte y as potential for zp[1]:6 [ print::spacing#0 ]
Statement [9] *((const byte*) SCREEN + (byte) idx) ← *((byte*) print::str#2) [ idx print::spacing#0 print::str#2 ] ( main:2::print:19 [ idx print::spacing#0 print::str#2 ] main:2::print:23 [ idx print::spacing#0 print::str#2 ] ) always clobbers reg byte a reg byte x reg byte y Statement [9] *((const byte*) SCREEN + (byte) idx) ← *((byte*) print::str#2) [ idx print::spacing#0 print::str#2 ] ( main:2::print:19 [ idx print::spacing#0 print::str#2 ] main:2::print:23 [ idx print::spacing#0 print::str#2 ] ) always clobbers reg byte a reg byte x reg byte y
Removing always clobbered register reg byte x as potential for zp[1]:5 [ print::spacing#0 ] Removing always clobbered register reg byte x as potential for zp[1]:6 [ print::spacing#0 ]
Statement [12] (byte) print::c ← (byte) 0 [ idx print::spacing#0 print::str#1 print::c ] ( main:2::print:19 [ idx print::spacing#0 print::str#1 print::c ] main:2::print:23 [ idx print::spacing#0 print::str#1 print::c ] ) always clobbers reg byte a Statement [14] *((const byte*) SCREEN + (byte) idx) ← (byte) ' ' [ idx print::spacing#0 print::str#1 print::c#2 ] ( main:2::print:19 [ idx print::spacing#0 print::str#1 print::c#2 ] main:2::print:23 [ idx print::spacing#0 print::str#1 print::c#2 ] ) always clobbers reg byte a reg byte y
Statement [13] if((byte) print::c<(byte) print::spacing#0) goto print::@4 [ idx print::spacing#0 print::str#1 print::c ] ( main:2::print:19 [ idx print::spacing#0 print::str#1 print::c ] main:2::print:23 [ idx print::spacing#0 print::str#1 print::c ] ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:4 [ print::c#2 print::c#1 ]
Statement [14] *((const byte*) SCREEN + (byte) idx) ← (byte) ' ' [ idx print::spacing#0 print::str#1 print::c ] ( main:2::print:19 [ idx print::spacing#0 print::str#1 print::c ] main:2::print:23 [ idx print::spacing#0 print::str#1 print::c ] ) always clobbers reg byte a reg byte y Removing always clobbered register reg byte y as potential for zp[1]:4 [ print::c#2 print::c#1 ]
Statement [17] stackpush(byte*) ← (const byte*) main::str [ idx ] ( main:2 [ idx ] ) always clobbers reg byte a Statement [17] stackpush(byte*) ← (const byte*) main::str [ idx ] ( main:2 [ idx ] ) always clobbers reg byte a
Statement [18] stackpush(byte) ← (byte) 1 [ idx ] ( main:2 [ idx ] ) always clobbers reg byte a Statement [18] stackpush(byte) ← (byte) 1 [ idx ] ( main:2 [ idx ] ) always clobbers reg byte a
Statement sideeffect stackpullbytes((number) 3) always clobbers reg byte a reg byte x Statement sideeffect stackpullbytes((number) 3) always clobbers reg byte a reg byte x
@ -413,9 +434,7 @@ Statement [4] (byte*) print::str#0 ← stackidx(byte*,(const byte) print::OFFSET
Statement [5] (byte) print::spacing#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_SPACING) [ idx print::str#0 print::spacing#0 ] ( main:2::print:19 [ idx print::str#0 print::spacing#0 ] main:2::print:23 [ idx print::str#0 print::spacing#0 ] ) always clobbers reg byte a reg byte x Statement [5] (byte) print::spacing#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_SPACING) [ idx print::str#0 print::spacing#0 ] ( main:2::print:19 [ idx print::str#0 print::spacing#0 ] main:2::print:23 [ idx print::str#0 print::spacing#0 ] ) always clobbers reg byte a reg byte x
Statement [7] if((byte) 0!=*((byte*) print::str#2)) goto print::@2 [ idx print::spacing#0 print::str#2 ] ( main:2::print:19 [ idx print::spacing#0 print::str#2 ] main:2::print:23 [ idx print::spacing#0 print::str#2 ] ) always clobbers reg byte a reg byte y Statement [7] if((byte) 0!=*((byte*) print::str#2)) goto print::@2 [ idx print::spacing#0 print::str#2 ] ( main:2::print:19 [ idx print::spacing#0 print::str#2 ] main:2::print:23 [ idx print::spacing#0 print::str#2 ] ) always clobbers reg byte a reg byte y
Statement [9] *((const byte*) SCREEN + (byte) idx) ← *((byte*) print::str#2) [ idx print::spacing#0 print::str#2 ] ( main:2::print:19 [ idx print::spacing#0 print::str#2 ] main:2::print:23 [ idx print::spacing#0 print::str#2 ] ) always clobbers reg byte a reg byte x reg byte y Statement [9] *((const byte*) SCREEN + (byte) idx) ← *((byte*) print::str#2) [ idx print::spacing#0 print::str#2 ] ( main:2::print:19 [ idx print::spacing#0 print::str#2 ] main:2::print:23 [ idx print::spacing#0 print::str#2 ] ) always clobbers reg byte a reg byte x reg byte y
Statement [12] (byte) print::c ← (byte) 0 [ idx print::spacing#0 print::str#1 print::c ] ( main:2::print:19 [ idx print::spacing#0 print::str#1 print::c ] main:2::print:23 [ idx print::spacing#0 print::str#1 print::c ] ) always clobbers reg byte a Statement [14] *((const byte*) SCREEN + (byte) idx) ← (byte) ' ' [ idx print::spacing#0 print::str#1 print::c#2 ] ( main:2::print:19 [ idx print::spacing#0 print::str#1 print::c#2 ] main:2::print:23 [ idx print::spacing#0 print::str#1 print::c#2 ] ) always clobbers reg byte a reg byte y
Statement [13] if((byte) print::c<(byte) print::spacing#0) goto print::@4 [ idx print::spacing#0 print::str#1 print::c ] ( main:2::print:19 [ idx print::spacing#0 print::str#1 print::c ] main:2::print:23 [ idx print::spacing#0 print::str#1 print::c ] ) always clobbers reg byte a
Statement [14] *((const byte*) SCREEN + (byte) idx) ← (byte) ' ' [ idx print::spacing#0 print::str#1 print::c ] ( main:2::print:19 [ idx print::spacing#0 print::str#1 print::c ] main:2::print:23 [ idx print::spacing#0 print::str#1 print::c ] ) always clobbers reg byte a reg byte y
Statement [17] stackpush(byte*) ← (const byte*) main::str [ idx ] ( main:2 [ idx ] ) always clobbers reg byte a Statement [17] stackpush(byte*) ← (const byte*) main::str [ idx ] ( main:2 [ idx ] ) always clobbers reg byte a
Statement [18] stackpush(byte) ← (byte) 1 [ idx ] ( main:2 [ idx ] ) always clobbers reg byte a Statement [18] stackpush(byte) ← (byte) 1 [ idx ] ( main:2 [ idx ] ) always clobbers reg byte a
Statement sideeffect stackpullbytes((number) 3) always clobbers reg byte a reg byte x Statement sideeffect stackpullbytes((number) 3) always clobbers reg byte a reg byte x
@ -423,24 +442,24 @@ Statement [21] stackpush(byte*) ← (const byte*) main::str1 [ idx ] ( main:2 [
Statement [22] stackpush(byte) ← (byte) 2 [ idx ] ( main:2 [ idx ] ) always clobbers reg byte a Statement [22] stackpush(byte) ← (byte) 2 [ idx ] ( main:2 [ idx ] ) always clobbers reg byte a
Statement sideeffect stackpullbytes((number) 3) always clobbers reg byte a reg byte x Statement sideeffect stackpullbytes((number) 3) always clobbers reg byte a reg byte x
Potential registers zp[2]:2 [ print::str#2 print::str#0 print::str#1 ] : zp[2]:2 , Potential registers zp[2]:2 [ print::str#2 print::str#0 print::str#1 ] : zp[2]:2 ,
Potential registers zp[1]:4 [ idx ] : zp[1]:4 , Potential registers zp[1]:4 [ print::c#2 print::c#1 ] : zp[1]:4 , reg byte x ,
Potential registers zp[1]:5 [ print::spacing#0 ] : zp[1]:5 , Potential registers zp[1]:5 [ idx ] : zp[1]:5 ,
Potential registers zp[1]:6 [ print::c ] : zp[1]:6 , Potential registers zp[1]:6 [ print::spacing#0 ] : zp[1]:6 ,
REGISTER UPLIFT SCOPES REGISTER UPLIFT SCOPES
Uplift Scope [print] 62.8: zp[1]:6 [ print::c ] 54.67: zp[2]:2 [ print::str#2 print::str#0 print::str#1 ] 9.36: zp[1]:5 [ print::spacing#0 ] Uplift Scope [print] 277.75: zp[1]:4 [ print::c#2 print::c#1 ] 54.67: zp[2]:2 [ print::str#2 print::str#0 print::str#1 ] 9.36: zp[1]:6 [ print::spacing#0 ]
Uplift Scope [] 16.1: zp[1]:4 [ idx ] Uplift Scope [] 16.1: zp[1]:5 [ idx ]
Uplift Scope [main] Uplift Scope [main]
Uplifting [print] best 4156 combination zp[1]:6 [ print::c ] zp[2]:2 [ print::str#2 print::str#0 print::str#1 ] zp[1]:5 [ print::spacing#0 ] Uplifting [print] best 3976 combination reg byte x [ print::c#2 print::c#1 ] zp[2]:2 [ print::str#2 print::str#0 print::str#1 ] zp[1]:6 [ print::spacing#0 ]
Uplifting [] best 4156 combination zp[1]:4 [ idx ] Uplifting [] best 3976 combination zp[1]:5 [ idx ]
Uplifting [main] best 4156 combination Uplifting [main] best 3976 combination
Attempting to uplift remaining variables inzp[1]:6 [ print::c ] Attempting to uplift remaining variables inzp[1]:5 [ idx ]
Uplifting [print] best 4156 combination zp[1]:6 [ print::c ] Uplifting [] best 3976 combination zp[1]:5 [ idx ]
Attempting to uplift remaining variables inzp[1]:4 [ idx ] Attempting to uplift remaining variables inzp[1]:6 [ print::spacing#0 ]
Uplifting [] best 4156 combination zp[1]:4 [ idx ] Uplifting [print] best 3976 combination zp[1]:6 [ print::spacing#0 ]
Attempting to uplift remaining variables inzp[1]:5 [ print::spacing#0 ] Allocated (was zp[1]:5) zp[1]:4 [ idx ]
Uplifting [print] best 4156 combination zp[1]:5 [ print::spacing#0 ] Allocated (was zp[1]:6) zp[1]:5 [ print::spacing#0 ]
ASSEMBLER BEFORE OPTIMIZATION ASSEMBLER BEFORE OPTIMIZATION
// File Comments // File Comments
@ -476,7 +495,6 @@ __bend:
print: { print: {
.const OFFSET_STACK_STR = 1 .const OFFSET_STACK_STR = 1
.const OFFSET_STACK_SPACING = 0 .const OFFSET_STACK_SPACING = 0
.label c = 6
.label str = 2 .label str = 2
.label spacing = 5 .label spacing = 5
// [4] (byte*) print::str#0 ← stackidx(byte*,(const byte) print::OFFSET_STACK_STR) -- pbuz1=_stackidxptr_vbuc1 // [4] (byte*) print::str#0 ← stackidx(byte*,(const byte) print::OFFSET_STACK_STR) -- pbuz1=_stackidxptr_vbuc1
@ -520,15 +538,15 @@ print: {
bne !+ bne !+
inc.z str+1 inc.z str+1
!: !:
// [12] (byte) print::c ← (byte) 0 -- vbuz1=vbuc1 // [12] phi from print::@2 to print::@3 [phi:print::@2->print::@3]
lda #0 __b3_from___b2:
sta.z c // [12] phi (byte) print::c#2 = (byte) 0 [phi:print::@2->print::@3#0] -- vbuxx=vbuc1
ldx #0
jmp __b3 jmp __b3
// print::@3 // print::@3
__b3: __b3:
// [13] if((byte) print::c<(byte) print::spacing#0) goto print::@4 -- vbuz1_lt_vbuz2_then_la1 // [13] if((byte) print::c#2<(byte) print::spacing#0) goto print::@4 -- vbuxx_lt_vbuz1_then_la1
lda.z c cpx.z spacing
cmp.z spacing
bcc __b4 bcc __b4
jmp __b1_from___b3 jmp __b1_from___b3
// print::@4 // print::@4
@ -539,8 +557,11 @@ print: {
sta SCREEN,y sta SCREEN,y
// [15] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1 // [15] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1
inc.z idx inc.z idx
// [16] (byte) print::c ← ++ (byte) print::c -- vbuz1=_inc_vbuz1 // [16] (byte) print::c#1 ← ++ (byte) print::c#2 -- vbuxx=_inc_vbuxx
inc.z c inx
// [12] phi from print::@4 to print::@3 [phi:print::@4->print::@3]
__b3_from___b4:
// [12] phi (byte) print::c#2 = (byte) print::c#1 [phi:print::@4->print::@3#0] -- register_copy
jmp __b3 jmp __b3
} }
// main // main
@ -606,6 +627,8 @@ Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __b1: Removing instruction __b1:
Removing instruction __bend: Removing instruction __bend:
Removing instruction __breturn: Removing instruction __breturn:
Removing instruction __b3_from___b2:
Removing instruction __b3_from___b4:
Removing instruction __breturn: Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination Succesful ASM optimization Pass5UnusedLabelElimination
Adding RTS to root block Adding RTS to root block
@ -630,7 +653,9 @@ __stackcall (void()) print((byte*) print::str , (byte) print::spacing)
(label) print::@return (label) print::@return
(const byte) print::OFFSET_STACK_SPACING = (byte) 0 (const byte) print::OFFSET_STACK_SPACING = (byte) 0
(const byte) print::OFFSET_STACK_STR = (byte) 1 (const byte) print::OFFSET_STACK_STR = (byte) 1
(byte) print::c loadstore zp[1]:6 62.8 (byte) print::c
(byte) print::c#1 reg byte x 202.0
(byte) print::c#2 reg byte x 75.75
(byte) print::spacing (byte) print::spacing
(byte) print::spacing#0 spacing zp[1]:5 9.363636363636363 (byte) print::spacing#0 spacing zp[1]:5 9.363636363636363
(byte*) print::str (byte*) print::str
@ -639,13 +664,13 @@ __stackcall (void()) print((byte*) print::str , (byte) print::spacing)
(byte*) print::str#2 str zp[2]:2 34.0 (byte*) print::str#2 str zp[2]:2 34.0
zp[2]:2 [ print::str#2 print::str#0 print::str#1 ] zp[2]:2 [ print::str#2 print::str#0 print::str#1 ]
reg byte x [ print::c#2 print::c#1 ]
zp[1]:4 [ idx ] zp[1]:4 [ idx ]
zp[1]:5 [ print::spacing#0 ] zp[1]:5 [ print::spacing#0 ]
zp[1]:6 [ print::c ]
FINAL ASSEMBLER FINAL ASSEMBLER
Score: 4063 Score: 3613
// File Comments // File Comments
// Test a procedure with calling convention stack // Test a procedure with calling convention stack
@ -676,7 +701,6 @@ __bbegin:
print: { print: {
.const OFFSET_STACK_STR = 1 .const OFFSET_STACK_STR = 1
.const OFFSET_STACK_SPACING = 0 .const OFFSET_STACK_SPACING = 0
.label c = 6
.label str = 2 .label str = 2
.label spacing = 5 .label spacing = 5
// } // }
@ -720,16 +744,14 @@ print: {
bne !+ bne !+
inc.z str+1 inc.z str+1
!: !:
// c=0 // [12] phi from print::@2 to print::@3 [phi:print::@2->print::@3]
// [12] (byte) print::c ← (byte) 0 -- vbuz1=vbuc1 // [12] phi (byte) print::c#2 = (byte) 0 [phi:print::@2->print::@3#0] -- vbuxx=vbuc1
lda #0 ldx #0
sta.z c
// print::@3 // print::@3
__b3: __b3:
// for(char c=0;c<spacing;c++) // for(char c=0;c<spacing;c++)
// [13] if((byte) print::c<(byte) print::spacing#0) goto print::@4 -- vbuz1_lt_vbuz2_then_la1 // [13] if((byte) print::c#2<(byte) print::spacing#0) goto print::@4 -- vbuxx_lt_vbuz1_then_la1
lda.z c cpx.z spacing
cmp.z spacing
bcc __b4 bcc __b4
jmp __b1 jmp __b1
// print::@4 // print::@4
@ -743,8 +765,10 @@ print: {
// [15] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1 // [15] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1
inc.z idx inc.z idx
// for(char c=0;c<spacing;c++) // for(char c=0;c<spacing;c++)
// [16] (byte) print::c ← ++ (byte) print::c -- vbuz1=_inc_vbuz1 // [16] (byte) print::c#1 ← ++ (byte) print::c#2 -- vbuxx=_inc_vbuxx
inc.z c inx
// [12] phi from print::@4 to print::@3 [phi:print::@4->print::@3]
// [12] phi (byte) print::c#2 = (byte) print::c#1 [phi:print::@4->print::@3#0] -- register_copy
jmp __b3 jmp __b3
} }
// main // main

View File

@ -16,7 +16,9 @@ __stackcall (void()) print((byte*) print::str , (byte) print::spacing)
(label) print::@return (label) print::@return
(const byte) print::OFFSET_STACK_SPACING = (byte) 0 (const byte) print::OFFSET_STACK_SPACING = (byte) 0
(const byte) print::OFFSET_STACK_STR = (byte) 1 (const byte) print::OFFSET_STACK_STR = (byte) 1
(byte) print::c loadstore zp[1]:6 62.8 (byte) print::c
(byte) print::c#1 reg byte x 202.0
(byte) print::c#2 reg byte x 75.75
(byte) print::spacing (byte) print::spacing
(byte) print::spacing#0 spacing zp[1]:5 9.363636363636363 (byte) print::spacing#0 spacing zp[1]:5 9.363636363636363
(byte*) print::str (byte*) print::str
@ -25,6 +27,6 @@ __stackcall (void()) print((byte*) print::str , (byte) print::spacing)
(byte*) print::str#2 str zp[2]:2 34.0 (byte*) print::str#2 str zp[2]:2 34.0
zp[2]:2 [ print::str#2 print::str#0 print::str#1 ] zp[2]:2 [ print::str#2 print::str#0 print::str#1 ]
reg byte x [ print::c#2 print::c#1 ]
zp[1]:4 [ idx ] zp[1]:4 [ idx ]
zp[1]:5 [ print::spacing#0 ] zp[1]:5 [ print::spacing#0 ]
zp[1]:6 [ print::c ]

View File

@ -1,16 +1,24 @@
// Test a procedure with calling convention stack // Test a procedure with calling convention stack
// A slightly more complex call // A slightly more complex call
.pc = $801 "Basic" .pc = $801 "Basic"
:BasicUpstart(main) :BasicUpstart(__bbegin)
.pc = $80d "Program" .pc = $80d "Program"
.label SCREEN = $400 .label SCREEN = $400
.const STACK_BASE = $103 .const STACK_BASE = $103
.label i = 3
__bbegin:
// i = 0
lda #0
sta.z i
jsr main
rts
main: { main: {
ldy #0 .label a = 2
lda #0
sta.z a
__b1: __b1:
// v = a+1 // v = a+1
tya ldx.z a
tax
inx inx
// plus('0', v) // plus('0', v)
lda #'0' lda #'0'
@ -22,29 +30,32 @@ main: {
// w = plus('0', v) // w = plus('0', v)
pla pla
// w+a // w+a
sty.z $ff
clc clc
adc.z $ff adc.z a
// SCREEN[i] = w+a // SCREEN[i] = w+a
sta SCREEN ldy.z i
sta SCREEN,y
// for(char a:0..1) // for(char a:0..1)
iny inc.z a
cpy #2 lda #2
cmp.z a
bne __b1 bne __b1
// } // }
rts rts
} }
// plus(byte zp(2) a, byte register(A) b) // plus(byte zp(4) a, byte register(A) b)
plus: { plus: {
.const OFFSET_STACK_A = 1 .const OFFSET_STACK_A = 1
.const OFFSET_STACK_B = 0 .const OFFSET_STACK_B = 0
.const OFFSET_STACK_RETURN = 1 .const OFFSET_STACK_RETURN = 1
.label a = 2 .label a = 4
tsx tsx
lda STACK_BASE+OFFSET_STACK_A,x lda STACK_BASE+OFFSET_STACK_A,x
sta.z a sta.z a
tsx tsx
lda STACK_BASE+OFFSET_STACK_B,x lda STACK_BASE+OFFSET_STACK_B,x
// i++;
inc.z i
// return a+b; // return a+b;
clc clc
adc.z a adc.z a

View File

@ -1,5 +1,5 @@
@begin: scope:[] from @begin: scope:[] from
[0] phi() [0] (byte) i ← (byte) 0
to:@1 to:@1
@1: scope:[] from @begin @1: scope:[] from @begin
[1] phi() [1] phi()
@ -21,7 +21,7 @@ main::@1: scope:[main] from main main::@1
sideeffect stackpullbytes((number) 1) sideeffect stackpullbytes((number) 1)
[11] (byte) main::w#0 ← stackpull(byte) [11] (byte) main::w#0 ← stackpull(byte)
[12] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 [12] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2
[13] *((const byte*) SCREEN) ← (byte~) main::$2 [13] *((const byte*) SCREEN + (byte) i) ← (byte~) main::$2
[14] (byte) main::a#1 ← ++ (byte) main::a#2 [14] (byte) main::a#1 ← ++ (byte) main::a#2
[15] if((byte) main::a#1!=(byte) 2) goto main::@1 [15] if((byte) main::a#1!=(byte) 2) goto main::@1
to:main::@return to:main::@return
@ -33,9 +33,10 @@ __stackcall (byte()) plus((byte) plus::a , (byte) plus::b)
plus: scope:[plus] from plus: scope:[plus] from
[17] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) [17] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A)
[18] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) [18] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B)
[19] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 [19] (byte) i ← ++ (byte) i
[20] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus
[20] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 [21] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0
[21] return [22] return
to:@return to:@return

View File

@ -1,6 +1,7 @@
Culled Empty Block (label) main::@2 Culled Empty Block (label) main::@2
Culled Empty Block (label) @1 Culled Empty Block (label) @1
Culled Empty Block (label) plus::@1 Culled Empty Block (label) plus::@1
Converting PHI-variable modified inside __stackcall procedure plus() to load/store (byte) i
Calling convention STACK_CALL adding prepare/execute/finalize for (byte~) main::$1 ← call plus (byte) '0' (byte) main::v Calling convention STACK_CALL adding prepare/execute/finalize for (byte~) main::$1 ← call plus (byte) '0' (byte) main::v
Calling convention STACK_CALL replacing param((byte) plus::a) with stackidx(byte,(const byte) plus::OFFSET_STACK_A) Calling convention STACK_CALL replacing param((byte) plus::a) with stackidx(byte,(const byte) plus::OFFSET_STACK_A)
Calling convention STACK_CALL replacing param((byte) plus::b) with stackidx(byte,(const byte) plus::OFFSET_STACK_B) Calling convention STACK_CALL replacing param((byte) plus::b) with stackidx(byte,(const byte) plus::OFFSET_STACK_B)
@ -11,16 +12,14 @@ Calling convention STACK_CALL adding stack push stackpush(byte) ← main::v
CONTROL FLOW GRAPH SSA CONTROL FLOW GRAPH SSA
@begin: scope:[] from @begin: scope:[] from
(byte) i#0 ← (byte) 0 (byte) i ← (byte) 0
to:@2 to:@2
(void()) main() (void()) main()
main: scope:[main] from @2 main: scope:[main] from @2
(byte) i#8 ← phi( @2/(byte) i#9 )
(byte) main::a#0 ← (byte) 0 (byte) main::a#0 ← (byte) 0
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1 main::@1: scope:[main] from main main::@1
(byte) i#4 ← phi( main/(byte) i#8 main::@1/(byte) i#4 )
(byte) main::a#2 ← phi( main/(byte) main::a#0 main::@1/(byte) main::a#1 ) (byte) main::a#2 ← phi( main/(byte) main::a#0 main::@1/(byte) main::a#1 )
(number~) main::$0 ← (byte) main::a#2 + (number) 1 (number~) main::$0 ← (byte) main::a#2 + (number) 1
(byte) main::v#0 ← (number~) main::$0 (byte) main::v#0 ← (number~) main::$0
@ -31,23 +30,20 @@ main::@1: scope:[main] from main main::@1
(byte~) main::$1 ← stackpull(byte) (byte~) main::$1 ← stackpull(byte)
(byte) main::w#0 ← (byte~) main::$1 (byte) main::w#0 ← (byte~) main::$1
(byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2
*((const byte*) SCREEN + (byte) i#4) ← (byte~) main::$2 *((const byte*) SCREEN + (byte) i) ← (byte~) main::$2
(byte) main::a#1 ← (byte) main::a#2 + rangenext(0,1) (byte) main::a#1 ← (byte) main::a#2 + rangenext(0,1)
(bool~) main::$3 ← (byte) main::a#1 != rangelast(0,1) (bool~) main::$3 ← (byte) main::a#1 != rangelast(0,1)
if((bool~) main::$3) goto main::@1 if((bool~) main::$3) goto main::@1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@1
(byte) i#5 ← phi( main::@1/(byte) i#4 )
(byte) i#1 ← (byte) i#5
return return
to:@return to:@return
__stackcall (byte()) plus((byte) plus::a , (byte) plus::b) __stackcall (byte()) plus((byte) plus::a , (byte) plus::b)
plus: scope:[plus] from plus: scope:[plus] from
(byte) i#6 ← phi( )
(byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A)
(byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B)
(byte) i#2 ← ++ (byte) i#6 (byte) i ← ++ (byte) i
(byte~) plus::$0 ← (byte) plus::a#0 + (byte) plus::b#0 (byte~) plus::$0 ← (byte) plus::a#0 + (byte) plus::b#0
(byte) plus::return#0 ← (byte~) plus::$0 (byte) plus::return#0 ← (byte~) plus::$0
to:plus::@return to:plus::@return
@ -57,12 +53,9 @@ plus::@return: scope:[plus] from plus
return return
to:@return to:@return
@2: scope:[] from @begin @2: scope:[] from @begin
(byte) i#9 ← phi( @begin/(byte) i#0 )
call main call main
to:@3 to:@3
@3: scope:[] from @2 @3: scope:[] from @2
(byte) i#7 ← phi( @2/(byte) i#1 )
(byte) i#3 ← (byte) i#7
to:@end to:@end
@end: scope:[] from @3 @end: scope:[] from @3
@ -73,17 +66,7 @@ SYMBOL TABLE SSA
(label) @end (label) @end
(const byte*) SCREEN = (byte*)(number) $400 (const byte*) SCREEN = (byte*)(number) $400
(const word) STACK_BASE = (word) $103 (const word) STACK_BASE = (word) $103
(byte) i (byte) i loadstore
(byte) i#0
(byte) i#1
(byte) i#2
(byte) i#3
(byte) i#4
(byte) i#5
(byte) i#6
(byte) i#7
(byte) i#8
(byte) i#9
(void()) main() (void()) main()
(number~) main::$0 (number~) main::$0
(byte~) main::$1 (byte~) main::$1
@ -124,29 +107,14 @@ Successful SSA optimization PassNFinalizeNumberTypeConversions
Inferred type updated to byte in (unumber~) main::$0 ← (byte) main::a#2 + (byte) 1 Inferred type updated to byte in (unumber~) main::$0 ← (byte) main::a#2 + (byte) 1
Alias (byte) main::v#0 = (byte~) main::$0 Alias (byte) main::v#0 = (byte~) main::$0
Alias (byte) main::w#0 = (byte~) main::$1 Alias (byte) main::w#0 = (byte~) main::$1
Alias (byte) i#1 = (byte) i#5 (byte) i#4
Alias (byte) plus::return#0 = (byte~) plus::$0 (byte) plus::return#1 Alias (byte) plus::return#0 = (byte~) plus::$0 (byte) plus::return#1
Alias (byte) i#0 = (byte) i#9
Alias (byte) i#3 = (byte) i#7
Successful SSA optimization Pass2AliasElimination Successful SSA optimization Pass2AliasElimination
Identical Phi Values (byte) i#8 (byte) i#0 Simple Condition (bool~) main::$3 [13] if((byte) main::a#1!=rangelast(0,1)) goto main::@1
Identical Phi Values (byte) i#1 (byte) i#8
Identical Phi Values (byte) i#3 (byte) i#1
Successful SSA optimization Pass2IdenticalPhiElimination
Simple Condition (bool~) main::$3 [14] if((byte) main::a#1!=rangelast(0,1)) goto main::@1
Successful SSA optimization Pass2ConditionalJumpSimplification Successful SSA optimization Pass2ConditionalJumpSimplification
Constant (const byte) i#0 = 0
Constant (const byte) main::a#0 = 0 Constant (const byte) main::a#0 = 0
Successful SSA optimization Pass2ConstantIdentification Successful SSA optimization Pass2ConstantIdentification
Resolved ranged next value [12] main::a#1 ← ++ main::a#2 to ++ Resolved ranged next value [11] main::a#1 ← ++ main::a#2 to ++
Resolved ranged comparison value [14] if(main::a#1!=rangelast(0,1)) goto main::@1 to (number) 2 Resolved ranged comparison value [13] if(main::a#1!=rangelast(0,1)) goto main::@1 to (number) 2
Simplifying expression containing zero SCREEN in [11] *((const byte*) SCREEN + (const byte) i#0) ← (byte~) main::$2
Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused variable (byte) i#2 and assignment [15] (byte) i#2 ← ++ (byte) i#6
Eliminating unused constant (const byte) i#0
Successful SSA optimization PassNEliminateUnusedVars
Eliminating unused variable - keeping the phi block (byte) i#6
Successful SSA optimization PassNEliminateUnusedVars
Adding number conversion cast (unumber) 2 in if((byte) main::a#1!=(number) 2) goto main::@1 Adding number conversion cast (unumber) 2 in if((byte) main::a#1!=(number) 2) goto main::@1
Successful SSA optimization PassNAddNumberTypeConversions Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant integer cast 2 Simplifying constant integer cast 2
@ -157,7 +125,6 @@ Inlining constant with var siblings (const byte) main::a#0
Constant inlined main::a#0 = (byte) 0 Constant inlined main::a#0 = (byte) 0
Successful SSA optimization Pass2ConstantInlining Successful SSA optimization Pass2ConstantInlining
Added new block during phi lifting main::@3(between main::@1 and main::@1) Added new block during phi lifting main::@3(between main::@1 and main::@1)
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @2 Adding NOP phi() at start of @2
Adding NOP phi() at start of @3 Adding NOP phi() at start of @3
Adding NOP phi() at start of @end Adding NOP phi() at start of @end
@ -172,14 +139,13 @@ Coalesced down to 1 phi equivalence classes
Culled Empty Block (label) @3 Culled Empty Block (label) @3
Culled Empty Block (label) main::@3 Culled Empty Block (label) main::@3
Renumbering block @2 to @1 Renumbering block @2 to @1
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1 Adding NOP phi() at start of @1
Adding NOP phi() at start of @end Adding NOP phi() at start of @end
Adding NOP phi() at start of main Adding NOP phi() at start of main
FINAL CONTROL FLOW GRAPH FINAL CONTROL FLOW GRAPH
@begin: scope:[] from @begin: scope:[] from
[0] phi() [0] (byte) i ← (byte) 0
to:@1 to:@1
@1: scope:[] from @begin @1: scope:[] from @begin
[1] phi() [1] phi()
@ -201,7 +167,7 @@ main::@1: scope:[main] from main main::@1
sideeffect stackpullbytes((number) 1) sideeffect stackpullbytes((number) 1)
[11] (byte) main::w#0 ← stackpull(byte) [11] (byte) main::w#0 ← stackpull(byte)
[12] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 [12] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2
[13] *((const byte*) SCREEN) ← (byte~) main::$2 [13] *((const byte*) SCREEN + (byte) i) ← (byte~) main::$2
[14] (byte) main::a#1 ← ++ (byte) main::a#2 [14] (byte) main::a#1 ← ++ (byte) main::a#2
[15] if((byte) main::a#1!=(byte) 2) goto main::@1 [15] if((byte) main::a#1!=(byte) 2) goto main::@1
to:main::@return to:main::@return
@ -213,16 +179,17 @@ __stackcall (byte()) plus((byte) plus::a , (byte) plus::b)
plus: scope:[plus] from plus: scope:[plus] from
[17] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) [17] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A)
[18] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) [18] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B)
[19] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 [19] (byte) i ← ++ (byte) i
[20] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0
to:plus::@return to:plus::@return
plus::@return: scope:[plus] from plus plus::@return: scope:[plus] from plus
[20] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 [21] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0
[21] return [22] return
to:@return to:@return
VARIABLE REGISTER WEIGHTS VARIABLE REGISTER WEIGHTS
(byte) i (byte) i loadstore 0.85
(void()) main() (void()) main()
(byte~) main::$2 22.0 (byte~) main::$2 22.0
(byte) main::a (byte) main::a
@ -234,14 +201,15 @@ VARIABLE REGISTER WEIGHTS
(byte) main::w#0 22.0 (byte) main::w#0 22.0
__stackcall (byte()) plus((byte) plus::a , (byte) plus::b) __stackcall (byte()) plus((byte) plus::a , (byte) plus::b)
(byte) plus::a (byte) plus::a
(byte) plus::a#0 2.0 (byte) plus::a#0 1.3333333333333333
(byte) plus::b (byte) plus::b
(byte) plus::b#0 4.0 (byte) plus::b#0 2.0
(byte) plus::return (byte) plus::return
(byte) plus::return#0 4.0 (byte) plus::return#0 4.0
Initial phi equivalence classes Initial phi equivalence classes
[ main::a#2 main::a#1 ] [ main::a#2 main::a#1 ]
Added variable i to live range equivalence class [ i ]
Added variable main::v#0 to live range equivalence class [ main::v#0 ] Added variable main::v#0 to live range equivalence class [ main::v#0 ]
Added variable main::w#0 to live range equivalence class [ main::w#0 ] Added variable main::w#0 to live range equivalence class [ main::w#0 ]
Added variable main::$2 to live range equivalence class [ main::$2 ] Added variable main::$2 to live range equivalence class [ main::$2 ]
@ -250,6 +218,7 @@ Added variable plus::b#0 to live range equivalence class [ plus::b#0 ]
Added variable plus::return#0 to live range equivalence class [ plus::return#0 ] Added variable plus::return#0 to live range equivalence class [ plus::return#0 ]
Complete equivalence classes Complete equivalence classes
[ main::a#2 main::a#1 ] [ main::a#2 main::a#1 ]
[ i ]
[ main::v#0 ] [ main::v#0 ]
[ main::w#0 ] [ main::w#0 ]
[ main::$2 ] [ main::$2 ]
@ -257,12 +226,13 @@ Complete equivalence classes
[ plus::b#0 ] [ plus::b#0 ]
[ plus::return#0 ] [ plus::return#0 ]
Allocated zp[1]:2 [ main::a#2 main::a#1 ] Allocated zp[1]:2 [ main::a#2 main::a#1 ]
Allocated zp[1]:3 [ main::v#0 ] Allocated zp[1]:3 [ i ]
Allocated zp[1]:4 [ main::w#0 ] Allocated zp[1]:4 [ main::v#0 ]
Allocated zp[1]:5 [ main::$2 ] Allocated zp[1]:5 [ main::w#0 ]
Allocated zp[1]:6 [ plus::a#0 ] Allocated zp[1]:6 [ main::$2 ]
Allocated zp[1]:7 [ plus::b#0 ] Allocated zp[1]:7 [ plus::a#0 ]
Allocated zp[1]:8 [ plus::return#0 ] Allocated zp[1]:8 [ plus::b#0 ]
Allocated zp[1]:9 [ plus::return#0 ]
INITIAL ASM INITIAL ASM
Target platform is c64basic / MOS6502X Target platform is c64basic / MOS6502X
@ -276,8 +246,12 @@ Target platform is c64basic / MOS6502X
// Global Constants & labels // Global Constants & labels
.label SCREEN = $400 .label SCREEN = $400
.const STACK_BASE = $103 .const STACK_BASE = $103
.label i = 3
// @begin // @begin
__bbegin: __bbegin:
// [0] (byte) i ← (byte) 0 -- vbuz1=vbuc1
lda #0
sta.z i
// [1] phi from @begin to @1 [phi:@begin->@1] // [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin: __b1_from___bbegin:
jmp __b1 jmp __b1
@ -294,9 +268,9 @@ __bend_from___b1:
__bend: __bend:
// main // main
main: { main: {
.label __2 = 5 .label __2 = 6
.label v = 3 .label v = 4
.label w = 4 .label w = 5
.label a = 2 .label a = 2
// [5] phi from main to main::@1 [phi:main->main::@1] // [5] phi from main to main::@1 [phi:main->main::@1]
__b1_from_main: __b1_from_main:
@ -332,9 +306,10 @@ main: {
clc clc
adc.z a adc.z a
sta.z __2 sta.z __2
// [13] *((const byte*) SCREEN) ← (byte~) main::$2 -- _deref_pbuc1=vbuz1 // [13] *((const byte*) SCREEN + (byte) i) ← (byte~) main::$2 -- pbuc1_derefidx_vbuz1=vbuz2
lda.z __2 lda.z __2
sta SCREEN ldy.z i
sta SCREEN,y
// [14] (byte) main::a#1 ← ++ (byte) main::a#2 -- vbuz1=_inc_vbuz1 // [14] (byte) main::a#1 ← ++ (byte) main::a#2 -- vbuz1=_inc_vbuz1
inc.z a inc.z a
// [15] if((byte) main::a#1!=(byte) 2) goto main::@1 -- vbuz1_neq_vbuc1_then_la1 // [15] if((byte) main::a#1!=(byte) 2) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
@ -348,14 +323,14 @@ main: {
rts rts
} }
// plus // plus
// plus(byte zp(6) a, byte zp(7) b) // plus(byte zp(7) a, byte zp(8) b)
plus: { plus: {
.const OFFSET_STACK_A = 1 .const OFFSET_STACK_A = 1
.const OFFSET_STACK_B = 0 .const OFFSET_STACK_B = 0
.const OFFSET_STACK_RETURN = 1 .const OFFSET_STACK_RETURN = 1
.label a = 6 .label a = 7
.label b = 7 .label b = 8
.label return = 8 .label return = 9
// [17] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1 // [17] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1
tsx tsx
lda STACK_BASE+OFFSET_STACK_A,x lda STACK_BASE+OFFSET_STACK_A,x
@ -364,7 +339,9 @@ plus: {
tsx tsx
lda STACK_BASE+OFFSET_STACK_B,x lda STACK_BASE+OFFSET_STACK_B,x
sta.z b sta.z b
// [19] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuz1=vbuz2_plus_vbuz3 // [19] (byte) i ← ++ (byte) i -- vbuz1=_inc_vbuz1
inc.z i
// [20] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuz1=vbuz2_plus_vbuz3
lda.z a lda.z a
clc clc
adc.z b adc.z b
@ -372,58 +349,69 @@ plus: {
jmp __breturn jmp __breturn
// plus::@return // plus::@return
__breturn: __breturn:
// [20] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuz1 // [21] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuz1
lda.z return lda.z return
tsx tsx
sta STACK_BASE+OFFSET_STACK_RETURN,x sta STACK_BASE+OFFSET_STACK_RETURN,x
// [21] return // [22] return
rts rts
} }
// File Data // File Data
REGISTER UPLIFT POTENTIAL REGISTERS REGISTER UPLIFT POTENTIAL REGISTERS
Statement [7] stackpush(byte) ← (byte) '0' [ main::a#2 main::v#0 ] ( main:2 [ main::a#2 main::v#0 ] ) always clobbers reg byte a Statement [0] (byte) i ← (byte) 0 [ i ] ( [ i ] ) always clobbers reg byte a
Statement [7] stackpush(byte) ← (byte) '0' [ i main::a#2 main::v#0 ] ( main:2 [ i main::a#2 main::v#0 ] ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::a#2 main::a#1 ] Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::a#2 main::a#1 ]
Removing always clobbered register reg byte a as potential for zp[1]:3 [ main::v#0 ] Removing always clobbered register reg byte a as potential for zp[1]:4 [ main::v#0 ]
Statement [8] stackpush(byte) ← (byte) main::v#0 [ main::a#2 ] ( main:2 [ main::a#2 ] ) always clobbers reg byte a Statement [8] stackpush(byte) ← (byte) main::v#0 [ i main::a#2 ] ( main:2 [ i main::a#2 ] ) always clobbers reg byte a
Statement sideeffect stackpullbytes((number) 1) always clobbers reg byte a Statement sideeffect stackpullbytes((number) 1) always clobbers reg byte a
Statement [11] (byte) main::w#0 ← stackpull(byte) [ main::a#2 main::w#0 ] ( main:2 [ main::a#2 main::w#0 ] ) always clobbers reg byte a Statement [11] (byte) main::w#0 ← stackpull(byte) [ i main::a#2 main::w#0 ] ( main:2 [ i main::a#2 main::w#0 ] ) always clobbers reg byte a
Statement [12] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 [ main::a#2 main::$2 ] ( main:2 [ main::a#2 main::$2 ] ) always clobbers reg byte a Statement [12] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 [ i main::a#2 main::$2 ] ( main:2 [ i main::a#2 main::$2 ] ) always clobbers reg byte a
Statement [17] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:9 [ main::a#2 plus::a#0 ] ) always clobbers reg byte a reg byte x Statement [13] *((const byte*) SCREEN + (byte) i) ← (byte~) main::$2 [ i main::a#2 ] ( main:2 [ i main::a#2 ] ) always clobbers reg byte y
Removing always clobbered register reg byte y as potential for zp[1]:2 [ main::a#2 main::a#1 ]
Statement [17] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) [ i plus::a#0 ] ( main:2::plus:9 [ main::a#2 i plus::a#0 ] ) always clobbers reg byte a reg byte x
Removing always clobbered register reg byte x as potential for zp[1]:2 [ main::a#2 main::a#1 ] Removing always clobbered register reg byte x as potential for zp[1]:2 [ main::a#2 main::a#1 ]
Statement [18] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:9 [ main::a#2 plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x Statement [18] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) [ i plus::a#0 plus::b#0 ] ( main:2::plus:9 [ main::a#2 i plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x
Removing always clobbered register reg byte a as potential for zp[1]:6 [ plus::a#0 ] Removing always clobbered register reg byte a as potential for zp[1]:7 [ plus::a#0 ]
Removing always clobbered register reg byte x as potential for zp[1]:6 [ plus::a#0 ] Removing always clobbered register reg byte x as potential for zp[1]:7 [ plus::a#0 ]
Statement [19] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 [ plus::return#0 ] ( main:2::plus:9 [ main::a#2 plus::return#0 ] ) always clobbers reg byte a Statement [20] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 [ i plus::return#0 ] ( main:2::plus:9 [ main::a#2 i plus::return#0 ] ) always clobbers reg byte a
Statement [20] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 [ ] ( main:2::plus:9 [ main::a#2 ] ) always clobbers reg byte x Statement [21] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 [ i ] ( main:2::plus:9 [ main::a#2 i ] ) always clobbers reg byte x
Statement [7] stackpush(byte) ← (byte) '0' [ main::a#2 main::v#0 ] ( main:2 [ main::a#2 main::v#0 ] ) always clobbers reg byte a Statement [0] (byte) i ← (byte) 0 [ i ] ( [ i ] ) always clobbers reg byte a
Statement [8] stackpush(byte) ← (byte) main::v#0 [ main::a#2 ] ( main:2 [ main::a#2 ] ) always clobbers reg byte a Statement [7] stackpush(byte) ← (byte) '0' [ i main::a#2 main::v#0 ] ( main:2 [ i main::a#2 main::v#0 ] ) always clobbers reg byte a
Statement [8] stackpush(byte) ← (byte) main::v#0 [ i main::a#2 ] ( main:2 [ i main::a#2 ] ) always clobbers reg byte a
Statement sideeffect stackpullbytes((number) 1) always clobbers reg byte a Statement sideeffect stackpullbytes((number) 1) always clobbers reg byte a
Statement [11] (byte) main::w#0 ← stackpull(byte) [ main::a#2 main::w#0 ] ( main:2 [ main::a#2 main::w#0 ] ) always clobbers reg byte a Statement [11] (byte) main::w#0 ← stackpull(byte) [ i main::a#2 main::w#0 ] ( main:2 [ i main::a#2 main::w#0 ] ) always clobbers reg byte a
Statement [12] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 [ main::a#2 main::$2 ] ( main:2 [ main::a#2 main::$2 ] ) always clobbers reg byte a Statement [12] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 [ i main::a#2 main::$2 ] ( main:2 [ i main::a#2 main::$2 ] ) always clobbers reg byte a
Statement [17] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:9 [ main::a#2 plus::a#0 ] ) always clobbers reg byte a reg byte x Statement [13] *((const byte*) SCREEN + (byte) i) ← (byte~) main::$2 [ i main::a#2 ] ( main:2 [ i main::a#2 ] ) always clobbers reg byte y
Statement [18] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:9 [ main::a#2 plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x Statement [15] if((byte) main::a#1!=(byte) 2) goto main::@1 [ i main::a#1 ] ( main:2 [ i main::a#1 ] ) always clobbers reg byte a
Statement [19] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 [ plus::return#0 ] ( main:2::plus:9 [ main::a#2 plus::return#0 ] ) always clobbers reg byte a Statement [17] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) [ i plus::a#0 ] ( main:2::plus:9 [ main::a#2 i plus::a#0 ] ) always clobbers reg byte a reg byte x
Statement [20] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 [ ] ( main:2::plus:9 [ main::a#2 ] ) always clobbers reg byte x Statement [18] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) [ i plus::a#0 plus::b#0 ] ( main:2::plus:9 [ main::a#2 i plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x
Potential registers zp[1]:2 [ main::a#2 main::a#1 ] : zp[1]:2 , reg byte y , Statement [20] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 [ i plus::return#0 ] ( main:2::plus:9 [ main::a#2 i plus::return#0 ] ) always clobbers reg byte a
Potential registers zp[1]:3 [ main::v#0 ] : zp[1]:3 , reg byte x , reg byte y , Statement [21] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 [ i ] ( main:2::plus:9 [ main::a#2 i ] ) always clobbers reg byte x
Potential registers zp[1]:4 [ main::w#0 ] : zp[1]:4 , reg byte a , reg byte x , reg byte y , Potential registers zp[1]:2 [ main::a#2 main::a#1 ] : zp[1]:2 ,
Potential registers zp[1]:5 [ main::$2 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y , Potential registers zp[1]:3 [ i ] : zp[1]:3 ,
Potential registers zp[1]:6 [ plus::a#0 ] : zp[1]:6 , reg byte y , Potential registers zp[1]:4 [ main::v#0 ] : zp[1]:4 , reg byte x , reg byte y ,
Potential registers zp[1]:7 [ plus::b#0 ] : zp[1]:7 , reg byte a , reg byte x , reg byte y , Potential registers zp[1]:5 [ main::w#0 ] : zp[1]:5 , 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]:6 [ main::$2 ] : zp[1]:6 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:7 [ plus::a#0 ] : zp[1]:7 , reg byte y ,
Potential registers zp[1]:8 [ plus::b#0 ] : zp[1]:8 , reg byte a , reg byte x , reg byte y ,
Potential registers zp[1]:9 [ plus::return#0 ] : zp[1]:9 , reg byte a , reg byte x , reg byte y ,
REGISTER UPLIFT SCOPES REGISTER UPLIFT SCOPES
Uplift Scope [main] 22: zp[1]:4 [ main::w#0 ] 22: zp[1]:5 [ main::$2 ] 21.39: zp[1]:2 [ main::a#2 main::a#1 ] 11: zp[1]:3 [ main::v#0 ] Uplift Scope [main] 22: zp[1]:5 [ main::w#0 ] 22: zp[1]:6 [ main::$2 ] 21.39: zp[1]:2 [ main::a#2 main::a#1 ] 11: zp[1]:4 [ main::v#0 ]
Uplift Scope [plus] 4: zp[1]:7 [ plus::b#0 ] 4: zp[1]:8 [ plus::return#0 ] 2: zp[1]:6 [ plus::a#0 ] Uplift Scope [plus] 4: zp[1]:9 [ plus::return#0 ] 2: zp[1]:8 [ plus::b#0 ] 1.33: zp[1]:7 [ plus::a#0 ]
Uplift Scope [] Uplift Scope [] 0.85: zp[1]:3 [ i ]
Uplifting [main] best 661 combination reg byte a [ main::w#0 ] reg byte a [ main::$2 ] reg byte y [ main::a#2 main::a#1 ] reg byte x [ main::v#0 ] Uplifting [main] best 761 combination reg byte a [ main::w#0 ] reg byte a [ main::$2 ] zp[1]:2 [ main::a#2 main::a#1 ] reg byte x [ main::v#0 ]
Uplifting [plus] best 649 combination reg byte a [ plus::b#0 ] reg byte a [ plus::return#0 ] zp[1]:6 [ plus::a#0 ] Uplifting [plus] best 749 combination reg byte a [ plus::return#0 ] reg byte a [ plus::b#0 ] zp[1]:7 [ plus::a#0 ]
Uplifting [] best 649 combination Uplifting [] best 749 combination zp[1]:3 [ i ]
Attempting to uplift remaining variables inzp[1]:6 [ plus::a#0 ] Attempting to uplift remaining variables inzp[1]:2 [ main::a#2 main::a#1 ]
Uplifting [plus] best 649 combination zp[1]:6 [ plus::a#0 ] Uplifting [main] best 749 combination zp[1]:2 [ main::a#2 main::a#1 ]
Allocated (was zp[1]:6) zp[1]:2 [ plus::a#0 ] Attempting to uplift remaining variables inzp[1]:7 [ plus::a#0 ]
Uplifting [plus] best 749 combination zp[1]:7 [ plus::a#0 ]
Attempting to uplift remaining variables inzp[1]:3 [ i ]
Uplifting [] best 749 combination zp[1]:3 [ i ]
Allocated (was zp[1]:7) zp[1]:4 [ plus::a#0 ]
ASSEMBLER BEFORE OPTIMIZATION ASSEMBLER BEFORE OPTIMIZATION
// File Comments // File Comments
@ -436,8 +424,12 @@ ASSEMBLER BEFORE OPTIMIZATION
// Global Constants & labels // Global Constants & labels
.label SCREEN = $400 .label SCREEN = $400
.const STACK_BASE = $103 .const STACK_BASE = $103
.label i = 3
// @begin // @begin
__bbegin: __bbegin:
// [0] (byte) i ← (byte) 0 -- vbuz1=vbuc1
lda #0
sta.z i
// [1] phi from @begin to @1 [phi:@begin->@1] // [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin: __b1_from___bbegin:
jmp __b1 jmp __b1
@ -454,10 +446,12 @@ __bend_from___b1:
__bend: __bend:
// main // main
main: { main: {
.label a = 2
// [5] phi from main to main::@1 [phi:main->main::@1] // [5] phi from main to main::@1 [phi:main->main::@1]
__b1_from_main: __b1_from_main:
// [5] phi (byte) main::a#2 = (byte) 0 [phi:main->main::@1#0] -- vbuyy=vbuc1 // [5] phi (byte) main::a#2 = (byte) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
ldy #0 lda #0
sta.z a
jmp __b1 jmp __b1
// [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1] // [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
__b1_from___b1: __b1_from___b1:
@ -465,9 +459,8 @@ main: {
jmp __b1 jmp __b1
// main::@1 // main::@1
__b1: __b1:
// [6] (byte) main::v#0 ← (byte) main::a#2 + (byte) 1 -- vbuxx=vbuyy_plus_1 // [6] (byte) main::v#0 ← (byte) main::a#2 + (byte) 1 -- vbuxx=vbuz1_plus_1
tya ldx.z a
tax
inx inx
// [7] stackpush(byte) ← (byte) '0' -- _stackpushbyte_=vbuc1 // [7] stackpush(byte) ← (byte) '0' -- _stackpushbyte_=vbuc1
lda #'0' lda #'0'
@ -481,16 +474,17 @@ main: {
pla pla
// [11] (byte) main::w#0 ← stackpull(byte) -- vbuaa=_stackpullbyte_ // [11] (byte) main::w#0 ← stackpull(byte) -- vbuaa=_stackpullbyte_
pla pla
// [12] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 -- vbuaa=vbuaa_plus_vbuyy // [12] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 -- vbuaa=vbuaa_plus_vbuz1
sty.z $ff
clc clc
adc.z $ff adc.z a
// [13] *((const byte*) SCREEN) ← (byte~) main::$2 -- _deref_pbuc1=vbuaa // [13] *((const byte*) SCREEN + (byte) i) ← (byte~) main::$2 -- pbuc1_derefidx_vbuz1=vbuaa
sta SCREEN ldy.z i
// [14] (byte) main::a#1 ← ++ (byte) main::a#2 -- vbuyy=_inc_vbuyy sta SCREEN,y
iny // [14] (byte) main::a#1 ← ++ (byte) main::a#2 -- vbuz1=_inc_vbuz1
// [15] if((byte) main::a#1!=(byte) 2) goto main::@1 -- vbuyy_neq_vbuc1_then_la1 inc.z a
cpy #2 // [15] if((byte) main::a#1!=(byte) 2) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
lda #2
cmp.z a
bne __b1_from___b1 bne __b1_from___b1
jmp __breturn jmp __breturn
// main::@return // main::@return
@ -499,12 +493,12 @@ main: {
rts rts
} }
// plus // plus
// plus(byte zp(2) a, byte register(A) b) // plus(byte zp(4) a, byte register(A) b)
plus: { plus: {
.const OFFSET_STACK_A = 1 .const OFFSET_STACK_A = 1
.const OFFSET_STACK_B = 0 .const OFFSET_STACK_B = 0
.const OFFSET_STACK_RETURN = 1 .const OFFSET_STACK_RETURN = 1
.label a = 2 .label a = 4
// [17] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1 // [17] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1
tsx tsx
lda STACK_BASE+OFFSET_STACK_A,x lda STACK_BASE+OFFSET_STACK_A,x
@ -512,16 +506,18 @@ plus: {
// [18] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuaa=_stackidxbyte_vbuc1 // [18] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuaa=_stackidxbyte_vbuc1
tsx tsx
lda STACK_BASE+OFFSET_STACK_B,x lda STACK_BASE+OFFSET_STACK_B,x
// [19] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuaa=vbuz1_plus_vbuaa // [19] (byte) i ← ++ (byte) i -- vbuz1=_inc_vbuz1
inc.z i
// [20] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuaa=vbuz1_plus_vbuaa
clc clc
adc.z a adc.z a
jmp __breturn jmp __breturn
// plus::@return // plus::@return
__breturn: __breturn:
// [20] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuaa // [21] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuaa
tsx tsx
sta STACK_BASE+OFFSET_STACK_RETURN,x sta STACK_BASE+OFFSET_STACK_RETURN,x
// [21] return // [22] return
rts rts
} }
// File Data // File Data
@ -535,23 +531,20 @@ Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination Succesful ASM optimization Pass5NextJumpElimination
Replacing label __b1_from___b1 with __b1 Replacing label __b1_from___b1 with __b1
Removing instruction __b1_from___bbegin: Removing instruction __b1_from___bbegin:
Removing instruction __b1:
Removing instruction main_from___b1: Removing instruction main_from___b1:
Removing instruction __bend_from___b1: Removing instruction __bend_from___b1:
Removing instruction __b1_from___b1: Removing instruction __b1_from___b1:
Succesful ASM optimization Pass5RedundantLabelElimination Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __b1:
Removing instruction __bend: Removing instruction __bend:
Removing instruction __b1_from_main: Removing instruction __b1_from_main:
Removing instruction __breturn: Removing instruction __breturn:
Removing instruction __breturn: Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination Succesful ASM optimization Pass5UnusedLabelElimination
Updating BasicUpstart to call main directly Adding RTS to root block
Removing instruction jsr main Succesful ASM optimization Pass5AddMainRts
Succesful ASM optimization Pass5SkipBegin
Removing instruction jmp __b1 Removing instruction jmp __b1
Succesful ASM optimization Pass5NextJumpElimination Succesful ASM optimization Pass5NextJumpElimination
Removing instruction __bbegin:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE FINAL SYMBOL TABLE
(label) @1 (label) @1
@ -559,14 +552,14 @@ FINAL SYMBOL TABLE
(label) @end (label) @end
(const byte*) SCREEN = (byte*) 1024 (const byte*) SCREEN = (byte*) 1024
(const word) STACK_BASE = (word) $103 (const word) STACK_BASE = (word) $103
(byte) i (byte) i loadstore zp[1]:3 0.85
(void()) main() (void()) main()
(byte~) main::$2 reg byte a 22.0 (byte~) main::$2 reg byte a 22.0
(label) main::@1 (label) main::@1
(label) main::@return (label) main::@return
(byte) main::a (byte) main::a
(byte) main::a#1 reg byte y 16.5 (byte) main::a#1 a zp[1]:2 16.5
(byte) main::a#2 reg byte y 4.888888888888889 (byte) main::a#2 a zp[1]:2 4.888888888888889
(byte) main::v (byte) main::v
(byte) main::v#0 reg byte x 11.0 (byte) main::v#0 reg byte x 11.0
(byte) main::w (byte) main::w
@ -577,54 +570,64 @@ __stackcall (byte()) plus((byte) plus::a , (byte) plus::b)
(const byte) plus::OFFSET_STACK_B = (byte) 0 (const byte) plus::OFFSET_STACK_B = (byte) 0
(const byte) plus::OFFSET_STACK_RETURN = (byte) 1 (const byte) plus::OFFSET_STACK_RETURN = (byte) 1
(byte) plus::a (byte) plus::a
(byte) plus::a#0 a zp[1]:2 2.0 (byte) plus::a#0 a zp[1]:4 1.3333333333333333
(byte) plus::b (byte) plus::b
(byte) plus::b#0 reg byte a 4.0 (byte) plus::b#0 reg byte a 2.0
(byte) plus::return (byte) plus::return
(byte) plus::return#0 reg byte a 4.0 (byte) plus::return#0 reg byte a 4.0
reg byte y [ main::a#2 main::a#1 ] zp[1]:2 [ main::a#2 main::a#1 ]
zp[1]:3 [ i ]
reg byte x [ main::v#0 ] reg byte x [ main::v#0 ]
reg byte a [ main::w#0 ] reg byte a [ main::w#0 ]
reg byte a [ main::$2 ] reg byte a [ main::$2 ]
zp[1]:2 [ plus::a#0 ] zp[1]:4 [ plus::a#0 ]
reg byte a [ plus::b#0 ] reg byte a [ plus::b#0 ]
reg byte a [ plus::return#0 ] reg byte a [ plus::return#0 ]
FINAL ASSEMBLER FINAL ASSEMBLER
Score: 544 Score: 656
// File Comments // File Comments
// Test a procedure with calling convention stack // Test a procedure with calling convention stack
// A slightly more complex call // A slightly more complex call
// Upstart // Upstart
.pc = $801 "Basic" .pc = $801 "Basic"
:BasicUpstart(main) :BasicUpstart(__bbegin)
.pc = $80d "Program" .pc = $80d "Program"
// Global Constants & labels // Global Constants & labels
.label SCREEN = $400 .label SCREEN = $400
.const STACK_BASE = $103 .const STACK_BASE = $103
.label i = 3
// @begin // @begin
__bbegin:
// i = 0
// [0] (byte) i ← (byte) 0 -- vbuz1=vbuc1
lda #0
sta.z i
// [1] phi from @begin to @1 [phi:@begin->@1] // [1] phi from @begin to @1 [phi:@begin->@1]
// @1 // @1
// [2] call main // [2] call main
// [4] phi from @1 to main [phi:@1->main] // [4] phi from @1 to main [phi:@1->main]
jsr main
rts
// [3] phi from @1 to @end [phi:@1->@end] // [3] phi from @1 to @end [phi:@1->@end]
// @end // @end
// main // main
main: { main: {
.label a = 2
// [5] phi from main to main::@1 [phi:main->main::@1] // [5] phi from main to main::@1 [phi:main->main::@1]
// [5] phi (byte) main::a#2 = (byte) 0 [phi:main->main::@1#0] -- vbuyy=vbuc1 // [5] phi (byte) main::a#2 = (byte) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
ldy #0 lda #0
sta.z a
// [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1] // [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
// [5] phi (byte) main::a#2 = (byte) main::a#1 [phi:main::@1->main::@1#0] -- register_copy // [5] phi (byte) main::a#2 = (byte) main::a#1 [phi:main::@1->main::@1#0] -- register_copy
// main::@1 // main::@1
__b1: __b1:
// v = a+1 // v = a+1
// [6] (byte) main::v#0 ← (byte) main::a#2 + (byte) 1 -- vbuxx=vbuyy_plus_1 // [6] (byte) main::v#0 ← (byte) main::a#2 + (byte) 1 -- vbuxx=vbuz1_plus_1
tya ldx.z a
tax
inx inx
// plus('0', v) // plus('0', v)
// [7] stackpush(byte) ← (byte) '0' -- _stackpushbyte_=vbuc1 // [7] stackpush(byte) ← (byte) '0' -- _stackpushbyte_=vbuc1
@ -641,18 +644,19 @@ main: {
// [11] (byte) main::w#0 ← stackpull(byte) -- vbuaa=_stackpullbyte_ // [11] (byte) main::w#0 ← stackpull(byte) -- vbuaa=_stackpullbyte_
pla pla
// w+a // w+a
// [12] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 -- vbuaa=vbuaa_plus_vbuyy // [12] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 -- vbuaa=vbuaa_plus_vbuz1
sty.z $ff
clc clc
adc.z $ff adc.z a
// SCREEN[i] = w+a // SCREEN[i] = w+a
// [13] *((const byte*) SCREEN) ← (byte~) main::$2 -- _deref_pbuc1=vbuaa // [13] *((const byte*) SCREEN + (byte) i) ← (byte~) main::$2 -- pbuc1_derefidx_vbuz1=vbuaa
sta SCREEN ldy.z i
sta SCREEN,y
// for(char a:0..1) // for(char a:0..1)
// [14] (byte) main::a#1 ← ++ (byte) main::a#2 -- vbuyy=_inc_vbuyy // [14] (byte) main::a#1 ← ++ (byte) main::a#2 -- vbuz1=_inc_vbuz1
iny inc.z a
// [15] if((byte) main::a#1!=(byte) 2) goto main::@1 -- vbuyy_neq_vbuc1_then_la1 // [15] if((byte) main::a#1!=(byte) 2) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
cpy #2 lda #2
cmp.z a
bne __b1 bne __b1
// main::@return // main::@return
// } // }
@ -660,12 +664,12 @@ main: {
rts rts
} }
// plus // plus
// plus(byte zp(2) a, byte register(A) b) // plus(byte zp(4) a, byte register(A) b)
plus: { plus: {
.const OFFSET_STACK_A = 1 .const OFFSET_STACK_A = 1
.const OFFSET_STACK_B = 0 .const OFFSET_STACK_B = 0
.const OFFSET_STACK_RETURN = 1 .const OFFSET_STACK_RETURN = 1
.label a = 2 .label a = 4
// [17] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1 // [17] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1
tsx tsx
lda STACK_BASE+OFFSET_STACK_A,x lda STACK_BASE+OFFSET_STACK_A,x
@ -673,16 +677,19 @@ plus: {
// [18] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuaa=_stackidxbyte_vbuc1 // [18] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuaa=_stackidxbyte_vbuc1
tsx tsx
lda STACK_BASE+OFFSET_STACK_B,x lda STACK_BASE+OFFSET_STACK_B,x
// i++;
// [19] (byte) i ← ++ (byte) i -- vbuz1=_inc_vbuz1
inc.z i
// return a+b; // return a+b;
// [19] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuaa=vbuz1_plus_vbuaa // [20] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuaa=vbuz1_plus_vbuaa
clc clc
adc.z a adc.z a
// plus::@return // plus::@return
// } // }
// [20] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuaa // [21] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuaa
tsx tsx
sta STACK_BASE+OFFSET_STACK_RETURN,x sta STACK_BASE+OFFSET_STACK_RETURN,x
// [21] return // [22] return
rts rts
} }
// File Data // File Data

View File

@ -3,14 +3,14 @@
(label) @end (label) @end
(const byte*) SCREEN = (byte*) 1024 (const byte*) SCREEN = (byte*) 1024
(const word) STACK_BASE = (word) $103 (const word) STACK_BASE = (word) $103
(byte) i (byte) i loadstore zp[1]:3 0.85
(void()) main() (void()) main()
(byte~) main::$2 reg byte a 22.0 (byte~) main::$2 reg byte a 22.0
(label) main::@1 (label) main::@1
(label) main::@return (label) main::@return
(byte) main::a (byte) main::a
(byte) main::a#1 reg byte y 16.5 (byte) main::a#1 a zp[1]:2 16.5
(byte) main::a#2 reg byte y 4.888888888888889 (byte) main::a#2 a zp[1]:2 4.888888888888889
(byte) main::v (byte) main::v
(byte) main::v#0 reg byte x 11.0 (byte) main::v#0 reg byte x 11.0
(byte) main::w (byte) main::w
@ -21,16 +21,17 @@ __stackcall (byte()) plus((byte) plus::a , (byte) plus::b)
(const byte) plus::OFFSET_STACK_B = (byte) 0 (const byte) plus::OFFSET_STACK_B = (byte) 0
(const byte) plus::OFFSET_STACK_RETURN = (byte) 1 (const byte) plus::OFFSET_STACK_RETURN = (byte) 1
(byte) plus::a (byte) plus::a
(byte) plus::a#0 a zp[1]:2 2.0 (byte) plus::a#0 a zp[1]:4 1.3333333333333333
(byte) plus::b (byte) plus::b
(byte) plus::b#0 reg byte a 4.0 (byte) plus::b#0 reg byte a 2.0
(byte) plus::return (byte) plus::return
(byte) plus::return#0 reg byte a 4.0 (byte) plus::return#0 reg byte a 4.0
reg byte y [ main::a#2 main::a#1 ] zp[1]:2 [ main::a#2 main::a#1 ]
zp[1]:3 [ i ]
reg byte x [ main::v#0 ] reg byte x [ main::v#0 ]
reg byte a [ main::w#0 ] reg byte a [ main::w#0 ]
reg byte a [ main::$2 ] reg byte a [ main::$2 ]
zp[1]:2 [ plus::a#0 ] zp[1]:4 [ plus::a#0 ]
reg byte a [ plus::b#0 ] reg byte a [ plus::b#0 ]
reg byte a [ plus::return#0 ] reg byte a [ plus::return#0 ]

View File

@ -1,15 +1,23 @@
// Test a procedure with calling convention stack // Test a procedure with calling convention stack
// Return value larger than parameter // Return value larger than parameter
.pc = $801 "Basic" .pc = $801 "Basic"
:BasicUpstart(main) :BasicUpstart(__bbegin)
.pc = $80d "Program" .pc = $80d "Program"
.label SCREEN = $400 .label SCREEN = $400
.const SIZEOF_SIGNED_WORD = 2 .const SIZEOF_SIGNED_WORD = 2
.const STACK_BASE = $103 .const STACK_BASE = $103
.label current = 2 .label current = 2
__bbegin:
// current = 48
lda #<$30
sta.z current
lda #>$30
sta.z current+1
jsr main
rts
main: { main: {
.label __0 = 2 .label __0 = 4
.label __1 = 4 .label __1 = 2
// next() // next()
pha pha
pha pha
@ -41,8 +49,16 @@ main: {
} }
next: { next: {
.const OFFSET_STACK_RETURN = 0 .const OFFSET_STACK_RETURN = 0
.label return = 2 .label return = 4
// return current++; // return current++;
lda.z current
sta.z return
lda.z current+1
sta.z return+1
inc.z current
bne !+
inc.z current+1
!:
// } // }
tsx tsx
lda.z return lda.z return

View File

@ -2,33 +2,36 @@
[0] phi() [0] phi()
to:@1 to:@1
@1: scope:[] from @begin @1: scope:[] from @begin
[1] phi() [1] (signed word) current ← (signed word) $30
[2] call main to:@2
@2: scope:[] from @1
[2] phi()
[3] call main
to:@end to:@end
@end: scope:[] from @1 @end: scope:[] from @2
[3] phi() [4] phi()
(void()) main() (void()) main()
main: scope:[main] from @1 main: scope:[main] from @2
sideeffect stackpushbytes((number) 2) sideeffect stackpushbytes((number) 2)
[5] callexecute next [6] callexecute next
[6] (signed word~) main::$0 ← stackpull(signed word) [7] (signed word~) main::$0 ← stackpull(signed word)
[7] *((const signed word*) SCREEN) ← (signed word~) main::$0 [8] *((const signed word*) SCREEN) ← (signed word~) main::$0
sideeffect stackpushbytes((number) 2) sideeffect stackpushbytes((number) 2)
[9] callexecute next [10] callexecute next
[10] (signed word~) main::$1 ← stackpull(signed word) [11] (signed word~) main::$1 ← stackpull(signed word)
[11] *((const signed word*) SCREEN+(byte) 1*(const byte) SIZEOF_SIGNED_WORD) ← (signed word~) main::$1 [12] *((const signed word*) SCREEN+(byte) 1*(const byte) SIZEOF_SIGNED_WORD) ← (signed word~) main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main main::@return: scope:[main] from main
[12] return [13] return
to:@return to:@return
__stackcall (signed word()) next() __stackcall (signed word()) next()
next: scope:[next] from next: scope:[next] from
[13] (signed word) current#5 ← phi( ) [14] (signed word) next::return#0 ← (signed word) current
[14] (signed word) next::return#0 ← (signed word) current#5 [15] (signed word) current ← ++ (signed word) current
to:next::@return to:next::@return
next::@return: scope:[next] from next next::@return: scope:[next] from next
[15] stackidx(signed word,(const byte) next::OFFSET_STACK_RETURN) ← (signed word) next::return#0 [16] stackidx(signed word,(const byte) next::OFFSET_STACK_RETURN) ← (signed word) next::return#0
[16] return [17] return
to:@return to:@return

View File

@ -1,6 +1,7 @@
Fixing pointer array-indexing *((const signed word*) SCREEN + (number) 0) Fixing pointer array-indexing *((const signed word*) SCREEN + (number) 0)
Fixing pointer array-indexing *((const signed word*) SCREEN + (number) 1) Fixing pointer array-indexing *((const signed word*) SCREEN + (number) 1)
Culled Empty Block (label) next::@1 Culled Empty Block (label) next::@1
Converting PHI-variable modified inside __stackcall procedure next() to load/store (signed word) current
Calling convention STACK_CALL adding prepare/execute/finalize for (signed word~) main::$0 ← call next Calling convention STACK_CALL adding prepare/execute/finalize for (signed word~) main::$0 ← call next
Calling convention STACK_CALL adding prepare/execute/finalize for (signed word~) main::$1 ← call next Calling convention STACK_CALL adding prepare/execute/finalize for (signed word~) main::$1 ← call next
Calling convention STACK_CALL adding stack return stackidx(signed word,next::OFFSET_STACK_RETURN) ← next::return Calling convention STACK_CALL adding stack return stackidx(signed word,next::OFFSET_STACK_RETURN) ← next::return
@ -13,7 +14,6 @@ CONTROL FLOW GRAPH SSA
(void()) main() (void()) main()
main: scope:[main] from @2 main: scope:[main] from @2
(signed word) current#7 ← phi( @2/(signed word) current#8 )
sideeffect stackpushbytes((number) 2) sideeffect stackpushbytes((number) 2)
callexecute next callexecute next
(signed word~) main::$0 ← stackpull(signed word) (signed word~) main::$0 ← stackpull(signed word)
@ -26,19 +26,16 @@ main: scope:[main] from @2
*((const signed word*) SCREEN + (number~) main::$3) ← (signed word~) main::$1 *((const signed word*) SCREEN + (number~) main::$3) ← (signed word~) main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main main::@return: scope:[main] from main
(signed word) current#4 ← phi( main/(signed word) current#7 )
(signed word) current#0 ← (signed word) current#4
return return
to:@return to:@return
@1: scope:[] from @begin @1: scope:[] from @begin
(signed word) current#1 ← (signed word) $30 (signed word) current ← (signed word) $30
to:@2 to:@2
__stackcall (signed word()) next() __stackcall (signed word()) next()
next: scope:[next] from next: scope:[next] from
(signed word) current#5 ← phi( ) (signed word) next::return#0 ← (signed word) current
(signed word) next::return#0 ← (signed word) current#5 (signed word) current ← ++ (signed word) current
(signed word) current#2 ← ++ (signed word) current#5
to:next::@return to:next::@return
next::@return: scope:[next] from next next::@return: scope:[next] from next
(signed word) next::return#1 ← phi( next/(signed word) next::return#0 ) (signed word) next::return#1 ← phi( next/(signed word) next::return#0 )
@ -46,12 +43,9 @@ next::@return: scope:[next] from next
return return
to:@return to:@return
@2: scope:[] from @1 @2: scope:[] from @1
(signed word) current#8 ← phi( @1/(signed word) current#1 )
call main call main
to:@3 to:@3
@3: scope:[] from @2 @3: scope:[] from @2
(signed word) current#6 ← phi( @2/(signed word) current#0 )
(signed word) current#3 ← (signed word) current#6
to:@end to:@end
@end: scope:[] from @3 @end: scope:[] from @3
@ -64,16 +58,7 @@ SYMBOL TABLE SSA
(const signed word*) SCREEN = (signed word*)(number) $400 (const signed word*) SCREEN = (signed word*)(number) $400
(const byte) SIZEOF_SIGNED_WORD = (byte) 2 (const byte) SIZEOF_SIGNED_WORD = (byte) 2
(const word) STACK_BASE = (word) $103 (const word) STACK_BASE = (word) $103
(signed word) current (signed word) current loadstore
(signed word) current#0
(signed word) current#1
(signed word) current#2
(signed word) current#3
(signed word) current#4
(signed word) current#5
(signed word) current#6
(signed word) current#7
(signed word) current#8
(void()) main() (void()) main()
(signed word~) main::$0 (signed word~) main::$0
(signed word~) main::$1 (signed word~) main::$1
@ -101,35 +86,25 @@ Finalized unsigned number type (byte) 1
Successful SSA optimization PassNFinalizeNumberTypeConversions Successful SSA optimization PassNFinalizeNumberTypeConversions
Inferred type updated to byte in (unumber~) main::$2 ← (byte) 0 * (const byte) SIZEOF_SIGNED_WORD Inferred type updated to byte in (unumber~) main::$2 ← (byte) 0 * (const byte) SIZEOF_SIGNED_WORD
Inferred type updated to byte in (unumber~) main::$3 ← (byte) 1 * (const byte) SIZEOF_SIGNED_WORD Inferred type updated to byte in (unumber~) main::$3 ← (byte) 1 * (const byte) SIZEOF_SIGNED_WORD
Alias (signed word) current#0 = (signed word) current#4 (signed word) current#7
Alias (signed word) next::return#0 = (signed word) next::return#1 Alias (signed word) next::return#0 = (signed word) next::return#1
Alias (signed word) current#1 = (signed word) current#8
Alias (signed word) current#3 = (signed word) current#6
Successful SSA optimization Pass2AliasElimination Successful SSA optimization Pass2AliasElimination
Identical Phi Values (signed word) current#0 (signed word) current#1 Constant right-side identified [3] (byte~) main::$2 ← (byte) 0 * (const byte) SIZEOF_SIGNED_WORD
Identical Phi Values (signed word) current#3 (signed word) current#0 Constant right-side identified [8] (byte~) main::$3 ← (byte) 1 * (const byte) SIZEOF_SIGNED_WORD
Successful SSA optimization Pass2IdenticalPhiElimination
Constant right-side identified [4] (byte~) main::$2 ← (byte) 0 * (const byte) SIZEOF_SIGNED_WORD
Constant right-side identified [9] (byte~) main::$3 ← (byte) 1 * (const byte) SIZEOF_SIGNED_WORD
Successful SSA optimization Pass2ConstantRValueConsolidation Successful SSA optimization Pass2ConstantRValueConsolidation
Constant (const byte) main::$2 = 0*SIZEOF_SIGNED_WORD Constant (const byte) main::$2 = 0*SIZEOF_SIGNED_WORD
Constant (const byte) main::$3 = 1*SIZEOF_SIGNED_WORD Constant (const byte) main::$3 = 1*SIZEOF_SIGNED_WORD
Constant (const signed word) current#1 = $30
Successful SSA optimization Pass2ConstantIdentification Successful SSA optimization Pass2ConstantIdentification
Simplifying constant evaluating to zero (byte) 0*(const byte) SIZEOF_SIGNED_WORD in Simplifying constant evaluating to zero (byte) 0*(const byte) SIZEOF_SIGNED_WORD in
Successful SSA optimization PassNSimplifyConstantZero Successful SSA optimization PassNSimplifyConstantZero
Simplifying expression containing zero SCREEN in [5] *((const signed word*) SCREEN + (const byte) main::$2) ← (signed word~) main::$0 Simplifying expression containing zero SCREEN in [4] *((const signed word*) SCREEN + (const byte) main::$2) ← (signed word~) main::$0
Successful SSA optimization PassNSimplifyExpressionWithZero Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused variable (signed word) current#2 and assignment [11] (signed word) current#2 ← ++ (signed word) current#5
Eliminating unused constant (const byte) main::$2 Eliminating unused constant (const byte) main::$2
Eliminating unused constant (const signed word) current#1
Successful SSA optimization PassNEliminateUnusedVars Successful SSA optimization PassNEliminateUnusedVars
Constant inlined main::$3 = (byte) 1*(const byte) SIZEOF_SIGNED_WORD Constant inlined main::$3 = (byte) 1*(const byte) SIZEOF_SIGNED_WORD
Successful SSA optimization Pass2ConstantInlining Successful SSA optimization Pass2ConstantInlining
Consolidated array index constant in *(SCREEN+1*SIZEOF_SIGNED_WORD) Consolidated array index constant in *(SCREEN+1*SIZEOF_SIGNED_WORD)
Successful SSA optimization Pass2ConstantAdditionElimination Successful SSA optimization Pass2ConstantAdditionElimination
Adding NOP phi() at start of @begin Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1
Adding NOP phi() at start of @2 Adding NOP phi() at start of @2
Adding NOP phi() at start of @3 Adding NOP phi() at start of @3
Adding NOP phi() at start of @end Adding NOP phi() at start of @end
@ -137,13 +112,11 @@ CALL GRAPH
Calls in [] to main:3 Calls in [] to main:3
Calls in [main] to next:7 next:11 Calls in [main] to next:7 next:11
Created 1 initial phi equivalence classes Created 0 initial phi equivalence classes
Coalesced down to 1 phi equivalence classes Coalesced down to 0 phi equivalence classes
Culled Empty Block (label) @1
Culled Empty Block (label) @3 Culled Empty Block (label) @3
Renumbering block @2 to @1
Adding NOP phi() at start of @begin Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1 Adding NOP phi() at start of @2
Adding NOP phi() at start of @end Adding NOP phi() at start of @end
FINAL CONTROL FLOW GRAPH FINAL CONTROL FLOW GRAPH
@ -151,59 +124,61 @@ FINAL CONTROL FLOW GRAPH
[0] phi() [0] phi()
to:@1 to:@1
@1: scope:[] from @begin @1: scope:[] from @begin
[1] phi() [1] (signed word) current ← (signed word) $30
[2] call main to:@2
@2: scope:[] from @1
[2] phi()
[3] call main
to:@end to:@end
@end: scope:[] from @1 @end: scope:[] from @2
[3] phi() [4] phi()
(void()) main() (void()) main()
main: scope:[main] from @1 main: scope:[main] from @2
sideeffect stackpushbytes((number) 2) sideeffect stackpushbytes((number) 2)
[5] callexecute next [6] callexecute next
[6] (signed word~) main::$0 ← stackpull(signed word) [7] (signed word~) main::$0 ← stackpull(signed word)
[7] *((const signed word*) SCREEN) ← (signed word~) main::$0 [8] *((const signed word*) SCREEN) ← (signed word~) main::$0
sideeffect stackpushbytes((number) 2) sideeffect stackpushbytes((number) 2)
[9] callexecute next [10] callexecute next
[10] (signed word~) main::$1 ← stackpull(signed word) [11] (signed word~) main::$1 ← stackpull(signed word)
[11] *((const signed word*) SCREEN+(byte) 1*(const byte) SIZEOF_SIGNED_WORD) ← (signed word~) main::$1 [12] *((const signed word*) SCREEN+(byte) 1*(const byte) SIZEOF_SIGNED_WORD) ← (signed word~) main::$1
to:main::@return to:main::@return
main::@return: scope:[main] from main main::@return: scope:[main] from main
[12] return [13] return
to:@return to:@return
__stackcall (signed word()) next() __stackcall (signed word()) next()
next: scope:[next] from next: scope:[next] from
[13] (signed word) current#5 ← phi( ) [14] (signed word) next::return#0 ← (signed word) current
[14] (signed word) next::return#0 ← (signed word) current#5 [15] (signed word) current ← ++ (signed word) current
to:next::@return to:next::@return
next::@return: scope:[next] from next next::@return: scope:[next] from next
[15] stackidx(signed word,(const byte) next::OFFSET_STACK_RETURN) ← (signed word) next::return#0 [16] stackidx(signed word,(const byte) next::OFFSET_STACK_RETURN) ← (signed word) next::return#0
[16] return [17] return
to:@return to:@return
VARIABLE REGISTER WEIGHTS VARIABLE REGISTER WEIGHTS
(signed word) current (signed word) current loadstore 0.7272727272727273
(signed word) current#5 2.0
(void()) main() (void()) main()
(signed word~) main::$0 4.0 (signed word~) main::$0 4.0
(signed word~) main::$1 4.0 (signed word~) main::$1 4.0
__stackcall (signed word()) next() __stackcall (signed word()) next()
(signed word) next::return (signed word) next::return
(signed word) next::return#0 4.0 (signed word) next::return#0 2.0
Initial phi equivalence classes Initial phi equivalence classes
[ current#5 ] Added variable current to live range equivalence class [ current ]
Added variable main::$0 to live range equivalence class [ main::$0 ] Added variable main::$0 to live range equivalence class [ main::$0 ]
Added variable main::$1 to live range equivalence class [ main::$1 ] Added variable main::$1 to live range equivalence class [ main::$1 ]
Added variable next::return#0 to live range equivalence class [ next::return#0 ] Added variable next::return#0 to live range equivalence class [ next::return#0 ]
Complete equivalence classes Complete equivalence classes
[ current#5 ] [ current ]
[ main::$0 ] [ main::$0 ]
[ main::$1 ] [ main::$1 ]
[ next::return#0 ] [ next::return#0 ]
Allocated zp[2]:2 [ current#5 ] Allocated zp[2]:2 [ current ]
Allocated zp[2]:4 [ main::$0 ] Allocated zp[2]:4 [ main::$0 ]
Allocated zp[2]:6 [ main::$1 ] Allocated zp[2]:6 [ main::$1 ]
Allocated zp[2]:8 [ next::return#0 ] Allocated zp[2]:8 [ next::return#0 ]
@ -224,15 +199,23 @@ Target platform is c64basic / MOS6502X
.label current = 2 .label current = 2
// @begin // @begin
__bbegin: __bbegin:
// [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin:
jmp __b1 jmp __b1
// @1 // @1
__b1: __b1:
// [2] call main // [1] (signed word) current ← (signed word) $30 -- vwsz1=vwsc1
lda #<$30
sta.z current
lda #>$30
sta.z current+1
// [2] phi from @1 to @2 [phi:@1->@2]
__b2_from___b1:
jmp __b2
// @2
__b2:
// [3] call main
jsr main jsr main
// [3] phi from @1 to @end [phi:@1->@end] // [4] phi from @2 to @end [phi:@2->@end]
__bend_from___b1: __bend_from___b2:
jmp __bend jmp __bend
// @end // @end
__bend: __bend:
@ -243,14 +226,14 @@ main: {
// sideeffect stackpushbytes((number) 2) -- _stackpushbyte_2 // sideeffect stackpushbytes((number) 2) -- _stackpushbyte_2
pha pha
pha pha
// [5] callexecute next -- jsr // [6] callexecute next -- jsr
jsr next jsr next
// [6] (signed word~) main::$0 ← stackpull(signed word) -- vwsz1=_stackpullsword_ // [7] (signed word~) main::$0 ← stackpull(signed word) -- vwsz1=_stackpullsword_
pla pla
sta.z __0 sta.z __0
pla pla
sta.z __0+1 sta.z __0+1
// [7] *((const signed word*) SCREEN) ← (signed word~) main::$0 -- _deref_pwsc1=vwsz1 // [8] *((const signed word*) SCREEN) ← (signed word~) main::$0 -- _deref_pwsc1=vwsz1
lda.z __0 lda.z __0
sta SCREEN sta SCREEN
lda.z __0+1 lda.z __0+1
@ -258,14 +241,14 @@ main: {
// sideeffect stackpushbytes((number) 2) -- _stackpushbyte_2 // sideeffect stackpushbytes((number) 2) -- _stackpushbyte_2
pha pha
pha pha
// [9] callexecute next -- jsr // [10] callexecute next -- jsr
jsr next jsr next
// [10] (signed word~) main::$1 ← stackpull(signed word) -- vwsz1=_stackpullsword_ // [11] (signed word~) main::$1 ← stackpull(signed word) -- vwsz1=_stackpullsword_
pla pla
sta.z __1 sta.z __1
pla pla
sta.z __1+1 sta.z __1+1
// [11] *((const signed word*) SCREEN+(byte) 1*(const byte) SIZEOF_SIGNED_WORD) ← (signed word~) main::$1 -- _deref_pwsc1=vwsz1 // [12] *((const signed word*) SCREEN+(byte) 1*(const byte) SIZEOF_SIGNED_WORD) ← (signed word~) main::$1 -- _deref_pwsc1=vwsz1
lda.z __1 lda.z __1
sta SCREEN+1*SIZEOF_SIGNED_WORD sta SCREEN+1*SIZEOF_SIGNED_WORD
lda.z __1+1 lda.z __1+1
@ -273,56 +256,62 @@ main: {
jmp __breturn jmp __breturn
// main::@return // main::@return
__breturn: __breturn:
// [12] return // [13] return
rts rts
} }
// next // next
next: { next: {
.const OFFSET_STACK_RETURN = 0 .const OFFSET_STACK_RETURN = 0
.label return = 8 .label return = 8
// [14] (signed word) next::return#0 ← (signed word) current#5 -- vwsz1=vwsz2 // [14] (signed word) next::return#0 ← (signed word) current -- vwsz1=vwsz2
lda.z current lda.z current
sta.z return sta.z return
lda.z current+1 lda.z current+1
sta.z return+1 sta.z return+1
// [15] (signed word) current ← ++ (signed word) current -- vwsz1=_inc_vwsz1
inc.z current
bne !+
inc.z current+1
!:
jmp __breturn jmp __breturn
// next::@return // next::@return
__breturn: __breturn:
// [15] stackidx(signed word,(const byte) next::OFFSET_STACK_RETURN) ← (signed word) next::return#0 -- _stackidxsword_vbuc1=vwsz1 // [16] stackidx(signed word,(const byte) next::OFFSET_STACK_RETURN) ← (signed word) next::return#0 -- _stackidxsword_vbuc1=vwsz1
tsx tsx
lda.z return lda.z return
sta STACK_BASE+OFFSET_STACK_RETURN,x sta STACK_BASE+OFFSET_STACK_RETURN,x
lda.z return+1 lda.z return+1
sta STACK_BASE+OFFSET_STACK_RETURN+1,x sta STACK_BASE+OFFSET_STACK_RETURN+1,x
// [16] return // [17] return
rts rts
} }
// File Data // File Data
REGISTER UPLIFT POTENTIAL REGISTERS REGISTER UPLIFT POTENTIAL REGISTERS
Statement [6] (signed word~) main::$0 ← stackpull(signed word) [ main::$0 ] ( main:2 [ main::$0 ] ) always clobbers reg byte a Statement [1] (signed word) current ← (signed word) $30 [ current ] ( [ current ] ) always clobbers reg byte a
Statement [7] *((const signed word*) SCREEN) ← (signed word~) main::$0 [ ] ( main:2 [ ] ) always clobbers reg byte a Statement [7] (signed word~) main::$0 ← stackpull(signed word) [ current main::$0 ] ( main:3 [ current main::$0 ] ) always clobbers reg byte a
Statement [10] (signed word~) main::$1 ← stackpull(signed word) [ main::$1 ] ( main:2 [ main::$1 ] ) always clobbers reg byte a Statement [8] *((const signed word*) SCREEN) ← (signed word~) main::$0 [ current ] ( main:3 [ current ] ) always clobbers reg byte a
Statement [11] *((const signed word*) SCREEN+(byte) 1*(const byte) SIZEOF_SIGNED_WORD) ← (signed word~) main::$1 [ ] ( main:2 [ ] ) always clobbers reg byte a Statement [11] (signed word~) main::$1 ← stackpull(signed word) [ main::$1 ] ( main:3 [ main::$1 ] ) always clobbers reg byte a
Statement [14] (signed word) next::return#0 ← (signed word) current#5 [ next::return#0 ] ( main:2::next:5 [ next::return#0 ] main:2::next:9 [ next::return#0 ] ) always clobbers reg byte a Statement [12] *((const signed word*) SCREEN+(byte) 1*(const byte) SIZEOF_SIGNED_WORD) ← (signed word~) main::$1 [ ] ( main:3 [ ] ) always clobbers reg byte a
Statement [15] stackidx(signed word,(const byte) next::OFFSET_STACK_RETURN) ← (signed word) next::return#0 [ ] ( main:2::next:5 [ ] main:2::next:9 [ ] ) always clobbers reg byte a reg byte x Statement [14] (signed word) next::return#0 ← (signed word) current [ current next::return#0 ] ( main:3::next:6 [ current next::return#0 ] main:3::next:10 [ current next::return#0 ] ) always clobbers reg byte a
Potential registers zp[2]:2 [ current#5 ] : zp[2]:2 , Statement [16] stackidx(signed word,(const byte) next::OFFSET_STACK_RETURN) ← (signed word) next::return#0 [ current ] ( main:3::next:6 [ current ] main:3::next:10 [ current ] ) always clobbers reg byte a reg byte x
Potential registers zp[2]:2 [ current ] : zp[2]:2 ,
Potential registers zp[2]:4 [ main::$0 ] : zp[2]:4 , Potential registers zp[2]:4 [ main::$0 ] : zp[2]:4 ,
Potential registers zp[2]:6 [ main::$1 ] : zp[2]:6 , Potential registers zp[2]:6 [ main::$1 ] : zp[2]:6 ,
Potential registers zp[2]:8 [ next::return#0 ] : zp[2]:8 , Potential registers zp[2]:8 [ next::return#0 ] : zp[2]:8 ,
REGISTER UPLIFT SCOPES REGISTER UPLIFT SCOPES
Uplift Scope [main] 4: zp[2]:4 [ main::$0 ] 4: zp[2]:6 [ main::$1 ] Uplift Scope [main] 4: zp[2]:4 [ main::$0 ] 4: zp[2]:6 [ main::$1 ]
Uplift Scope [next] 4: zp[2]:8 [ next::return#0 ] Uplift Scope [next] 2: zp[2]:8 [ next::return#0 ]
Uplift Scope [] 2: zp[2]:2 [ current#5 ] Uplift Scope [] 0.73: zp[2]:2 [ current ]
Uplifting [main] best 140 combination zp[2]:4 [ main::$0 ] zp[2]:6 [ main::$1 ] Uplifting [main] best 192 combination zp[2]:4 [ main::$0 ] zp[2]:6 [ main::$1 ]
Uplifting [next] best 140 combination zp[2]:8 [ next::return#0 ] Uplifting [next] best 192 combination zp[2]:8 [ next::return#0 ]
Uplifting [] best 140 combination zp[2]:2 [ current#5 ] Uplifting [] best 192 combination zp[2]:2 [ current ]
Coalescing zero page register [ zp[2]:2 [ current#5 ] ] with [ zp[2]:8 [ next::return#0 ] ] - score: 1 Coalescing zero page register [ zp[2]:6 [ main::$1 ] ] with [ zp[2]:2 [ current ] ]
Coalescing zero page register [ zp[2]:4 [ main::$0 ] ] with [ zp[2]:2 [ current#5 next::return#0 ] ] Coalescing zero page register [ zp[2]:8 [ next::return#0 ] ] with [ zp[2]:4 [ main::$0 ] ]
Allocated (was zp[2]:4) zp[2]:2 [ main::$0 current#5 next::return#0 ] Allocated (was zp[2]:6) zp[2]:2 [ main::$1 current ]
Allocated (was zp[2]:6) zp[2]:4 [ main::$1 ] Allocated (was zp[2]:8) zp[2]:4 [ next::return#0 main::$0 ]
ASSEMBLER BEFORE OPTIMIZATION ASSEMBLER BEFORE OPTIMIZATION
// File Comments // File Comments
@ -339,33 +328,41 @@ ASSEMBLER BEFORE OPTIMIZATION
.label current = 2 .label current = 2
// @begin // @begin
__bbegin: __bbegin:
// [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin:
jmp __b1 jmp __b1
// @1 // @1
__b1: __b1:
// [2] call main // [1] (signed word) current ← (signed word) $30 -- vwsz1=vwsc1
lda #<$30
sta.z current
lda #>$30
sta.z current+1
// [2] phi from @1 to @2 [phi:@1->@2]
__b2_from___b1:
jmp __b2
// @2
__b2:
// [3] call main
jsr main jsr main
// [3] phi from @1 to @end [phi:@1->@end] // [4] phi from @2 to @end [phi:@2->@end]
__bend_from___b1: __bend_from___b2:
jmp __bend jmp __bend
// @end // @end
__bend: __bend:
// main // main
main: { main: {
.label __0 = 2 .label __0 = 4
.label __1 = 4 .label __1 = 2
// sideeffect stackpushbytes((number) 2) -- _stackpushbyte_2 // sideeffect stackpushbytes((number) 2) -- _stackpushbyte_2
pha pha
pha pha
// [5] callexecute next -- jsr // [6] callexecute next -- jsr
jsr next jsr next
// [6] (signed word~) main::$0 ← stackpull(signed word) -- vwsz1=_stackpullsword_ // [7] (signed word~) main::$0 ← stackpull(signed word) -- vwsz1=_stackpullsword_
pla pla
sta.z __0 sta.z __0
pla pla
sta.z __0+1 sta.z __0+1
// [7] *((const signed word*) SCREEN) ← (signed word~) main::$0 -- _deref_pwsc1=vwsz1 // [8] *((const signed word*) SCREEN) ← (signed word~) main::$0 -- _deref_pwsc1=vwsz1
lda.z __0 lda.z __0
sta SCREEN sta SCREEN
lda.z __0+1 lda.z __0+1
@ -373,14 +370,14 @@ main: {
// sideeffect stackpushbytes((number) 2) -- _stackpushbyte_2 // sideeffect stackpushbytes((number) 2) -- _stackpushbyte_2
pha pha
pha pha
// [9] callexecute next -- jsr // [10] callexecute next -- jsr
jsr next jsr next
// [10] (signed word~) main::$1 ← stackpull(signed word) -- vwsz1=_stackpullsword_ // [11] (signed word~) main::$1 ← stackpull(signed word) -- vwsz1=_stackpullsword_
pla pla
sta.z __1 sta.z __1
pla pla
sta.z __1+1 sta.z __1+1
// [11] *((const signed word*) SCREEN+(byte) 1*(const byte) SIZEOF_SIGNED_WORD) ← (signed word~) main::$1 -- _deref_pwsc1=vwsz1 // [12] *((const signed word*) SCREEN+(byte) 1*(const byte) SIZEOF_SIGNED_WORD) ← (signed word~) main::$1 -- _deref_pwsc1=vwsz1
lda.z __1 lda.z __1
sta SCREEN+1*SIZEOF_SIGNED_WORD sta SCREEN+1*SIZEOF_SIGNED_WORD
lda.z __1+1 lda.z __1+1
@ -388,80 +385,88 @@ main: {
jmp __breturn jmp __breturn
// main::@return // main::@return
__breturn: __breturn:
// [12] return // [13] return
rts rts
} }
// next // next
next: { next: {
.const OFFSET_STACK_RETURN = 0 .const OFFSET_STACK_RETURN = 0
.label return = 2 .label return = 4
// [14] (signed word) next::return#0 ← (signed word) current#5 // [14] (signed word) next::return#0 ← (signed word) current -- vwsz1=vwsz2
lda.z current
sta.z return
lda.z current+1
sta.z return+1
// [15] (signed word) current ← ++ (signed word) current -- vwsz1=_inc_vwsz1
inc.z current
bne !+
inc.z current+1
!:
jmp __breturn jmp __breturn
// next::@return // next::@return
__breturn: __breturn:
// [15] stackidx(signed word,(const byte) next::OFFSET_STACK_RETURN) ← (signed word) next::return#0 -- _stackidxsword_vbuc1=vwsz1 // [16] stackidx(signed word,(const byte) next::OFFSET_STACK_RETURN) ← (signed word) next::return#0 -- _stackidxsword_vbuc1=vwsz1
tsx tsx
lda.z return lda.z return
sta STACK_BASE+OFFSET_STACK_RETURN,x sta STACK_BASE+OFFSET_STACK_RETURN,x
lda.z return+1 lda.z return+1
sta STACK_BASE+OFFSET_STACK_RETURN+1,x sta STACK_BASE+OFFSET_STACK_RETURN+1,x
// [16] return // [17] 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 __bend Removing instruction jmp __bend
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 __b1_from___bbegin:
Removing instruction __b1: Removing instruction __b1:
Removing instruction __bend_from___b1: Removing instruction __b2_from___b1:
Removing instruction __bend_from___b2:
Succesful ASM optimization Pass5RedundantLabelElimination Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __b2:
Removing instruction __bend: Removing instruction __bend:
Removing instruction __breturn: Removing instruction __breturn:
Removing instruction __breturn: Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination Succesful ASM optimization Pass5UnusedLabelElimination
Updating BasicUpstart to call main directly Adding RTS to root block
Removing instruction jsr main Succesful ASM optimization Pass5AddMainRts
Succesful ASM optimization Pass5SkipBegin
Removing instruction __bbegin:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE FINAL SYMBOL TABLE
(label) @1 (label) @1
(label) @2
(label) @begin (label) @begin
(label) @end (label) @end
(const signed word*) SCREEN = (signed word*) 1024 (const signed word*) SCREEN = (signed word*) 1024
(const byte) SIZEOF_SIGNED_WORD = (byte) 2 (const byte) SIZEOF_SIGNED_WORD = (byte) 2
(const word) STACK_BASE = (word) $103 (const word) STACK_BASE = (word) $103
(signed word) current (signed word) current loadstore zp[2]:2 0.7272727272727273
(signed word) current#5 current zp[2]:2 2.0
(void()) main() (void()) main()
(signed word~) main::$0 zp[2]:2 4.0 (signed word~) main::$0 zp[2]:4 4.0
(signed word~) main::$1 zp[2]:4 4.0 (signed word~) main::$1 zp[2]:2 4.0
(label) main::@return (label) main::@return
__stackcall (signed word()) next() __stackcall (signed word()) next()
(label) next::@return (label) next::@return
(const byte) next::OFFSET_STACK_RETURN = (byte) 0 (const byte) next::OFFSET_STACK_RETURN = (byte) 0
(signed word) next::return (signed word) next::return
(signed word) next::return#0 return zp[2]:2 4.0 (signed word) next::return#0 return zp[2]:4 2.0
zp[2]:2 [ main::$0 current#5 next::return#0 ] zp[2]:2 [ main::$1 current ]
zp[2]:4 [ main::$1 ] zp[2]:4 [ next::return#0 main::$0 ]
FINAL ASSEMBLER FINAL ASSEMBLER
Score: 110 Score: 156
// File Comments // File Comments
// Test a procedure with calling convention stack // Test a procedure with calling convention stack
// Return value larger than parameter // Return value larger than parameter
// Upstart // Upstart
.pc = $801 "Basic" .pc = $801 "Basic"
:BasicUpstart(main) :BasicUpstart(__bbegin)
.pc = $80d "Program" .pc = $80d "Program"
// Global Constants & labels // Global Constants & labels
.label SCREEN = $400 .label SCREEN = $400
@ -469,28 +474,38 @@ Score: 110
.const STACK_BASE = $103 .const STACK_BASE = $103
.label current = 2 .label current = 2
// @begin // @begin
// [1] phi from @begin to @1 [phi:@begin->@1] __bbegin:
// @1 // @1
// [2] call main // current = 48
// [3] phi from @1 to @end [phi:@1->@end] // [1] (signed word) current ← (signed word) $30 -- vwsz1=vwsc1
lda #<$30
sta.z current
lda #>$30
sta.z current+1
// [2] phi from @1 to @2 [phi:@1->@2]
// @2
// [3] call main
jsr main
rts
// [4] phi from @2 to @end [phi:@2->@end]
// @end // @end
// main // main
main: { main: {
.label __0 = 2 .label __0 = 4
.label __1 = 4 .label __1 = 2
// next() // next()
// sideeffect stackpushbytes((number) 2) -- _stackpushbyte_2 // sideeffect stackpushbytes((number) 2) -- _stackpushbyte_2
pha pha
pha pha
// [5] callexecute next -- jsr // [6] callexecute next -- jsr
jsr next jsr next
// [6] (signed word~) main::$0 ← stackpull(signed word) -- vwsz1=_stackpullsword_ // [7] (signed word~) main::$0 ← stackpull(signed word) -- vwsz1=_stackpullsword_
pla pla
sta.z __0 sta.z __0
pla pla
sta.z __0+1 sta.z __0+1
// SCREEN[0] = next() // SCREEN[0] = next()
// [7] *((const signed word*) SCREEN) ← (signed word~) main::$0 -- _deref_pwsc1=vwsz1 // [8] *((const signed word*) SCREEN) ← (signed word~) main::$0 -- _deref_pwsc1=vwsz1
lda.z __0 lda.z __0
sta SCREEN sta SCREEN
lda.z __0+1 lda.z __0+1
@ -499,39 +514,48 @@ main: {
// sideeffect stackpushbytes((number) 2) -- _stackpushbyte_2 // sideeffect stackpushbytes((number) 2) -- _stackpushbyte_2
pha pha
pha pha
// [9] callexecute next -- jsr // [10] callexecute next -- jsr
jsr next jsr next
// [10] (signed word~) main::$1 ← stackpull(signed word) -- vwsz1=_stackpullsword_ // [11] (signed word~) main::$1 ← stackpull(signed word) -- vwsz1=_stackpullsword_
pla pla
sta.z __1 sta.z __1
pla pla
sta.z __1+1 sta.z __1+1
// SCREEN[1] = next() // SCREEN[1] = next()
// [11] *((const signed word*) SCREEN+(byte) 1*(const byte) SIZEOF_SIGNED_WORD) ← (signed word~) main::$1 -- _deref_pwsc1=vwsz1 // [12] *((const signed word*) SCREEN+(byte) 1*(const byte) SIZEOF_SIGNED_WORD) ← (signed word~) main::$1 -- _deref_pwsc1=vwsz1
lda.z __1 lda.z __1
sta SCREEN+1*SIZEOF_SIGNED_WORD sta SCREEN+1*SIZEOF_SIGNED_WORD
lda.z __1+1 lda.z __1+1
sta SCREEN+1*SIZEOF_SIGNED_WORD+1 sta SCREEN+1*SIZEOF_SIGNED_WORD+1
// main::@return // main::@return
// } // }
// [12] return // [13] return
rts rts
} }
// next // next
next: { next: {
.const OFFSET_STACK_RETURN = 0 .const OFFSET_STACK_RETURN = 0
.label return = 2 .label return = 4
// return current++; // return current++;
// [14] (signed word) next::return#0 ← (signed word) current#5 // [14] (signed word) next::return#0 ← (signed word) current -- vwsz1=vwsz2
lda.z current
sta.z return
lda.z current+1
sta.z return+1
// [15] (signed word) current ← ++ (signed word) current -- vwsz1=_inc_vwsz1
inc.z current
bne !+
inc.z current+1
!:
// next::@return // next::@return
// } // }
// [15] stackidx(signed word,(const byte) next::OFFSET_STACK_RETURN) ← (signed word) next::return#0 -- _stackidxsword_vbuc1=vwsz1 // [16] stackidx(signed word,(const byte) next::OFFSET_STACK_RETURN) ← (signed word) next::return#0 -- _stackidxsword_vbuc1=vwsz1
tsx tsx
lda.z return lda.z return
sta STACK_BASE+OFFSET_STACK_RETURN,x sta STACK_BASE+OFFSET_STACK_RETURN,x
lda.z return+1 lda.z return+1
sta STACK_BASE+OFFSET_STACK_RETURN+1,x sta STACK_BASE+OFFSET_STACK_RETURN+1,x
// [16] return // [17] return
rts rts
} }
// File Data // File Data

View File

@ -1,20 +1,20 @@
(label) @1 (label) @1
(label) @2
(label) @begin (label) @begin
(label) @end (label) @end
(const signed word*) SCREEN = (signed word*) 1024 (const signed word*) SCREEN = (signed word*) 1024
(const byte) SIZEOF_SIGNED_WORD = (byte) 2 (const byte) SIZEOF_SIGNED_WORD = (byte) 2
(const word) STACK_BASE = (word) $103 (const word) STACK_BASE = (word) $103
(signed word) current (signed word) current loadstore zp[2]:2 0.7272727272727273
(signed word) current#5 current zp[2]:2 2.0
(void()) main() (void()) main()
(signed word~) main::$0 zp[2]:2 4.0 (signed word~) main::$0 zp[2]:4 4.0
(signed word~) main::$1 zp[2]:4 4.0 (signed word~) main::$1 zp[2]:2 4.0
(label) main::@return (label) main::@return
__stackcall (signed word()) next() __stackcall (signed word()) next()
(label) next::@return (label) next::@return
(const byte) next::OFFSET_STACK_RETURN = (byte) 0 (const byte) next::OFFSET_STACK_RETURN = (byte) 0
(signed word) next::return (signed word) next::return
(signed word) next::return#0 return zp[2]:2 4.0 (signed word) next::return#0 return zp[2]:4 2.0
zp[2]:2 [ main::$0 current#5 next::return#0 ] zp[2]:2 [ main::$1 current ]
zp[2]:4 [ main::$1 ] zp[2]:4 [ next::return#0 main::$0 ]

View File

@ -5,39 +5,28 @@
.pc = $80d "Program" .pc = $80d "Program"
.label SCREEN = $400 .label SCREEN = $400
printline: { printline: {
.label i = 2 ldx #0
// i=0
lda #0
sta.z i
__b1: __b1:
// for(char i=0; i<40; i++) // for(char i=0; i<40; i++)
lda.z i cpx #$28
cmp #$28
bcc __b2 bcc __b2
// } // }
rts rts
__b2: __b2:
// SCREEN[i] = '*' // SCREEN[i] = '*'
lda #'*' lda #'*'
ldy.z i sta SCREEN,x
sta SCREEN,y
// for(char i=0; i<40; i++) // for(char i=0; i<40; i++)
inc.z i inx
jmp __b1 jmp __b1
} }
main: { main: {
.label val = 3
// val
lda #0
sta.z val
// val = *SCREEN // val = *SCREEN
lda SCREEN ldy SCREEN
sta.z val
// printline() // printline()
jsr printline jsr printline
// SCREEN[80] = val // SCREEN[80] = val
lda.z val sty SCREEN+$50
sta SCREEN+$50
// } // }
rts rts
} }

View File

@ -10,25 +10,25 @@
__stackcall (void()) printline() __stackcall (void()) printline()
printline: scope:[printline] from printline: scope:[printline] from
[4] (byte) printline::i ← (byte) 0 [4] phi()
to:printline::@1 to:printline::@1
printline::@1: scope:[printline] from printline printline::@2 printline::@1: scope:[printline] from printline printline::@2
[5] if((byte) printline::i<(byte) $28) goto printline::@2 [5] (byte) printline::i#2 ← phi( printline/(byte) 0 printline::@2/(byte) printline::i#1 )
[6] if((byte) printline::i#2<(byte) $28) goto printline::@2
to:printline::@return to:printline::@return
printline::@return: scope:[printline] from printline::@1 printline::@return: scope:[printline] from printline::@1
[6] return [7] return
to:@return to:@return
printline::@2: scope:[printline] from printline::@1 printline::@2: scope:[printline] from printline::@1
[7] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' [8] *((const byte*) SCREEN + (byte) printline::i#2) ← (byte) '*'
[8] (byte) printline::i ← ++ (byte) printline::i [9] (byte) printline::i#1 ← ++ (byte) printline::i#2
to:printline::@1 to:printline::@1
__stackcall (void()) main() __stackcall (void()) main()
main: scope:[main] from main: scope:[main] from
[9] (byte) main::val ← (byte) 0 [10] (byte) main::val#1 ← *((const byte*) SCREEN)
[10] (byte) main::val ← *((const byte*) SCREEN)
[11] callexecute printline [11] callexecute printline
[12] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val [12] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val#1
to:main::@return to:main::@return
main::@return: scope:[main] from main main::@return: scope:[main] from main
[13] return [13] return

View File

@ -12,10 +12,10 @@ CONTROL FLOW GRAPH SSA
__stackcall (void()) main() __stackcall (void()) main()
main: scope:[main] from main: scope:[main] from
(byte) main::val ← (byte) 0 (byte) main::val#0 ← (byte) 0
(byte) main::val ← *((const byte*) SCREEN) (byte) main::val#1 ← *((const byte*) SCREEN)
callexecute printline callexecute printline
*((const byte*) SCREEN + (number) $50) ← (byte) main::val *((const byte*) SCREEN + (number) $50) ← (byte) main::val#1
to:main::@return to:main::@return
main::@return: scope:[main] from main main::@return: scope:[main] from main
return return
@ -23,15 +23,17 @@ main::@return: scope:[main] from main
__stackcall (void()) printline() __stackcall (void()) printline()
printline: scope:[printline] from printline: scope:[printline] from
(byte) printline::i ← (byte) 0 (byte) printline::i#0 ← (byte) 0
to:printline::@1 to:printline::@1
printline::@1: scope:[printline] from printline printline::@2 printline::@1: scope:[printline] from printline printline::@2
(bool~) printline::$0 ← (byte) printline::i < (number) $28 (byte) printline::i#2 ← phi( printline/(byte) printline::i#0 printline::@2/(byte) printline::i#1 )
(bool~) printline::$0 ← (byte) printline::i#2 < (number) $28
if((bool~) printline::$0) goto printline::@2 if((bool~) printline::$0) goto printline::@2
to:printline::@return to:printline::@return
printline::@2: scope:[printline] from printline::@1 printline::@2: scope:[printline] from printline::@1
*((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' (byte) printline::i#3 ← phi( printline::@1/(byte) printline::i#2 )
(byte) printline::i ← ++ (byte) printline::i *((const byte*) SCREEN + (byte) printline::i#3) ← (byte) '*'
(byte) printline::i#1 ← ++ (byte) printline::i#3
to:printline::@1 to:printline::@1
printline::@return: scope:[printline] from printline::@1 printline::@return: scope:[printline] from printline::@1
return return
@ -48,16 +50,22 @@ SYMBOL TABLE SSA
(const byte*) SCREEN = (byte*)(number) $400 (const byte*) SCREEN = (byte*)(number) $400
__stackcall (void()) main() __stackcall (void()) main()
(label) main::@return (label) main::@return
(byte) main::val loadstore (byte) main::val
(byte) main::val#0
(byte) main::val#1
__stackcall (void()) printline() __stackcall (void()) printline()
(bool~) printline::$0 (bool~) printline::$0
(label) printline::@1 (label) printline::@1
(label) printline::@2 (label) printline::@2
(label) printline::@return (label) printline::@return
(byte) printline::i loadstore (byte) printline::i
(byte) printline::i#0
(byte) printline::i#1
(byte) printline::i#2
(byte) printline::i#3
Adding number conversion cast (unumber) $50 in *((const byte*) SCREEN + (number) $50) ← (byte) main::val Adding number conversion cast (unumber) $50 in *((const byte*) SCREEN + (number) $50) ← (byte) main::val#1
Adding number conversion cast (unumber) $28 in (bool~) printline::$0 ← (byte) printline::i < (number) $28 Adding number conversion cast (unumber) $28 in (bool~) printline::$0 ← (byte) printline::i#2 < (number) $28
Successful SSA optimization PassNAddNumberTypeConversions Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant pointer cast (byte*) 1024 Simplifying constant pointer cast (byte*) 1024
Simplifying constant integer cast $50 Simplifying constant integer cast $50
@ -66,23 +74,36 @@ Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) $50 Finalized unsigned number type (byte) $50
Finalized unsigned number type (byte) $28 Finalized unsigned number type (byte) $28
Successful SSA optimization PassNFinalizeNumberTypeConversions Successful SSA optimization PassNFinalizeNumberTypeConversions
Simple Condition (bool~) printline::$0 [7] if((byte) printline::i<(byte) $28) goto printline::@2 Alias (byte) printline::i#2 = (byte) printline::i#3
Successful SSA optimization Pass2AliasElimination
Simple Condition (bool~) printline::$0 [8] if((byte) printline::i#2<(byte) $28) goto printline::@2
Successful SSA optimization Pass2ConditionalJumpSimplification Successful SSA optimization Pass2ConditionalJumpSimplification
Constant (const byte) main::val#0 = 0
Constant (const byte) printline::i#0 = 0
Successful SSA optimization Pass2ConstantIdentification
Eliminating unused constant (const byte) main::val#0
Successful SSA optimization PassNEliminateUnusedVars
Inlining constant with var siblings (const byte) printline::i#0
Constant inlined printline::i#0 = (byte) 0
Successful SSA optimization Pass2ConstantInlining
Consolidated array index constant in *(SCREEN+$50) Consolidated array index constant in *(SCREEN+$50)
Successful SSA optimization Pass2ConstantAdditionElimination Successful SSA optimization Pass2ConstantAdditionElimination
Adding NOP phi() at start of @begin Adding NOP phi() at start of @begin
Adding NOP phi() at start of @2 Adding NOP phi() at start of @2
Adding NOP phi() at start of @end Adding NOP phi() at start of @end
Adding NOP phi() at start of printline
CALL GRAPH CALL GRAPH
Calls in [] to main:2 Calls in [] to main:2
Calls in [main] to printline:11 Calls in [main] to printline:12
Created 0 initial phi equivalence classes Created 1 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes Coalesced [10] printline::i#4 ← printline::i#1
Coalesced down to 1 phi equivalence classes
Renumbering block @2 to @1 Renumbering block @2 to @1
Adding NOP phi() at start of @begin Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1 Adding NOP phi() at start of @1
Adding NOP phi() at start of @end Adding NOP phi() at start of @end
Adding NOP phi() at start of printline
FINAL CONTROL FLOW GRAPH FINAL CONTROL FLOW GRAPH
@begin: scope:[] from @begin: scope:[] from
@ -97,25 +118,25 @@ FINAL CONTROL FLOW GRAPH
__stackcall (void()) printline() __stackcall (void()) printline()
printline: scope:[printline] from printline: scope:[printline] from
[4] (byte) printline::i ← (byte) 0 [4] phi()
to:printline::@1 to:printline::@1
printline::@1: scope:[printline] from printline printline::@2 printline::@1: scope:[printline] from printline printline::@2
[5] if((byte) printline::i<(byte) $28) goto printline::@2 [5] (byte) printline::i#2 ← phi( printline/(byte) 0 printline::@2/(byte) printline::i#1 )
[6] if((byte) printline::i#2<(byte) $28) goto printline::@2
to:printline::@return to:printline::@return
printline::@return: scope:[printline] from printline::@1 printline::@return: scope:[printline] from printline::@1
[6] return [7] return
to:@return to:@return
printline::@2: scope:[printline] from printline::@1 printline::@2: scope:[printline] from printline::@1
[7] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' [8] *((const byte*) SCREEN + (byte) printline::i#2) ← (byte) '*'
[8] (byte) printline::i ← ++ (byte) printline::i [9] (byte) printline::i#1 ← ++ (byte) printline::i#2
to:printline::@1 to:printline::@1
__stackcall (void()) main() __stackcall (void()) main()
main: scope:[main] from main: scope:[main] from
[9] (byte) main::val ← (byte) 0 [10] (byte) main::val#1 ← *((const byte*) SCREEN)
[10] (byte) main::val ← *((const byte*) SCREEN)
[11] callexecute printline [11] callexecute printline
[12] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val [12] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val#1
to:main::@return to:main::@return
main::@return: scope:[main] from main main::@return: scope:[main] from main
[13] return [13] return
@ -124,18 +145,21 @@ main::@return: scope:[main] from main
VARIABLE REGISTER WEIGHTS VARIABLE REGISTER WEIGHTS
__stackcall (void()) main() __stackcall (void()) main()
(byte) main::val loadstore 3.0 (byte) main::val
(byte) main::val#1 2.0
__stackcall (void()) printline() __stackcall (void()) printline()
(byte) printline::i loadstore 11.5 (byte) printline::i
(byte) printline::i#1 22.0
(byte) printline::i#2 14.666666666666666
Initial phi equivalence classes Initial phi equivalence classes
Added variable printline::i to live range equivalence class [ printline::i ] [ printline::i#2 printline::i#1 ]
Added variable main::val to live range equivalence class [ main::val ] Added variable main::val#1 to live range equivalence class [ main::val#1 ]
Complete equivalence classes Complete equivalence classes
[ printline::i ] [ printline::i#2 printline::i#1 ]
[ main::val ] [ main::val#1 ]
Allocated zp[1]:2 [ printline::i ] Allocated zp[1]:2 [ printline::i#2 printline::i#1 ]
Allocated zp[1]:3 [ main::val ] Allocated zp[1]:3 [ main::val#1 ]
INITIAL ASM INITIAL ASM
Target platform is c64basic / MOS6502X Target platform is c64basic / MOS6502X
@ -165,43 +189,45 @@ __bend:
// printline // printline
printline: { printline: {
.label i = 2 .label i = 2
// [4] (byte) printline::i ← (byte) 0 -- vbuz1=vbuc1 // [5] phi from printline to printline::@1 [phi:printline->printline::@1]
__b1_from_printline:
// [5] phi (byte) printline::i#2 = (byte) 0 [phi:printline->printline::@1#0] -- vbuz1=vbuc1
lda #0 lda #0
sta.z i sta.z i
jmp __b1 jmp __b1
// printline::@1 // printline::@1
__b1: __b1:
// [5] if((byte) printline::i<(byte) $28) goto printline::@2 -- vbuz1_lt_vbuc1_then_la1 // [6] if((byte) printline::i#2<(byte) $28) goto printline::@2 -- vbuz1_lt_vbuc1_then_la1
lda.z i lda.z i
cmp #$28 cmp #$28
bcc __b2 bcc __b2
jmp __breturn jmp __breturn
// printline::@return // printline::@return
__breturn: __breturn:
// [6] return // [7] return
rts rts
// printline::@2 // printline::@2
__b2: __b2:
// [7] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' -- pbuc1_derefidx_vbuz1=vbuc2 // [8] *((const byte*) SCREEN + (byte) printline::i#2) ← (byte) '*' -- pbuc1_derefidx_vbuz1=vbuc2
lda #'*' lda #'*'
ldy.z i ldy.z i
sta SCREEN,y sta SCREEN,y
// [8] (byte) printline::i ← ++ (byte) printline::i -- vbuz1=_inc_vbuz1 // [9] (byte) printline::i#1 ← ++ (byte) printline::i#2 -- vbuz1=_inc_vbuz1
inc.z i inc.z i
// [5] phi from printline::@2 to printline::@1 [phi:printline::@2->printline::@1]
__b1_from___b2:
// [5] phi (byte) printline::i#2 = (byte) printline::i#1 [phi:printline::@2->printline::@1#0] -- register_copy
jmp __b1 jmp __b1
} }
// main // main
main: { main: {
.label val = 3 .label val = 3
// [9] (byte) main::val ← (byte) 0 -- vbuz1=vbuc1 // [10] (byte) main::val#1 ← *((const byte*) SCREEN) -- vbuz1=_deref_pbuc1
lda #0
sta.z val
// [10] (byte) main::val ← *((const byte*) SCREEN) -- vbuz1=_deref_pbuc1
lda SCREEN lda SCREEN
sta.z val sta.z val
// [11] callexecute printline -- jsr // [11] callexecute printline -- jsr
jsr printline jsr printline
// [12] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val -- _deref_pbuc1=vbuz1 // [12] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val#1 -- _deref_pbuc1=vbuz1
lda.z val lda.z val
sta SCREEN+$50 sta SCREEN+$50
jmp __breturn jmp __breturn
@ -213,27 +239,21 @@ main: {
// File Data // File Data
REGISTER UPLIFT POTENTIAL REGISTERS REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] (byte) printline::i ← (byte) 0 [ printline::i ] ( main:2::printline:11 [ main::val printline::i ] ) always clobbers reg byte a Statement [8] *((const byte*) SCREEN + (byte) printline::i#2) ← (byte) '*' [ printline::i#2 ] ( main:2::printline:11 [ main::val#1 printline::i#2 ] ) always clobbers reg byte a
Statement [5] if((byte) printline::i<(byte) $28) goto printline::@2 [ printline::i ] ( main:2::printline:11 [ main::val printline::i ] ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:3 [ main::val#1 ]
Statement [7] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' [ printline::i ] ( main:2::printline:11 [ main::val printline::i ] ) always clobbers reg byte a reg byte y Removing always clobbered register reg byte a as potential for zp[1]:2 [ printline::i#2 printline::i#1 ]
Statement [9] (byte) main::val ← (byte) 0 [ ] ( main:2 [ ] ) always clobbers reg byte a Statement [8] *((const byte*) SCREEN + (byte) printline::i#2) ← (byte) '*' [ printline::i#2 ] ( main:2::printline:11 [ main::val#1 printline::i#2 ] ) always clobbers reg byte a
Statement [10] (byte) main::val ← *((const byte*) SCREEN) [ main::val ] ( main:2 [ main::val ] ) always clobbers reg byte a Potential registers zp[1]:2 [ printline::i#2 printline::i#1 ] : zp[1]:2 , reg byte x , reg byte y ,
Statement [12] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val [ ] ( main:2 [ ] ) always clobbers reg byte a Potential registers zp[1]:3 [ main::val#1 ] : zp[1]:3 , reg byte x , reg byte y ,
Potential registers zp[1]:2 [ printline::i ] : zp[1]:2 ,
Potential registers zp[1]:3 [ main::val ] : zp[1]:3 ,
REGISTER UPLIFT SCOPES REGISTER UPLIFT SCOPES
Uplift Scope [printline] 11.5: zp[1]:2 [ printline::i ] Uplift Scope [printline] 36.67: zp[1]:2 [ printline::i#2 printline::i#1 ]
Uplift Scope [main] 3: zp[1]:3 [ main::val ] Uplift Scope [main] 2: zp[1]:3 [ main::val#1 ]
Uplift Scope [] Uplift Scope []
Uplifting [printline] best 345 combination zp[1]:2 [ printline::i ] Uplifting [printline] best 292 combination reg byte x [ printline::i#2 printline::i#1 ]
Uplifting [main] best 345 combination zp[1]:3 [ main::val ] Uplifting [main] best 286 combination reg byte y [ main::val#1 ]
Uplifting [] best 345 combination Uplifting [] best 286 combination
Attempting to uplift remaining variables inzp[1]:2 [ printline::i ]
Uplifting [printline] best 345 combination zp[1]:2 [ printline::i ]
Attempting to uplift remaining variables inzp[1]:3 [ main::val ]
Uplifting [main] best 345 combination zp[1]:3 [ main::val ]
ASSEMBLER BEFORE OPTIMIZATION ASSEMBLER BEFORE OPTIMIZATION
// File Comments // File Comments
@ -261,46 +281,41 @@ __bend_from___b1:
__bend: __bend:
// printline // printline
printline: { printline: {
.label i = 2 // [5] phi from printline to printline::@1 [phi:printline->printline::@1]
// [4] (byte) printline::i ← (byte) 0 -- vbuz1=vbuc1 __b1_from_printline:
lda #0 // [5] phi (byte) printline::i#2 = (byte) 0 [phi:printline->printline::@1#0] -- vbuxx=vbuc1
sta.z i ldx #0
jmp __b1 jmp __b1
// printline::@1 // printline::@1
__b1: __b1:
// [5] if((byte) printline::i<(byte) $28) goto printline::@2 -- vbuz1_lt_vbuc1_then_la1 // [6] if((byte) printline::i#2<(byte) $28) goto printline::@2 -- vbuxx_lt_vbuc1_then_la1
lda.z i cpx #$28
cmp #$28
bcc __b2 bcc __b2
jmp __breturn jmp __breturn
// printline::@return // printline::@return
__breturn: __breturn:
// [6] return // [7] return
rts rts
// printline::@2 // printline::@2
__b2: __b2:
// [7] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' -- pbuc1_derefidx_vbuz1=vbuc2 // [8] *((const byte*) SCREEN + (byte) printline::i#2) ← (byte) '*' -- pbuc1_derefidx_vbuxx=vbuc2
lda #'*' lda #'*'
ldy.z i sta SCREEN,x
sta SCREEN,y // [9] (byte) printline::i#1 ← ++ (byte) printline::i#2 -- vbuxx=_inc_vbuxx
// [8] (byte) printline::i ← ++ (byte) printline::i -- vbuz1=_inc_vbuz1 inx
inc.z i // [5] phi from printline::@2 to printline::@1 [phi:printline::@2->printline::@1]
__b1_from___b2:
// [5] phi (byte) printline::i#2 = (byte) printline::i#1 [phi:printline::@2->printline::@1#0] -- register_copy
jmp __b1 jmp __b1
} }
// main // main
main: { main: {
.label val = 3 // [10] (byte) main::val#1 ← *((const byte*) SCREEN) -- vbuyy=_deref_pbuc1
// [9] (byte) main::val ← (byte) 0 -- vbuz1=vbuc1 ldy SCREEN
lda #0
sta.z val
// [10] (byte) main::val ← *((const byte*) SCREEN) -- vbuz1=_deref_pbuc1
lda SCREEN
sta.z val
// [11] callexecute printline -- jsr // [11] callexecute printline -- jsr
jsr printline jsr printline
// [12] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val -- _deref_pbuc1=vbuz1 // [12] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val#1 -- _deref_pbuc1=vbuyy
lda.z val sty SCREEN+$50
sta SCREEN+$50
jmp __breturn jmp __breturn
// main::@return // main::@return
__breturn: __breturn:
@ -321,7 +336,9 @@ Removing instruction __b1:
Removing instruction __bend_from___b1: Removing instruction __bend_from___b1:
Succesful ASM optimization Pass5RedundantLabelElimination Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __bend: Removing instruction __bend:
Removing instruction __b1_from_printline:
Removing instruction __breturn: Removing instruction __breturn:
Removing instruction __b1_from___b2:
Removing instruction __breturn: Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination Succesful ASM optimization Pass5UnusedLabelElimination
Updating BasicUpstart to call main directly Updating BasicUpstart to call main directly
@ -337,19 +354,22 @@ FINAL SYMBOL TABLE
(const byte*) SCREEN = (byte*) 1024 (const byte*) SCREEN = (byte*) 1024
__stackcall (void()) main() __stackcall (void()) main()
(label) main::@return (label) main::@return
(byte) main::val loadstore zp[1]:3 3.0 (byte) main::val
(byte) main::val#1 reg byte y 2.0
__stackcall (void()) printline() __stackcall (void()) printline()
(label) printline::@1 (label) printline::@1
(label) printline::@2 (label) printline::@2
(label) printline::@return (label) printline::@return
(byte) printline::i loadstore zp[1]:2 11.5 (byte) printline::i
(byte) printline::i#1 reg byte x 22.0
(byte) printline::i#2 reg byte x 14.666666666666666
zp[1]:2 [ printline::i ] reg byte x [ printline::i#2 printline::i#1 ]
zp[1]:3 [ main::val ] reg byte y [ main::val#1 ]
FINAL ASSEMBLER FINAL ASSEMBLER
Score: 297 Score: 211
// File Comments // File Comments
// Test a procedure with calling convention stack // Test a procedure with calling convention stack
@ -368,52 +388,43 @@ Score: 297
// @end // @end
// printline // printline
printline: { printline: {
.label i = 2 // [5] phi from printline to printline::@1 [phi:printline->printline::@1]
// i=0 // [5] phi (byte) printline::i#2 = (byte) 0 [phi:printline->printline::@1#0] -- vbuxx=vbuc1
// [4] (byte) printline::i ← (byte) 0 -- vbuz1=vbuc1 ldx #0
lda #0
sta.z i
// printline::@1 // printline::@1
__b1: __b1:
// for(char i=0; i<40; i++) // for(char i=0; i<40; i++)
// [5] if((byte) printline::i<(byte) $28) goto printline::@2 -- vbuz1_lt_vbuc1_then_la1 // [6] if((byte) printline::i#2<(byte) $28) goto printline::@2 -- vbuxx_lt_vbuc1_then_la1
lda.z i cpx #$28
cmp #$28
bcc __b2 bcc __b2
// printline::@return // printline::@return
// } // }
// [6] return // [7] return
rts rts
// printline::@2 // printline::@2
__b2: __b2:
// SCREEN[i] = '*' // SCREEN[i] = '*'
// [7] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' -- pbuc1_derefidx_vbuz1=vbuc2 // [8] *((const byte*) SCREEN + (byte) printline::i#2) ← (byte) '*' -- pbuc1_derefidx_vbuxx=vbuc2
lda #'*' lda #'*'
ldy.z i sta SCREEN,x
sta SCREEN,y
// for(char i=0; i<40; i++) // for(char i=0; i<40; i++)
// [8] (byte) printline::i ← ++ (byte) printline::i -- vbuz1=_inc_vbuz1 // [9] (byte) printline::i#1 ← ++ (byte) printline::i#2 -- vbuxx=_inc_vbuxx
inc.z i inx
// [5] phi from printline::@2 to printline::@1 [phi:printline::@2->printline::@1]
// [5] phi (byte) printline::i#2 = (byte) printline::i#1 [phi:printline::@2->printline::@1#0] -- register_copy
jmp __b1 jmp __b1
} }
// main // main
main: { main: {
.label val = 3
// val
// [9] (byte) main::val ← (byte) 0 -- vbuz1=vbuc1
lda #0
sta.z val
// val = *SCREEN // val = *SCREEN
// [10] (byte) main::val ← *((const byte*) SCREEN) -- vbuz1=_deref_pbuc1 // [10] (byte) main::val#1 ← *((const byte*) SCREEN) -- vbuyy=_deref_pbuc1
lda SCREEN ldy SCREEN
sta.z val
// printline() // printline()
// [11] callexecute printline -- jsr // [11] callexecute printline -- jsr
jsr printline jsr printline
// SCREEN[80] = val // SCREEN[80] = val
// [12] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val -- _deref_pbuc1=vbuz1 // [12] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val#1 -- _deref_pbuc1=vbuyy
lda.z val sty SCREEN+$50
sta SCREEN+$50
// main::@return // main::@return
// } // }
// [13] return // [13] return

View File

@ -4,12 +4,15 @@
(const byte*) SCREEN = (byte*) 1024 (const byte*) SCREEN = (byte*) 1024
__stackcall (void()) main() __stackcall (void()) main()
(label) main::@return (label) main::@return
(byte) main::val loadstore zp[1]:3 3.0 (byte) main::val
(byte) main::val#1 reg byte y 2.0
__stackcall (void()) printline() __stackcall (void()) printline()
(label) printline::@1 (label) printline::@1
(label) printline::@2 (label) printline::@2
(label) printline::@return (label) printline::@return
(byte) printline::i loadstore zp[1]:2 11.5 (byte) printline::i
(byte) printline::i#1 reg byte x 22.0
(byte) printline::i#2 reg byte x 14.666666666666666
zp[1]:2 [ printline::i ] reg byte x [ printline::i#2 printline::i#1 ]
zp[1]:3 [ main::val ] reg byte y [ main::val#1 ]

View File

@ -12,24 +12,19 @@ __bbegin:
jsr main jsr main
rts rts
printline: { printline: {
.label i = 3 ldx #0
// i=0
lda #0
sta.z i
__b1: __b1:
// for(char i=0; i<40; i++) // for(char i=0; i<40; i++)
lda.z i cpx #$28
cmp #$28
bcc __b2 bcc __b2
// } // }
rts rts
__b2: __b2:
// SCREEN[i] = '*' // SCREEN[i] = '*'
lda #'*' lda #'*'
ldy.z i sta SCREEN,x
sta SCREEN,y
// for(char i=0; i<40; i++) // for(char i=0; i<40; i++)
inc.z i inx
jmp __b1 jmp __b1
} }
main: { main: {

View File

@ -10,25 +10,26 @@
__stackcall (void()) printline() __stackcall (void()) printline()
printline: scope:[printline] from printline: scope:[printline] from
[4] (byte) printline::i ← (byte) 0 [4] phi()
to:printline::@1 to:printline::@1
printline::@1: scope:[printline] from printline printline::@2 printline::@1: scope:[printline] from printline printline::@2
[5] if((byte) printline::i<(byte) $28) goto printline::@2 [5] (byte) printline::i#2 ← phi( printline/(byte) 0 printline::@2/(byte) printline::i#1 )
[6] if((byte) printline::i#2<(byte) $28) goto printline::@2
to:printline::@return to:printline::@return
printline::@return: scope:[printline] from printline::@1 printline::@return: scope:[printline] from printline::@1
[6] return [7] return
to:@return to:@return
printline::@2: scope:[printline] from printline::@1 printline::@2: scope:[printline] from printline::@1
[7] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' [8] *((const byte*) SCREEN + (byte) printline::i#2) ← (byte) '*'
[8] (byte) printline::i ← ++ (byte) printline::i [9] (byte) printline::i#1 ← ++ (byte) printline::i#2
to:printline::@1 to:printline::@1
__stackcall (void()) main() __stackcall (void()) main()
main: scope:[main] from main: scope:[main] from
[9] (byte) val ← (byte) '-' [10] (byte) val ← (byte) '-'
[10] callexecute printline [11] callexecute printline
[11] *((const byte*) SCREEN+(byte) $50) ← (byte) val [12] *((const byte*) SCREEN+(byte) $50) ← (byte) val
to:main::@return to:main::@return
main::@return: scope:[main] from main main::@return: scope:[main] from main
[12] return [13] return
to:@return to:@return

View File

@ -3,6 +3,7 @@ Culled Empty Block (label) printline::@4
Culled Empty Block (label) printline::@3 Culled Empty Block (label) printline::@3
Culled Empty Block (label) printline::@5 Culled Empty Block (label) printline::@5
Culled Empty Block (label) printline::@6 Culled Empty Block (label) printline::@6
Converting PHI-variable modified inside __stackcall procedure main() to load/store (byte) val
Calling convention STACK_CALL adding prepare/execute/finalize for call printline Calling convention STACK_CALL adding prepare/execute/finalize for call printline
Calling convention STACK_CALL adding prepare/execute/finalize for call main Calling convention STACK_CALL adding prepare/execute/finalize for call main
@ -23,15 +24,17 @@ main::@return: scope:[main] from main
__stackcall (void()) printline() __stackcall (void()) printline()
printline: scope:[printline] from printline: scope:[printline] from
(byte) printline::i ← (byte) 0 (byte) printline::i#0 ← (byte) 0
to:printline::@1 to:printline::@1
printline::@1: scope:[printline] from printline printline::@2 printline::@1: scope:[printline] from printline printline::@2
(bool~) printline::$0 ← (byte) printline::i < (number) $28 (byte) printline::i#2 ← phi( printline/(byte) printline::i#0 printline::@2/(byte) printline::i#1 )
(bool~) printline::$0 ← (byte) printline::i#2 < (number) $28
if((bool~) printline::$0) goto printline::@2 if((bool~) printline::$0) goto printline::@2
to:printline::@return to:printline::@return
printline::@2: scope:[printline] from printline::@1 printline::@2: scope:[printline] from printline::@1
*((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' (byte) printline::i#3 ← phi( printline::@1/(byte) printline::i#2 )
(byte) printline::i ← ++ (byte) printline::i *((const byte*) SCREEN + (byte) printline::i#3) ← (byte) '*'
(byte) printline::i#1 ← ++ (byte) printline::i#3
to:printline::@1 to:printline::@1
printline::@return: scope:[printline] from printline::@1 printline::@return: scope:[printline] from printline::@1
return return
@ -53,11 +56,15 @@ __stackcall (void()) printline()
(label) printline::@1 (label) printline::@1
(label) printline::@2 (label) printline::@2
(label) printline::@return (label) printline::@return
(byte) printline::i loadstore (byte) printline::i
(byte) printline::i#0
(byte) printline::i#1
(byte) printline::i#2
(byte) printline::i#3
(byte) val loadstore (byte) val loadstore
Adding number conversion cast (unumber) $50 in *((const byte*) SCREEN + (number) $50) ← (byte) val Adding number conversion cast (unumber) $50 in *((const byte*) SCREEN + (number) $50) ← (byte) val
Adding number conversion cast (unumber) $28 in (bool~) printline::$0 ← (byte) printline::i < (number) $28 Adding number conversion cast (unumber) $28 in (bool~) printline::$0 ← (byte) printline::i#2 < (number) $28
Successful SSA optimization PassNAddNumberTypeConversions Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant pointer cast (byte*) 1024 Simplifying constant pointer cast (byte*) 1024
Simplifying constant integer cast $50 Simplifying constant integer cast $50
@ -66,21 +73,31 @@ Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) $50 Finalized unsigned number type (byte) $50
Finalized unsigned number type (byte) $28 Finalized unsigned number type (byte) $28
Successful SSA optimization PassNFinalizeNumberTypeConversions Successful SSA optimization PassNFinalizeNumberTypeConversions
Simple Condition (bool~) printline::$0 [7] if((byte) printline::i<(byte) $28) goto printline::@2 Alias (byte) printline::i#2 = (byte) printline::i#3
Successful SSA optimization Pass2AliasElimination
Simple Condition (bool~) printline::$0 [8] if((byte) printline::i#2<(byte) $28) goto printline::@2
Successful SSA optimization Pass2ConditionalJumpSimplification Successful SSA optimization Pass2ConditionalJumpSimplification
Constant (const byte) printline::i#0 = 0
Successful SSA optimization Pass2ConstantIdentification
Inlining constant with var siblings (const byte) printline::i#0
Constant inlined printline::i#0 = (byte) 0
Successful SSA optimization Pass2ConstantInlining
Consolidated array index constant in *(SCREEN+$50) Consolidated array index constant in *(SCREEN+$50)
Successful SSA optimization Pass2ConstantAdditionElimination Successful SSA optimization Pass2ConstantAdditionElimination
Adding NOP phi() at start of @2 Adding NOP phi() at start of @2
Adding NOP phi() at start of @end Adding NOP phi() at start of @end
Adding NOP phi() at start of printline
CALL GRAPH CALL GRAPH
Calls in [] to main:2 Calls in [] to main:2
Calls in [main] to printline:10 Calls in [main] to printline:12
Created 0 initial phi equivalence classes Created 1 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes Coalesced [10] printline::i#4 ← printline::i#1
Coalesced down to 1 phi equivalence classes
Renumbering block @2 to @1 Renumbering block @2 to @1
Adding NOP phi() at start of @1 Adding NOP phi() at start of @1
Adding NOP phi() at start of @end Adding NOP phi() at start of @end
Adding NOP phi() at start of printline
FINAL CONTROL FLOW GRAPH FINAL CONTROL FLOW GRAPH
@begin: scope:[] from @begin: scope:[] from
@ -95,44 +112,47 @@ FINAL CONTROL FLOW GRAPH
__stackcall (void()) printline() __stackcall (void()) printline()
printline: scope:[printline] from printline: scope:[printline] from
[4] (byte) printline::i ← (byte) 0 [4] phi()
to:printline::@1 to:printline::@1
printline::@1: scope:[printline] from printline printline::@2 printline::@1: scope:[printline] from printline printline::@2
[5] if((byte) printline::i<(byte) $28) goto printline::@2 [5] (byte) printline::i#2 ← phi( printline/(byte) 0 printline::@2/(byte) printline::i#1 )
[6] if((byte) printline::i#2<(byte) $28) goto printline::@2
to:printline::@return to:printline::@return
printline::@return: scope:[printline] from printline::@1 printline::@return: scope:[printline] from printline::@1
[6] return [7] return
to:@return to:@return
printline::@2: scope:[printline] from printline::@1 printline::@2: scope:[printline] from printline::@1
[7] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' [8] *((const byte*) SCREEN + (byte) printline::i#2) ← (byte) '*'
[8] (byte) printline::i ← ++ (byte) printline::i [9] (byte) printline::i#1 ← ++ (byte) printline::i#2
to:printline::@1 to:printline::@1
__stackcall (void()) main() __stackcall (void()) main()
main: scope:[main] from main: scope:[main] from
[9] (byte) val ← (byte) '-' [10] (byte) val ← (byte) '-'
[10] callexecute printline [11] callexecute printline
[11] *((const byte*) SCREEN+(byte) $50) ← (byte) val [12] *((const byte*) SCREEN+(byte) $50) ← (byte) val
to:main::@return to:main::@return
main::@return: scope:[main] from main main::@return: scope:[main] from main
[12] return [13] return
to:@return to:@return
VARIABLE REGISTER WEIGHTS VARIABLE REGISTER WEIGHTS
__stackcall (void()) main() __stackcall (void()) main()
__stackcall (void()) printline() __stackcall (void()) printline()
(byte) printline::i loadstore 11.5 (byte) printline::i
(byte) printline::i#1 22.0
(byte) printline::i#2 14.666666666666666
(byte) val loadstore 3.0 (byte) val loadstore 3.0
Initial phi equivalence classes Initial phi equivalence classes
[ printline::i#2 printline::i#1 ]
Added variable val to live range equivalence class [ val ] Added variable val to live range equivalence class [ val ]
Added variable printline::i to live range equivalence class [ printline::i ]
Complete equivalence classes Complete equivalence classes
[ printline::i#2 printline::i#1 ]
[ val ] [ val ]
[ printline::i ] Allocated zp[1]:2 [ printline::i#2 printline::i#1 ]
Allocated zp[1]:2 [ val ] Allocated zp[1]:3 [ val ]
Allocated zp[1]:3 [ printline::i ]
INITIAL ASM INITIAL ASM
Target platform is c64basic / MOS6502X Target platform is c64basic / MOS6502X
@ -145,7 +165,7 @@ Target platform is c64basic / MOS6502X
.pc = $80d "Program" .pc = $80d "Program"
// Global Constants & labels // Global Constants & labels
.label SCREEN = $400 .label SCREEN = $400
.label val = 2 .label val = 3
// @begin // @begin
__bbegin: __bbegin:
// [0] (byte) val ← (byte) 0 -- vbuz1=vbuc1 // [0] (byte) val ← (byte) 0 -- vbuz1=vbuc1
@ -165,72 +185,79 @@ __bend_from___b1:
__bend: __bend:
// printline // printline
printline: { printline: {
.label i = 3 .label i = 2
// [4] (byte) printline::i ← (byte) 0 -- vbuz1=vbuc1 // [5] phi from printline to printline::@1 [phi:printline->printline::@1]
__b1_from_printline:
// [5] phi (byte) printline::i#2 = (byte) 0 [phi:printline->printline::@1#0] -- vbuz1=vbuc1
lda #0 lda #0
sta.z i sta.z i
jmp __b1 jmp __b1
// printline::@1 // printline::@1
__b1: __b1:
// [5] if((byte) printline::i<(byte) $28) goto printline::@2 -- vbuz1_lt_vbuc1_then_la1 // [6] if((byte) printline::i#2<(byte) $28) goto printline::@2 -- vbuz1_lt_vbuc1_then_la1
lda.z i lda.z i
cmp #$28 cmp #$28
bcc __b2 bcc __b2
jmp __breturn jmp __breturn
// printline::@return // printline::@return
__breturn: __breturn:
// [6] return // [7] return
rts rts
// printline::@2 // printline::@2
__b2: __b2:
// [7] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' -- pbuc1_derefidx_vbuz1=vbuc2 // [8] *((const byte*) SCREEN + (byte) printline::i#2) ← (byte) '*' -- pbuc1_derefidx_vbuz1=vbuc2
lda #'*' lda #'*'
ldy.z i ldy.z i
sta SCREEN,y sta SCREEN,y
// [8] (byte) printline::i ← ++ (byte) printline::i -- vbuz1=_inc_vbuz1 // [9] (byte) printline::i#1 ← ++ (byte) printline::i#2 -- vbuz1=_inc_vbuz1
inc.z i inc.z i
// [5] phi from printline::@2 to printline::@1 [phi:printline::@2->printline::@1]
__b1_from___b2:
// [5] phi (byte) printline::i#2 = (byte) printline::i#1 [phi:printline::@2->printline::@1#0] -- register_copy
jmp __b1 jmp __b1
} }
// main // main
main: { main: {
// [9] (byte) val ← (byte) '-' -- vbuz1=vbuc1 // [10] (byte) val ← (byte) '-' -- vbuz1=vbuc1
lda #'-' lda #'-'
sta.z val sta.z val
// [10] callexecute printline -- jsr // [11] callexecute printline -- jsr
jsr printline jsr printline
// [11] *((const byte*) SCREEN+(byte) $50) ← (byte) val -- _deref_pbuc1=vbuz1 // [12] *((const byte*) SCREEN+(byte) $50) ← (byte) val -- _deref_pbuc1=vbuz1
lda.z val lda.z val
sta SCREEN+$50 sta SCREEN+$50
jmp __breturn jmp __breturn
// main::@return // main::@return
__breturn: __breturn:
// [12] return // [13] return
rts rts
} }
// File Data // File Data
REGISTER UPLIFT POTENTIAL REGISTERS REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] (byte) val ← (byte) 0 [ ] ( [ ] ) always clobbers reg byte a Statement [0] (byte) val ← (byte) 0 [ ] ( [ ] ) always clobbers reg byte a
Statement [4] (byte) printline::i ← (byte) 0 [ printline::i ] ( main:2::printline:10 [ val printline::i ] ) always clobbers reg byte a Statement [8] *((const byte*) SCREEN + (byte) printline::i#2) ← (byte) '*' [ printline::i#2 ] ( main:2::printline:11 [ val printline::i#2 ] ) always clobbers reg byte a
Statement [5] if((byte) printline::i<(byte) $28) goto printline::@2 [ printline::i ] ( main:2::printline:10 [ val printline::i ] ) always clobbers reg byte a Removing always clobbered register reg byte a as potential for zp[1]:2 [ printline::i#2 printline::i#1 ]
Statement [7] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' [ printline::i ] ( main:2::printline:10 [ val printline::i ] ) always clobbers reg byte a reg byte y Statement [10] (byte) val ← (byte) '-' [ val ] ( main:2 [ val ] ) always clobbers reg byte a
Statement [9] (byte) val ← (byte) '-' [ val ] ( main:2 [ val ] ) always clobbers reg byte a Statement [12] *((const byte*) SCREEN+(byte) $50) ← (byte) val [ ] ( main:2 [ ] ) always clobbers reg byte a
Statement [11] *((const byte*) SCREEN+(byte) $50) ← (byte) val [ ] ( main:2 [ ] ) always clobbers reg byte a Statement [0] (byte) val ← (byte) 0 [ ] ( [ ] ) always clobbers reg byte a
Potential registers zp[1]:2 [ val ] : zp[1]:2 , Statement [8] *((const byte*) SCREEN + (byte) printline::i#2) ← (byte) '*' [ printline::i#2 ] ( main:2::printline:11 [ val printline::i#2 ] ) always clobbers reg byte a
Potential registers zp[1]:3 [ printline::i ] : zp[1]:3 , Statement [10] (byte) val ← (byte) '-' [ val ] ( main:2 [ val ] ) always clobbers reg byte a
Statement [12] *((const byte*) SCREEN+(byte) $50) ← (byte) val [ ] ( main:2 [ ] ) always clobbers reg byte a
Potential registers zp[1]:2 [ printline::i#2 printline::i#1 ] : zp[1]:2 , reg byte x , reg byte y ,
Potential registers zp[1]:3 [ val ] : zp[1]:3 ,
REGISTER UPLIFT SCOPES REGISTER UPLIFT SCOPES
Uplift Scope [printline] 11.5: zp[1]:3 [ printline::i ] Uplift Scope [printline] 36.67: zp[1]:2 [ printline::i#2 printline::i#1 ]
Uplift Scope [] 3: zp[1]:2 [ val ] Uplift Scope [] 3: zp[1]:3 [ val ]
Uplift Scope [main] Uplift Scope [main]
Uplifting [printline] best 343 combination zp[1]:3 [ printline::i ] Uplifting [printline] best 295 combination reg byte x [ printline::i#2 printline::i#1 ]
Uplifting [] best 343 combination zp[1]:2 [ val ] Uplifting [] best 295 combination zp[1]:3 [ val ]
Uplifting [main] best 343 combination Uplifting [main] best 295 combination
Attempting to uplift remaining variables inzp[1]:3 [ printline::i ] Attempting to uplift remaining variables inzp[1]:3 [ val ]
Uplifting [printline] best 343 combination zp[1]:3 [ printline::i ] Uplifting [] best 295 combination zp[1]:3 [ val ]
Attempting to uplift remaining variables inzp[1]:2 [ val ] Allocated (was zp[1]:3) zp[1]:2 [ val ]
Uplifting [] best 343 combination zp[1]:2 [ val ]
ASSEMBLER BEFORE OPTIMIZATION ASSEMBLER BEFORE OPTIMIZATION
// File Comments // File Comments
@ -262,46 +289,47 @@ __bend_from___b1:
__bend: __bend:
// printline // printline
printline: { printline: {
.label i = 3 // [5] phi from printline to printline::@1 [phi:printline->printline::@1]
// [4] (byte) printline::i ← (byte) 0 -- vbuz1=vbuc1 __b1_from_printline:
lda #0 // [5] phi (byte) printline::i#2 = (byte) 0 [phi:printline->printline::@1#0] -- vbuxx=vbuc1
sta.z i ldx #0
jmp __b1 jmp __b1
// printline::@1 // printline::@1
__b1: __b1:
// [5] if((byte) printline::i<(byte) $28) goto printline::@2 -- vbuz1_lt_vbuc1_then_la1 // [6] if((byte) printline::i#2<(byte) $28) goto printline::@2 -- vbuxx_lt_vbuc1_then_la1
lda.z i cpx #$28
cmp #$28
bcc __b2 bcc __b2
jmp __breturn jmp __breturn
// printline::@return // printline::@return
__breturn: __breturn:
// [6] return // [7] return
rts rts
// printline::@2 // printline::@2
__b2: __b2:
// [7] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' -- pbuc1_derefidx_vbuz1=vbuc2 // [8] *((const byte*) SCREEN + (byte) printline::i#2) ← (byte) '*' -- pbuc1_derefidx_vbuxx=vbuc2
lda #'*' lda #'*'
ldy.z i sta SCREEN,x
sta SCREEN,y // [9] (byte) printline::i#1 ← ++ (byte) printline::i#2 -- vbuxx=_inc_vbuxx
// [8] (byte) printline::i ← ++ (byte) printline::i -- vbuz1=_inc_vbuz1 inx
inc.z i // [5] phi from printline::@2 to printline::@1 [phi:printline::@2->printline::@1]
__b1_from___b2:
// [5] phi (byte) printline::i#2 = (byte) printline::i#1 [phi:printline::@2->printline::@1#0] -- register_copy
jmp __b1 jmp __b1
} }
// main // main
main: { main: {
// [9] (byte) val ← (byte) '-' -- vbuz1=vbuc1 // [10] (byte) val ← (byte) '-' -- vbuz1=vbuc1
lda #'-' lda #'-'
sta.z val sta.z val
// [10] callexecute printline -- jsr // [11] callexecute printline -- jsr
jsr printline jsr printline
// [11] *((const byte*) SCREEN+(byte) $50) ← (byte) val -- _deref_pbuc1=vbuz1 // [12] *((const byte*) SCREEN+(byte) $50) ← (byte) val -- _deref_pbuc1=vbuz1
lda.z val lda.z val
sta SCREEN+$50 sta SCREEN+$50
jmp __breturn jmp __breturn
// main::@return // main::@return
__breturn: __breturn:
// [12] return // [13] return
rts rts
} }
// File Data // File Data
@ -318,7 +346,9 @@ Removing instruction __bend_from___b1:
Succesful ASM optimization Pass5RedundantLabelElimination Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __b1: Removing instruction __b1:
Removing instruction __bend: Removing instruction __bend:
Removing instruction __b1_from_printline:
Removing instruction __breturn: Removing instruction __breturn:
Removing instruction __b1_from___b2:
Removing instruction __breturn: Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination Succesful ASM optimization Pass5UnusedLabelElimination
Adding RTS to root block Adding RTS to root block
@ -335,15 +365,17 @@ __stackcall (void()) printline()
(label) printline::@1 (label) printline::@1
(label) printline::@2 (label) printline::@2
(label) printline::@return (label) printline::@return
(byte) printline::i loadstore zp[1]:3 11.5 (byte) printline::i
(byte) printline::i#1 reg byte x 22.0
(byte) printline::i#2 reg byte x 14.666666666666666
(byte) val loadstore zp[1]:2 3.0 (byte) val loadstore zp[1]:2 3.0
reg byte x [ printline::i#2 printline::i#1 ]
zp[1]:2 [ val ] zp[1]:2 [ val ]
zp[1]:3 [ printline::i ]
FINAL ASSEMBLER FINAL ASSEMBLER
Score: 307 Score: 232
// File Comments // File Comments
// Test a procedure with calling convention stack // Test a procedure with calling convention stack
@ -370,50 +402,48 @@ __bbegin:
// @end // @end
// printline // printline
printline: { printline: {
.label i = 3 // [5] phi from printline to printline::@1 [phi:printline->printline::@1]
// i=0 // [5] phi (byte) printline::i#2 = (byte) 0 [phi:printline->printline::@1#0] -- vbuxx=vbuc1
// [4] (byte) printline::i ← (byte) 0 -- vbuz1=vbuc1 ldx #0
lda #0
sta.z i
// printline::@1 // printline::@1
__b1: __b1:
// for(char i=0; i<40; i++) // for(char i=0; i<40; i++)
// [5] if((byte) printline::i<(byte) $28) goto printline::@2 -- vbuz1_lt_vbuc1_then_la1 // [6] if((byte) printline::i#2<(byte) $28) goto printline::@2 -- vbuxx_lt_vbuc1_then_la1
lda.z i cpx #$28
cmp #$28
bcc __b2 bcc __b2
// printline::@return // printline::@return
// } // }
// [6] return // [7] return
rts rts
// printline::@2 // printline::@2
__b2: __b2:
// SCREEN[i] = '*' // SCREEN[i] = '*'
// [7] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' -- pbuc1_derefidx_vbuz1=vbuc2 // [8] *((const byte*) SCREEN + (byte) printline::i#2) ← (byte) '*' -- pbuc1_derefidx_vbuxx=vbuc2
lda #'*' lda #'*'
ldy.z i sta SCREEN,x
sta SCREEN,y
// for(char i=0; i<40; i++) // for(char i=0; i<40; i++)
// [8] (byte) printline::i ← ++ (byte) printline::i -- vbuz1=_inc_vbuz1 // [9] (byte) printline::i#1 ← ++ (byte) printline::i#2 -- vbuxx=_inc_vbuxx
inc.z i inx
// [5] phi from printline::@2 to printline::@1 [phi:printline::@2->printline::@1]
// [5] phi (byte) printline::i#2 = (byte) printline::i#1 [phi:printline::@2->printline::@1#0] -- register_copy
jmp __b1 jmp __b1
} }
// main // main
main: { main: {
// val = '-' // val = '-'
// [9] (byte) val ← (byte) '-' -- vbuz1=vbuc1 // [10] (byte) val ← (byte) '-' -- vbuz1=vbuc1
lda #'-' lda #'-'
sta.z val sta.z val
// printline() // printline()
// [10] callexecute printline -- jsr // [11] callexecute printline -- jsr
jsr printline jsr printline
// SCREEN[80] = val // SCREEN[80] = val
// [11] *((const byte*) SCREEN+(byte) $50) ← (byte) val -- _deref_pbuc1=vbuz1 // [12] *((const byte*) SCREEN+(byte) $50) ← (byte) val -- _deref_pbuc1=vbuz1
lda.z val lda.z val
sta SCREEN+$50 sta SCREEN+$50
// main::@return // main::@return
// } // }
// [12] return // [13] return
rts rts
} }
// File Data // File Data

View File

@ -8,8 +8,10 @@ __stackcall (void()) printline()
(label) printline::@1 (label) printline::@1
(label) printline::@2 (label) printline::@2
(label) printline::@return (label) printline::@return
(byte) printline::i loadstore zp[1]:3 11.5 (byte) printline::i
(byte) printline::i#1 reg byte x 22.0
(byte) printline::i#2 reg byte x 14.666666666666666
(byte) val loadstore zp[1]:2 3.0 (byte) val loadstore zp[1]:2 3.0
reg byte x [ printline::i#2 printline::i#1 ]
zp[1]:2 [ val ] zp[1]:2 [ val ]
zp[1]:3 [ printline::i ]

View File

@ -12,18 +12,13 @@ __bbegin:
jsr main jsr main
rts rts
printother: { printother: {
.label i = 3 ldx #0
// for(char i:0..5)
lda #0
sta.z i
__b1: __b1:
// (SCREEN+40)[i]++; // (SCREEN+40)[i]++;
ldx.z i
inc SCREEN+$28,x inc SCREEN+$28,x
// for(char i:0..5) // for(char i:0..5)
inc.z i inx
lda #6 cpx #6
cmp.z i
bne __b1 bne __b1
// } // }
rts rts
@ -54,10 +49,7 @@ pval: {
rts rts
} }
main: { main: {
.label i = 4 ldy #0
// for(char i:0..5)
lda #0
sta.z i
__b1: __b1:
// pval() // pval()
jsr pval jsr pval
@ -66,9 +58,8 @@ main: {
// ival() // ival()
jsr ival jsr ival
// for(char i:0..5) // for(char i:0..5)
inc.z i iny
lda #6 cpy #6
cmp.z i
bne __b1 bne __b1
// } // }
rts rts

View File

@ -10,63 +10,64 @@
__stackcall (void()) printother() __stackcall (void()) printother()
printother: scope:[printother] from printother: scope:[printother] from
[4] (byte) printother::i(byte) 0 [4] phi()
to:printother::@1 to:printother::@1
printother::@1: scope:[printother] from printother printother::@1 printother::@1: scope:[printother] from printother printother::@1
[5] *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) ← ++ *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) [5] (byte) printother::i#2 ← phi( printother/(byte) 0 printother::@1/(byte) printother::i#1 )
[6] (byte) printother::i ← ++ (byte) printother::i [6] *((const byte*) SCREEN+(byte) $28 + (byte) printother::i#2) ← ++ *((const byte*) SCREEN+(byte) $28 + (byte) printother::i#2)
[7] if((byte) printother::i!=(byte) 6) goto printother::@1 [7] (byte) printother::i#1 ← ++ (byte) printother::i#2
[8] if((byte) printother::i#1!=(byte) 6) goto printother::@1
to:printother::@return to:printother::@return
printother::@return: scope:[printother] from printother::@1 printother::@return: scope:[printother] from printother::@1
[8] return [9] return
to:@return to:@return
__stackcall (void()) incval() __stackcall (void()) incval()
incval: scope:[incval] from incval: scope:[incval] from
[9] (byte) val ← ++ (byte) val [10] (byte) val ← ++ (byte) val
to:incval::@return to:incval::@return
incval::@return: scope:[incval] from incval incval::@return: scope:[incval] from incval
[10] return [11] return
to:@return to:@return
__stackcall (void()) printval() __stackcall (void()) printval()
printval: scope:[printval] from printval: scope:[printval] from
[11] *((const byte*) SCREEN) ← (byte) val [12] *((const byte*) SCREEN) ← (byte) val
to:printval::@return to:printval::@return
printval::@return: scope:[printval] from printval printval::@return: scope:[printval] from printval
[12] return [13] return
to:@return to:@return
__stackcall (void()) ival() __stackcall (void()) ival()
ival: scope:[ival] from ival: scope:[ival] from
[13] phi() [14] phi()
[14] callexecute incval [15] callexecute incval
to:ival::@return to:ival::@return
ival::@return: scope:[ival] from ival ival::@return: scope:[ival] from ival
[15] return [16] return
to:@return to:@return
__stackcall (void()) pval() __stackcall (void()) pval()
pval: scope:[pval] from pval: scope:[pval] from
[16] phi() [17] phi()
[17] callexecute printval [18] callexecute printval
to:pval::@return to:pval::@return
pval::@return: scope:[pval] from pval pval::@return: scope:[pval] from pval
[18] return [19] return
to:@return to:@return
__stackcall (void()) main() __stackcall (void()) main()
main: scope:[main] from main: scope:[main] from
[19] (byte) main::i ← (byte) 0 [20] phi()
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1 main::@1: scope:[main] from main main::@1
[20] phi() [21] (byte) main::i#2 ← phi( main/(byte) 0 main::@1/(byte) main::i#1 )
[21] callexecute pval [22] callexecute pval
[22] callexecute printother [23] callexecute printother
[23] callexecute ival [24] callexecute ival
[24] (byte) main::i ← ++ (byte) main::i [25] (byte) main::i#1 ← ++ (byte) main::i#2
[25] if((byte) main::i!=(byte) 6) goto main::@1 [26] if((byte) main::i#1!=(byte) 6) goto main::@1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@1
[26] return [27] return
to:@return to:@return

View File

@ -5,6 +5,7 @@ Culled Empty Block (label) @3
Culled Empty Block (label) @4 Culled Empty Block (label) @4
Culled Empty Block (label) @5 Culled Empty Block (label) @5
Culled Empty Block (label) printother::@2 Culled Empty Block (label) printother::@2
Converting PHI-variable modified inside __stackcall procedure main() to load/store (byte) val
Calling convention STACK_CALL adding prepare/execute/finalize for call pval Calling convention STACK_CALL adding prepare/execute/finalize for call pval
Calling convention STACK_CALL adding prepare/execute/finalize for call printother Calling convention STACK_CALL adding prepare/execute/finalize for call printother
Calling convention STACK_CALL adding prepare/execute/finalize for call ival Calling convention STACK_CALL adding prepare/execute/finalize for call ival
@ -19,14 +20,15 @@ CONTROL FLOW GRAPH SSA
__stackcall (void()) main() __stackcall (void()) main()
main: scope:[main] from main: scope:[main] from
(byte) main::i ← (byte) 0 (byte) main::i#0 ← (byte) 0
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1 main::@1: scope:[main] from main main::@1
(byte) main::i#2 ← phi( main/(byte) main::i#0 main::@1/(byte) main::i#1 )
callexecute pval callexecute pval
callexecute printother callexecute printother
callexecute ival callexecute ival
(byte) main::i ← (byte) main::i + rangenext(0,5) (byte) main::i#1 ← (byte) main::i#2 + rangenext(0,5)
(bool~) main::$3 ← (byte) main::i != rangelast(0,5) (bool~) main::$3 ← (byte) main::i#1 != rangelast(0,5)
if((bool~) main::$3) goto main::@1 if((bool~) main::$3) goto main::@1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@1
@ -67,12 +69,13 @@ incval::@return: scope:[incval] from incval
__stackcall (void()) printother() __stackcall (void()) printother()
printother: scope:[printother] from printother: scope:[printother] from
(byte) printother::i ← (byte) 0 (byte) printother::i#0 ← (byte) 0
to:printother::@1 to:printother::@1
printother::@1: scope:[printother] from printother printother::@1 printother::@1: scope:[printother] from printother printother::@1
*((const byte*) SCREEN+(number) $28 + (byte) printother::i) ← ++ *((const byte*) SCREEN+(number) $28 + (byte) printother::i) (byte) printother::i#2 ← phi( printother/(byte) printother::i#0 printother::@1/(byte) printother::i#1 )
(byte) printother::i ← (byte) printother::i + rangenext(0,5) *((const byte*) SCREEN+(number) $28 + (byte) printother::i#2) ← ++ *((const byte*) SCREEN+(number) $28 + (byte) printother::i#2)
(bool~) printother::$1 ← (byte) printother::i != rangelast(0,5) (byte) printother::i#1 ← (byte) printother::i#2 + rangenext(0,5)
(bool~) printother::$1 ← (byte) printother::i#1 != rangelast(0,5)
if((bool~) printother::$1) goto printother::@1 if((bool~) printother::$1) goto printother::@1
to:printother::@return to:printother::@return
printother::@return: scope:[printother] from printother::@1 printother::@return: scope:[printother] from printother::@1
@ -96,12 +99,18 @@ __stackcall (void()) main()
(bool~) main::$3 (bool~) main::$3
(label) main::@1 (label) main::@1
(label) main::@return (label) main::@return
(byte) main::i loadstore (byte) main::i
(byte) main::i#0
(byte) main::i#1
(byte) main::i#2
__stackcall (void()) printother() __stackcall (void()) printother()
(bool~) printother::$1 (bool~) printother::$1
(label) printother::@1 (label) printother::@1
(label) printother::@return (label) printother::@return
(byte) printother::i loadstore (byte) printother::i
(byte) printother::i#0
(byte) printother::i#1
(byte) printother::i#2
__stackcall (void()) printval() __stackcall (void()) printval()
(label) printval::@return (label) printval::@return
__stackcall (void()) pval() __stackcall (void()) pval()
@ -109,7 +118,7 @@ __stackcall (void()) pval()
(byte) val loadstore (byte) val loadstore
Adding number conversion cast (unumber) 0 in *((const byte*) SCREEN + (number) 0) ← (byte) val Adding number conversion cast (unumber) 0 in *((const byte*) SCREEN + (number) 0) ← (byte) val
Adding number conversion cast (unumber) $28 in *((const byte*) SCREEN+(number) $28 + (byte) printother::i) ← ++ *((const byte*) SCREEN+(number) $28 + (byte) printother::i) Adding number conversion cast (unumber) $28 in *((const byte*) SCREEN+(number) $28 + (byte) printother::i#2) ← ++ *((const byte*) SCREEN+(number) $28 + (byte) printother::i#2)
Successful SSA optimization PassNAddNumberTypeConversions Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant pointer cast (byte*) 1024 Simplifying constant pointer cast (byte*) 1024
Simplifying constant integer cast 0 Simplifying constant integer cast 0
@ -118,17 +127,20 @@ Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) 0 Finalized unsigned number type (byte) 0
Finalized unsigned number type (byte) $28 Finalized unsigned number type (byte) $28
Successful SSA optimization PassNFinalizeNumberTypeConversions Successful SSA optimization PassNFinalizeNumberTypeConversions
Simple Condition (bool~) main::$3 [7] if((byte) main::i!=rangelast(0,5)) goto main::@1 Simple Condition (bool~) main::$3 [8] if((byte) main::i#1!=rangelast(0,5)) goto main::@1
Simple Condition (bool~) printother::$1 [21] if((byte) printother::i!=rangelast(0,5)) goto printother::@1 Simple Condition (bool~) printother::$1 [23] if((byte) printother::i#1!=rangelast(0,5)) goto printother::@1
Successful SSA optimization Pass2ConditionalJumpSimplification Successful SSA optimization Pass2ConditionalJumpSimplification
Resolved ranged next value [5] main::i ← ++ main::i to ++ Constant (const byte) main::i#0 = 0
Resolved ranged comparison value [7] if(main::i!=rangelast(0,5)) goto main::@1 to (number) 6 Constant (const byte) printother::i#0 = 0
Resolved ranged next value [19] printother::i ← ++ printother::i to ++ Successful SSA optimization Pass2ConstantIdentification
Resolved ranged comparison value [21] if(printother::i!=rangelast(0,5)) goto printother::@1 to (number) 6 Resolved ranged next value [6] main::i#1 ← ++ main::i#2 to ++
Simplifying expression containing zero SCREEN in [13] *((const byte*) SCREEN + (byte) 0) ← (byte) val Resolved ranged comparison value [8] if(main::i#1!=rangelast(0,5)) goto main::@1 to (number) 6
Resolved ranged next value [21] printother::i#1 ← ++ printother::i#2 to ++
Resolved ranged comparison value [23] if(printother::i#1!=rangelast(0,5)) goto printother::@1 to (number) 6
Simplifying expression containing zero SCREEN in [14] *((const byte*) SCREEN + (byte) 0) ← (byte) val
Successful SSA optimization PassNSimplifyExpressionWithZero Successful SSA optimization PassNSimplifyExpressionWithZero
Adding number conversion cast (unumber) 6 in if((byte) main::i!=(number) 6) goto main::@1 Adding number conversion cast (unumber) 6 in if((byte) main::i#1!=(number) 6) goto main::@1
Adding number conversion cast (unumber) 6 in if((byte) printother::i!=(number) 6) goto printother::@1 Adding number conversion cast (unumber) 6 in if((byte) printother::i#1!=(number) 6) goto printother::@1
Successful SSA optimization PassNAddNumberTypeConversions Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant integer cast 6 Simplifying constant integer cast 6
Simplifying constant integer cast 6 Simplifying constant integer cast 6
@ -136,25 +148,38 @@ Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) 6 Finalized unsigned number type (byte) 6
Finalized unsigned number type (byte) 6 Finalized unsigned number type (byte) 6
Successful SSA optimization PassNFinalizeNumberTypeConversions Successful SSA optimization PassNFinalizeNumberTypeConversions
Inlining constant with var siblings (const byte) main::i#0
Inlining constant with var siblings (const byte) printother::i#0
Constant inlined main::i#0 = (byte) 0
Constant inlined printother::i#0 = (byte) 0
Successful SSA optimization Pass2ConstantInlining
Added new block during phi lifting main::@3(between main::@1 and main::@1)
Added new block during phi lifting printother::@3(between printother::@1 and printother::@1)
Adding NOP phi() at start of @6 Adding NOP phi() at start of @6
Adding NOP phi() at start of @end Adding NOP phi() at start of @end
Adding NOP phi() at start of printother
Adding NOP phi() at start of ival Adding NOP phi() at start of ival
Adding NOP phi() at start of pval Adding NOP phi() at start of pval
Adding NOP phi() at start of main::@1 Adding NOP phi() at start of main
CALL GRAPH CALL GRAPH
Calls in [] to main:2 Calls in [] to main:2
Calls in [ival] to incval:14 Calls in [ival] to incval:16
Calls in [pval] to printval:17 Calls in [pval] to printval:19
Calls in [main] to pval:21 printother:22 ival:23 Calls in [main] to pval:23 printother:24 ival:25
Created 0 initial phi equivalence classes Created 2 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes Coalesced [10] printother::i#3 ← printother::i#1
Coalesced [29] main::i#3 ← main::i#1
Coalesced down to 2 phi equivalence classes
Culled Empty Block (label) printother::@3
Culled Empty Block (label) main::@3
Renumbering block @6 to @1 Renumbering block @6 to @1
Adding NOP phi() at start of @1 Adding NOP phi() at start of @1
Adding NOP phi() at start of @end Adding NOP phi() at start of @end
Adding NOP phi() at start of printother
Adding NOP phi() at start of ival Adding NOP phi() at start of ival
Adding NOP phi() at start of pval Adding NOP phi() at start of pval
Adding NOP phi() at start of main::@1 Adding NOP phi() at start of main
FINAL CONTROL FLOW GRAPH FINAL CONTROL FLOW GRAPH
@begin: scope:[] from @begin: scope:[] from
@ -169,65 +194,66 @@ FINAL CONTROL FLOW GRAPH
__stackcall (void()) printother() __stackcall (void()) printother()
printother: scope:[printother] from printother: scope:[printother] from
[4] (byte) printother::i(byte) 0 [4] phi()
to:printother::@1 to:printother::@1
printother::@1: scope:[printother] from printother printother::@1 printother::@1: scope:[printother] from printother printother::@1
[5] *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) ← ++ *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) [5] (byte) printother::i#2 ← phi( printother/(byte) 0 printother::@1/(byte) printother::i#1 )
[6] (byte) printother::i ← ++ (byte) printother::i [6] *((const byte*) SCREEN+(byte) $28 + (byte) printother::i#2) ← ++ *((const byte*) SCREEN+(byte) $28 + (byte) printother::i#2)
[7] if((byte) printother::i!=(byte) 6) goto printother::@1 [7] (byte) printother::i#1 ← ++ (byte) printother::i#2
[8] if((byte) printother::i#1!=(byte) 6) goto printother::@1
to:printother::@return to:printother::@return
printother::@return: scope:[printother] from printother::@1 printother::@return: scope:[printother] from printother::@1
[8] return [9] return
to:@return to:@return
__stackcall (void()) incval() __stackcall (void()) incval()
incval: scope:[incval] from incval: scope:[incval] from
[9] (byte) val ← ++ (byte) val [10] (byte) val ← ++ (byte) val
to:incval::@return to:incval::@return
incval::@return: scope:[incval] from incval incval::@return: scope:[incval] from incval
[10] return [11] return
to:@return to:@return
__stackcall (void()) printval() __stackcall (void()) printval()
printval: scope:[printval] from printval: scope:[printval] from
[11] *((const byte*) SCREEN) ← (byte) val [12] *((const byte*) SCREEN) ← (byte) val
to:printval::@return to:printval::@return
printval::@return: scope:[printval] from printval printval::@return: scope:[printval] from printval
[12] return [13] return
to:@return to:@return
__stackcall (void()) ival() __stackcall (void()) ival()
ival: scope:[ival] from ival: scope:[ival] from
[13] phi() [14] phi()
[14] callexecute incval [15] callexecute incval
to:ival::@return to:ival::@return
ival::@return: scope:[ival] from ival ival::@return: scope:[ival] from ival
[15] return [16] return
to:@return to:@return
__stackcall (void()) pval() __stackcall (void()) pval()
pval: scope:[pval] from pval: scope:[pval] from
[16] phi() [17] phi()
[17] callexecute printval [18] callexecute printval
to:pval::@return to:pval::@return
pval::@return: scope:[pval] from pval pval::@return: scope:[pval] from pval
[18] return [19] return
to:@return to:@return
__stackcall (void()) main() __stackcall (void()) main()
main: scope:[main] from main: scope:[main] from
[19] (byte) main::i ← (byte) 0 [20] phi()
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1 main::@1: scope:[main] from main main::@1
[20] phi() [21] (byte) main::i#2 ← phi( main/(byte) 0 main::@1/(byte) main::i#1 )
[21] callexecute pval [22] callexecute pval
[22] callexecute printother [23] callexecute printother
[23] callexecute ival [24] callexecute ival
[24] (byte) main::i ← ++ (byte) main::i [25] (byte) main::i#1 ← ++ (byte) main::i#2
[25] if((byte) main::i!=(byte) 6) goto main::@1 [26] if((byte) main::i#1!=(byte) 6) goto main::@1
to:main::@return to:main::@return
main::@return: scope:[main] from main::@1 main::@return: scope:[main] from main::@1
[26] return [27] return
to:@return to:@return
null depth in calling loop Loop head: main::@1 tails: main::@1 blocks: main::@1 in scope printother null depth in calling loop Loop head: main::@1 tails: main::@1 blocks: main::@1 in scope printother
@ -240,24 +266,28 @@ VARIABLE REGISTER WEIGHTS
__stackcall (void()) incval() __stackcall (void()) incval()
__stackcall (void()) ival() __stackcall (void()) ival()
__stackcall (void()) main() __stackcall (void()) main()
(byte) main::i loadstore 5.0 (byte) main::i
(byte) main::i#1 16.5
(byte) main::i#2 5.5
__stackcall (void()) printother() __stackcall (void()) printother()
(byte) printother::i loadstore 14.25 (byte) printother::i
(byte) printother::i#1 16.5
(byte) printother::i#2 22.0
__stackcall (void()) printval() __stackcall (void()) printval()
__stackcall (void()) pval() __stackcall (void()) pval()
(byte) val loadstore 0.42105263157894735 (byte) val loadstore 0.42105263157894735
Initial phi equivalence classes Initial phi equivalence classes
[ printother::i#2 printother::i#1 ]
[ main::i#2 main::i#1 ]
Added variable val to live range equivalence class [ val ] Added variable val to live range equivalence class [ val ]
Added variable printother::i to live range equivalence class [ printother::i ]
Added variable main::i to live range equivalence class [ main::i ]
Complete equivalence classes Complete equivalence classes
[ printother::i#2 printother::i#1 ]
[ main::i#2 main::i#1 ]
[ val ] [ val ]
[ printother::i ] Allocated zp[1]:2 [ printother::i#2 printother::i#1 ]
[ main::i ] Allocated zp[1]:3 [ main::i#2 main::i#1 ]
Allocated zp[1]:2 [ val ] Allocated zp[1]:4 [ val ]
Allocated zp[1]:3 [ printother::i ]
Allocated zp[1]:4 [ main::i ]
INITIAL ASM INITIAL ASM
Target platform is c64basic / MOS6502X Target platform is c64basic / MOS6502X
@ -270,7 +300,7 @@ Target platform is c64basic / MOS6502X
.pc = $80d "Program" .pc = $80d "Program"
// Global Constants & labels // Global Constants & labels
.label SCREEN = $400 .label SCREEN = $400
.label val = 2 .label val = 4
// @begin // @begin
__bbegin: __bbegin:
// [0] (byte) val ← (byte) 0 -- vbuz1=vbuc1 // [0] (byte) val ← (byte) 0 -- vbuz1=vbuc1
@ -290,135 +320,139 @@ __bend_from___b1:
__bend: __bend:
// printother // printother
printother: { printother: {
.label i = 3 .label i = 2
// [4] (byte) printother::i ← (byte) 0 -- vbuz1=vbuc1 // [5] phi from printother to printother::@1 [phi:printother->printother::@1]
__b1_from_printother:
// [5] phi (byte) printother::i#2 = (byte) 0 [phi:printother->printother::@1#0] -- vbuz1=vbuc1
lda #0 lda #0
sta.z i sta.z i
jmp __b1 jmp __b1
// [5] phi from printother::@1 to printother::@1 [phi:printother::@1->printother::@1]
__b1_from___b1:
// [5] phi (byte) printother::i#2 = (byte) printother::i#1 [phi:printother::@1->printother::@1#0] -- register_copy
jmp __b1
// printother::@1 // printother::@1
__b1: __b1:
// [5] *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) ← ++ *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) -- pbuc1_derefidx_vbuz1=_inc_pbuc1_derefidx_vbuz1 // [6] *((const byte*) SCREEN+(byte) $28 + (byte) printother::i#2) ← ++ *((const byte*) SCREEN+(byte) $28 + (byte) printother::i#2) -- pbuc1_derefidx_vbuz1=_inc_pbuc1_derefidx_vbuz1
ldx.z i ldx.z i
inc SCREEN+$28,x inc SCREEN+$28,x
// [6] (byte) printother::i ← ++ (byte) printother::i -- vbuz1=_inc_vbuz1 // [7] (byte) printother::i#1 ← ++ (byte) printother::i#2 -- vbuz1=_inc_vbuz1
inc.z i inc.z i
// [7] if((byte) printother::i!=(byte) 6) goto printother::@1 -- vbuz1_neq_vbuc1_then_la1 // [8] if((byte) printother::i#1!=(byte) 6) goto printother::@1 -- vbuz1_neq_vbuc1_then_la1
lda #6 lda #6
cmp.z i cmp.z i
bne __b1 bne __b1_from___b1
jmp __breturn jmp __breturn
// printother::@return // printother::@return
__breturn: __breturn:
// [8] return // [9] return
rts rts
} }
// incval // incval
incval: { incval: {
// [9] (byte) val ← ++ (byte) val -- vbuz1=_inc_vbuz1 // [10] (byte) val ← ++ (byte) val -- vbuz1=_inc_vbuz1
inc.z val inc.z val
jmp __breturn jmp __breturn
// incval::@return // incval::@return
__breturn: __breturn:
// [10] return // [11] return
rts rts
} }
// printval // printval
printval: { printval: {
// [11] *((const byte*) SCREEN) ← (byte) val -- _deref_pbuc1=vbuz1 // [12] *((const byte*) SCREEN) ← (byte) val -- _deref_pbuc1=vbuz1
lda.z val lda.z val
sta SCREEN sta SCREEN
jmp __breturn jmp __breturn
// printval::@return // printval::@return
__breturn: __breturn:
// [12] return // [13] return
rts rts
} }
// ival // ival
ival: { ival: {
// [14] callexecute incval -- jsr // [15] callexecute incval -- jsr
jsr incval jsr incval
jmp __breturn jmp __breturn
// ival::@return // ival::@return
__breturn: __breturn:
// [15] return // [16] return
rts rts
} }
// pval // pval
pval: { pval: {
// [17] callexecute printval -- jsr // [18] callexecute printval -- jsr
jsr printval jsr printval
jmp __breturn jmp __breturn
// pval::@return // pval::@return
__breturn: __breturn:
// [18] return // [19] return
rts rts
} }
// main // main
main: { main: {
.label i = 4 .label i = 3
// [19] (byte) main::i ← (byte) 0 -- vbuz1=vbuc1 // [21] phi from main to main::@1 [phi:main->main::@1]
__b1_from_main:
// [21] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
lda #0 lda #0
sta.z i sta.z i
// [20] phi from main main::@1 to main::@1 [phi:main/main::@1->main::@1] jmp __b1
__b1_from_main: // [21] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
__b1_from___b1: __b1_from___b1:
// [21] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy
jmp __b1 jmp __b1
// main::@1 // main::@1
__b1: __b1:
// [21] callexecute pval -- jsr // [22] callexecute pval -- jsr
jsr pval jsr pval
// [22] callexecute printother -- jsr // [23] callexecute printother -- jsr
jsr printother jsr printother
// [23] callexecute ival -- jsr // [24] callexecute ival -- jsr
jsr ival jsr ival
// [24] (byte) main::i ← ++ (byte) main::i -- vbuz1=_inc_vbuz1 // [25] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuz1=_inc_vbuz1
inc.z i inc.z i
// [25] if((byte) main::i!=(byte) 6) goto main::@1 -- vbuz1_neq_vbuc1_then_la1 // [26] if((byte) main::i#1!=(byte) 6) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
lda #6 lda #6
cmp.z i cmp.z i
bne __b1_from___b1 bne __b1_from___b1
jmp __breturn jmp __breturn
// main::@return // main::@return
__breturn: __breturn:
// [26] return // [27] return
rts rts
} }
// File Data // File Data
REGISTER UPLIFT POTENTIAL REGISTERS REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] (byte) val ← (byte) 0 [ val ] ( [ val ] ) always clobbers reg byte a Statement [0] (byte) val ← (byte) 0 [ val ] ( [ val ] ) always clobbers reg byte a
Statement [4] (byte) printother::i ← (byte) 0 [ printother::i ] ( main:2::printother:22 [ val main::i printother::i ] ) always clobbers reg byte a Statement [12] *((const byte*) SCREEN) ← (byte) val [ val ] ( main:2::pval:22::printval:18 [ main::i#2 val ] ) always clobbers reg byte a
Statement [5] *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) ← ++ *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) [ printother::i ] ( main:2::printother:22 [ val main::i printother::i ] ) always clobbers reg byte x Removing always clobbered register reg byte a as potential for zp[1]:3 [ main::i#2 main::i#1 ]
Statement [7] if((byte) printother::i!=(byte) 6) goto printother::@1 [ printother::i ] ( main:2::printother:22 [ val main::i printother::i ] ) always clobbers reg byte a Statement [0] (byte) val ← (byte) 0 [ val ] ( [ val ] ) always clobbers reg byte a
Statement [11] *((const byte*) SCREEN) ← (byte) val [ val ] ( main:2::pval:21::printval:17 [ main::i val ] ) always clobbers reg byte a Statement [12] *((const byte*) SCREEN) ← (byte) val [ val ] ( main:2::pval:22::printval:18 [ main::i#2 val ] ) always clobbers reg byte a
Statement [19] (byte) main::i ← (byte) 0 [ val main::i ] ( main:2 [ val main::i ] ) always clobbers reg byte a Potential registers zp[1]:2 [ printother::i#2 printother::i#1 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y ,
Statement [25] if((byte) main::i!=(byte) 6) goto main::@1 [ val main::i ] ( main:2 [ val main::i ] ) always clobbers reg byte a Potential registers zp[1]:3 [ main::i#2 main::i#1 ] : zp[1]:3 , reg byte x , reg byte y ,
Potential registers zp[1]:2 [ val ] : zp[1]:2 , Potential registers zp[1]:4 [ val ] : zp[1]:4 ,
Potential registers zp[1]:3 [ printother::i ] : zp[1]:3 ,
Potential registers zp[1]:4 [ main::i ] : zp[1]:4 ,
REGISTER UPLIFT SCOPES REGISTER UPLIFT SCOPES
Uplift Scope [printother] 14.25: zp[1]:3 [ printother::i ] Uplift Scope [printother] 38.5: zp[1]:2 [ printother::i#2 printother::i#1 ]
Uplift Scope [main] 5: zp[1]:4 [ main::i ] Uplift Scope [main] 22: zp[1]:3 [ main::i#2 main::i#1 ]
Uplift Scope [] 0.42: zp[1]:2 [ val ] Uplift Scope [] 0.42: zp[1]:4 [ val ]
Uplift Scope [pval] Uplift Scope [pval]
Uplift Scope [ival] Uplift Scope [ival]
Uplift Scope [printval] Uplift Scope [printval]
Uplift Scope [incval] Uplift Scope [incval]
Uplifting [printother] best 722 combination zp[1]:3 [ printother::i ] Uplifting [printother] best 779 combination reg byte x [ printother::i#2 printother::i#1 ]
Uplifting [main] best 722 combination zp[1]:4 [ main::i ] Uplifting [main] best 689 combination reg byte y [ main::i#2 main::i#1 ]
Uplifting [] best 722 combination zp[1]:2 [ val ] Uplifting [] best 689 combination zp[1]:4 [ val ]
Uplifting [pval] best 722 combination Uplifting [pval] best 689 combination
Uplifting [ival] best 722 combination Uplifting [ival] best 689 combination
Uplifting [printval] best 722 combination Uplifting [printval] best 689 combination
Uplifting [incval] best 722 combination Uplifting [incval] best 689 combination
Attempting to uplift remaining variables inzp[1]:3 [ printother::i ] Attempting to uplift remaining variables inzp[1]:4 [ val ]
Uplifting [printother] best 722 combination zp[1]:3 [ printother::i ] Uplifting [] best 689 combination zp[1]:4 [ val ]
Attempting to uplift remaining variables inzp[1]:4 [ main::i ] Allocated (was zp[1]:4) zp[1]:2 [ val ]
Uplifting [main] best 722 combination zp[1]:4 [ main::i ]
Attempting to uplift remaining variables inzp[1]:2 [ val ]
Uplifting [] best 722 combination zp[1]:2 [ val ]
ASSEMBLER BEFORE OPTIMIZATION ASSEMBLER BEFORE OPTIMIZATION
// File Comments // File Comments
@ -450,97 +484,99 @@ __bend_from___b1:
__bend: __bend:
// printother // printother
printother: { printother: {
.label i = 3 // [5] phi from printother to printother::@1 [phi:printother->printother::@1]
// [4] (byte) printother::i ← (byte) 0 -- vbuz1=vbuc1 __b1_from_printother:
lda #0 // [5] phi (byte) printother::i#2 = (byte) 0 [phi:printother->printother::@1#0] -- vbuxx=vbuc1
sta.z i ldx #0
jmp __b1
// [5] phi from printother::@1 to printother::@1 [phi:printother::@1->printother::@1]
__b1_from___b1:
// [5] phi (byte) printother::i#2 = (byte) printother::i#1 [phi:printother::@1->printother::@1#0] -- register_copy
jmp __b1 jmp __b1
// printother::@1 // printother::@1
__b1: __b1:
// [5] *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) ← ++ *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) -- pbuc1_derefidx_vbuz1=_inc_pbuc1_derefidx_vbuz1 // [6] *((const byte*) SCREEN+(byte) $28 + (byte) printother::i#2) ← ++ *((const byte*) SCREEN+(byte) $28 + (byte) printother::i#2) -- pbuc1_derefidx_vbuxx=_inc_pbuc1_derefidx_vbuxx
ldx.z i
inc SCREEN+$28,x inc SCREEN+$28,x
// [6] (byte) printother::i ← ++ (byte) printother::i -- vbuz1=_inc_vbuz1 // [7] (byte) printother::i#1 ← ++ (byte) printother::i#2 -- vbuxx=_inc_vbuxx
inc.z i inx
// [7] if((byte) printother::i!=(byte) 6) goto printother::@1 -- vbuz1_neq_vbuc1_then_la1 // [8] if((byte) printother::i#1!=(byte) 6) goto printother::@1 -- vbuxx_neq_vbuc1_then_la1
lda #6 cpx #6
cmp.z i bne __b1_from___b1
bne __b1
jmp __breturn jmp __breturn
// printother::@return // printother::@return
__breturn: __breturn:
// [8] return // [9] return
rts rts
} }
// incval // incval
incval: { incval: {
// [9] (byte) val ← ++ (byte) val -- vbuz1=_inc_vbuz1 // [10] (byte) val ← ++ (byte) val -- vbuz1=_inc_vbuz1
inc.z val inc.z val
jmp __breturn jmp __breturn
// incval::@return // incval::@return
__breturn: __breturn:
// [10] return // [11] return
rts rts
} }
// printval // printval
printval: { printval: {
// [11] *((const byte*) SCREEN) ← (byte) val -- _deref_pbuc1=vbuz1 // [12] *((const byte*) SCREEN) ← (byte) val -- _deref_pbuc1=vbuz1
lda.z val lda.z val
sta SCREEN sta SCREEN
jmp __breturn jmp __breturn
// printval::@return // printval::@return
__breturn: __breturn:
// [12] return // [13] return
rts rts
} }
// ival // ival
ival: { ival: {
// [14] callexecute incval -- jsr // [15] callexecute incval -- jsr
jsr incval jsr incval
jmp __breturn jmp __breturn
// ival::@return // ival::@return
__breturn: __breturn:
// [15] return // [16] return
rts rts
} }
// pval // pval
pval: { pval: {
// [17] callexecute printval -- jsr // [18] callexecute printval -- jsr
jsr printval jsr printval
jmp __breturn jmp __breturn
// pval::@return // pval::@return
__breturn: __breturn:
// [18] return // [19] return
rts rts
} }
// main // main
main: { main: {
.label i = 4 // [21] phi from main to main::@1 [phi:main->main::@1]
// [19] (byte) main::i ← (byte) 0 -- vbuz1=vbuc1
lda #0
sta.z i
// [20] phi from main main::@1 to main::@1 [phi:main/main::@1->main::@1]
__b1_from_main: __b1_from_main:
// [21] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- vbuyy=vbuc1
ldy #0
jmp __b1
// [21] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
__b1_from___b1: __b1_from___b1:
// [21] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy
jmp __b1 jmp __b1
// main::@1 // main::@1
__b1: __b1:
// [21] callexecute pval -- jsr // [22] callexecute pval -- jsr
jsr pval jsr pval
// [22] callexecute printother -- jsr // [23] callexecute printother -- jsr
jsr printother jsr printother
// [23] callexecute ival -- jsr // [24] callexecute ival -- jsr
jsr ival jsr ival
// [24] (byte) main::i ← ++ (byte) main::i -- vbuz1=_inc_vbuz1 // [25] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuyy=_inc_vbuyy
inc.z i iny
// [25] if((byte) main::i!=(byte) 6) goto main::@1 -- vbuz1_neq_vbuc1_then_la1 // [26] if((byte) main::i#1!=(byte) 6) goto main::@1 -- vbuyy_neq_vbuc1_then_la1
lda #6 cpy #6
cmp.z i
bne __b1_from___b1 bne __b1_from___b1
jmp __breturn jmp __breturn
// main::@return // main::@return
__breturn: __breturn:
// [26] return // [27] return
rts rts
} }
// File Data // File Data
@ -558,22 +594,28 @@ Removing instruction jmp __b1
Removing instruction jmp __breturn Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination Succesful ASM optimization Pass5NextJumpElimination
Replacing label __b1_from___b1 with __b1 Replacing label __b1_from___b1 with __b1
Replacing label __b1_from___b1 with __b1
Removing instruction __b1_from___bbegin: Removing instruction __b1_from___bbegin:
Removing instruction __bend_from___b1: Removing instruction __bend_from___b1:
Removing instruction __b1_from_main: Removing instruction __b1_from___b1:
Removing instruction __b1_from___b1: Removing instruction __b1_from___b1:
Succesful ASM optimization Pass5RedundantLabelElimination Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __b1: Removing instruction __b1:
Removing instruction __bend: Removing instruction __bend:
Removing instruction __b1_from_printother:
Removing instruction __breturn: Removing instruction __breturn:
Removing instruction __breturn: Removing instruction __breturn:
Removing instruction __breturn: Removing instruction __breturn:
Removing instruction __breturn: Removing instruction __breturn:
Removing instruction __breturn: Removing instruction __breturn:
Removing instruction __b1_from_main:
Removing instruction __breturn: Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination Succesful ASM optimization Pass5UnusedLabelElimination
Adding RTS to root block Adding RTS to root block
Succesful ASM optimization Pass5AddMainRts Succesful ASM optimization Pass5AddMainRts
Removing instruction jmp __b1
Removing instruction jmp __b1
Succesful ASM optimization Pass5NextJumpElimination
FINAL SYMBOL TABLE FINAL SYMBOL TABLE
(label) @1 (label) @1
@ -587,24 +629,28 @@ __stackcall (void()) ival()
__stackcall (void()) main() __stackcall (void()) main()
(label) main::@1 (label) main::@1
(label) main::@return (label) main::@return
(byte) main::i loadstore zp[1]:4 5.0 (byte) main::i
(byte) main::i#1 reg byte y 16.5
(byte) main::i#2 reg byte y 5.5
__stackcall (void()) printother() __stackcall (void()) printother()
(label) printother::@1 (label) printother::@1
(label) printother::@return (label) printother::@return
(byte) printother::i loadstore zp[1]:3 14.25 (byte) printother::i
(byte) printother::i#1 reg byte x 16.5
(byte) printother::i#2 reg byte x 22.0
__stackcall (void()) printval() __stackcall (void()) printval()
(label) printval::@return (label) printval::@return
__stackcall (void()) pval() __stackcall (void()) pval()
(label) pval::@return (label) pval::@return
(byte) val loadstore zp[1]:2 0.42105263157894735 (byte) val loadstore zp[1]:2 0.42105263157894735
reg byte x [ printother::i#2 printother::i#1 ]
reg byte y [ main::i#2 main::i#1 ]
zp[1]:2 [ val ] zp[1]:2 [ val ]
zp[1]:3 [ printother::i ]
zp[1]:4 [ main::i ]
FINAL ASSEMBLER FINAL ASSEMBLER
Score: 617 Score: 497
// File Comments // File Comments
// Test a procedure with calling convention stack // Test a procedure with calling convention stack
@ -631,99 +677,95 @@ __bbegin:
// @end // @end
// printother // printother
printother: { printother: {
.label i = 3 // [5] phi from printother to printother::@1 [phi:printother->printother::@1]
// for(char i:0..5) // [5] phi (byte) printother::i#2 = (byte) 0 [phi:printother->printother::@1#0] -- vbuxx=vbuc1
// [4] (byte) printother::i ← (byte) 0 -- vbuz1=vbuc1 ldx #0
lda #0 // [5] phi from printother::@1 to printother::@1 [phi:printother::@1->printother::@1]
sta.z i // [5] phi (byte) printother::i#2 = (byte) printother::i#1 [phi:printother::@1->printother::@1#0] -- register_copy
// printother::@1 // printother::@1
__b1: __b1:
// (SCREEN+40)[i]++; // (SCREEN+40)[i]++;
// [5] *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) ← ++ *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) -- pbuc1_derefidx_vbuz1=_inc_pbuc1_derefidx_vbuz1 // [6] *((const byte*) SCREEN+(byte) $28 + (byte) printother::i#2) ← ++ *((const byte*) SCREEN+(byte) $28 + (byte) printother::i#2) -- pbuc1_derefidx_vbuxx=_inc_pbuc1_derefidx_vbuxx
ldx.z i
inc SCREEN+$28,x inc SCREEN+$28,x
// for(char i:0..5) // for(char i:0..5)
// [6] (byte) printother::i ← ++ (byte) printother::i -- vbuz1=_inc_vbuz1 // [7] (byte) printother::i#1 ← ++ (byte) printother::i#2 -- vbuxx=_inc_vbuxx
inc.z i inx
// [7] if((byte) printother::i!=(byte) 6) goto printother::@1 -- vbuz1_neq_vbuc1_then_la1 // [8] if((byte) printother::i#1!=(byte) 6) goto printother::@1 -- vbuxx_neq_vbuc1_then_la1
lda #6 cpx #6
cmp.z i
bne __b1 bne __b1
// printother::@return // printother::@return
// } // }
// [8] return // [9] return
rts rts
} }
// incval // incval
incval: { incval: {
// val++; // val++;
// [9] (byte) val ← ++ (byte) val -- vbuz1=_inc_vbuz1 // [10] (byte) val ← ++ (byte) val -- vbuz1=_inc_vbuz1
inc.z val inc.z val
// incval::@return // incval::@return
// } // }
// [10] return // [11] return
rts rts
} }
// printval // printval
printval: { printval: {
// SCREEN[0] = val // SCREEN[0] = val
// [11] *((const byte*) SCREEN) ← (byte) val -- _deref_pbuc1=vbuz1 // [12] *((const byte*) SCREEN) ← (byte) val -- _deref_pbuc1=vbuz1
lda.z val lda.z val
sta SCREEN sta SCREEN
// printval::@return // printval::@return
// } // }
// [12] return // [13] return
rts rts
} }
// ival // ival
ival: { ival: {
// incval() // incval()
// [14] callexecute incval -- jsr // [15] callexecute incval -- jsr
jsr incval jsr incval
// ival::@return // ival::@return
// } // }
// [15] return // [16] return
rts rts
} }
// pval // pval
pval: { pval: {
// printval() // printval()
// [17] callexecute printval -- jsr // [18] callexecute printval -- jsr
jsr printval jsr printval
// pval::@return // pval::@return
// } // }
// [18] return // [19] return
rts rts
} }
// main // main
main: { main: {
.label i = 4 // [21] phi from main to main::@1 [phi:main->main::@1]
// for(char i:0..5) // [21] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- vbuyy=vbuc1
// [19] (byte) main::i ← (byte) 0 -- vbuz1=vbuc1 ldy #0
lda #0 // [21] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
sta.z i // [21] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy
// [20] phi from main main::@1 to main::@1 [phi:main/main::@1->main::@1]
// main::@1 // main::@1
__b1: __b1:
// pval() // pval()
// [21] callexecute pval -- jsr // [22] callexecute pval -- jsr
jsr pval jsr pval
// printother() // printother()
// [22] callexecute printother -- jsr // [23] callexecute printother -- jsr
jsr printother jsr printother
// ival() // ival()
// [23] callexecute ival -- jsr // [24] callexecute ival -- jsr
jsr ival jsr ival
// for(char i:0..5) // for(char i:0..5)
// [24] (byte) main::i ← ++ (byte) main::i -- vbuz1=_inc_vbuz1 // [25] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuyy=_inc_vbuyy
inc.z i iny
// [25] if((byte) main::i!=(byte) 6) goto main::@1 -- vbuz1_neq_vbuc1_then_la1 // [26] if((byte) main::i#1!=(byte) 6) goto main::@1 -- vbuyy_neq_vbuc1_then_la1
lda #6 cpy #6
cmp.z i
bne __b1 bne __b1
// main::@return // main::@return
// } // }
// [26] return // [27] return
rts rts
} }
// File Data // File Data

View File

@ -9,17 +9,21 @@ __stackcall (void()) ival()
__stackcall (void()) main() __stackcall (void()) main()
(label) main::@1 (label) main::@1
(label) main::@return (label) main::@return
(byte) main::i loadstore zp[1]:4 5.0 (byte) main::i
(byte) main::i#1 reg byte y 16.5
(byte) main::i#2 reg byte y 5.5
__stackcall (void()) printother() __stackcall (void()) printother()
(label) printother::@1 (label) printother::@1
(label) printother::@return (label) printother::@return
(byte) printother::i loadstore zp[1]:3 14.25 (byte) printother::i
(byte) printother::i#1 reg byte x 16.5
(byte) printother::i#2 reg byte x 22.0
__stackcall (void()) printval() __stackcall (void()) printval()
(label) printval::@return (label) printval::@return
__stackcall (void()) pval() __stackcall (void()) pval()
(label) pval::@return (label) pval::@return
(byte) val loadstore zp[1]:2 0.42105263157894735 (byte) val loadstore zp[1]:2 0.42105263157894735
reg byte x [ printother::i#2 printother::i#1 ]
reg byte y [ main::i#2 main::i#1 ]
zp[1]:2 [ val ] zp[1]:2 [ val ]
zp[1]:3 [ printother::i ]
zp[1]:4 [ main::i ]