mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-02-27 16:30:14 +00:00
Now auto-converting global variables modified inside a __stackcall procedure to load/store.
This commit is contained in:
parent
d217113afb
commit
afe8294cd1
@ -53,6 +53,20 @@ public class Pass1CallStack extends Pass2SsaOptimization {
|
||||
if(createStackBase)
|
||||
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
|
||||
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
|
||||
ListIterator<Statement> stmtIt = block.getStatements().listIterator();
|
||||
|
@ -2,7 +2,6 @@
|
||||
// Returning and passing struct values
|
||||
|
||||
#pragma calling(__stackcall)
|
||||
#pragma var_model(ma_zp)
|
||||
|
||||
const char* SCREEN = 0x0400;
|
||||
char idx = 0;
|
||||
|
@ -2,7 +2,6 @@
|
||||
// Returning and passing struct of struct values
|
||||
|
||||
#pragma calling(__stackcall)
|
||||
#pragma var_model(ma_zp)
|
||||
|
||||
const char* SCREEN = 0x0400;
|
||||
char idx = 0;
|
||||
|
@ -2,7 +2,6 @@
|
||||
// Test that comments are handled correctly
|
||||
|
||||
#pragma calling(__stackcall)
|
||||
#pragma var_model(ma_zp)
|
||||
|
||||
const char* SCREEN = 0x0400;
|
||||
char idx = 0;
|
||||
|
@ -2,7 +2,6 @@
|
||||
// Illustrates live ranges for main::val and printline::i
|
||||
|
||||
#pragma calling(__stackcall)
|
||||
#pragma var_model(ma_zp)
|
||||
|
||||
const char* SCREEN = 0x0400;
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
// Illustrates live ranges for printline::i and global variable val
|
||||
|
||||
#pragma calling(__stackcall)
|
||||
#pragma var_model(ma_zp)
|
||||
|
||||
const char* SCREEN = 0x0400;
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
// Illustrates live range problem with function variable printother::i and global variable val
|
||||
|
||||
#pragma calling(__stackcall)
|
||||
#pragma var_model(ma_zp)
|
||||
|
||||
const char* SCREEN = 0x0400;
|
||||
|
||||
|
@ -4,9 +4,9 @@
|
||||
:BasicUpstart(__bbegin)
|
||||
.pc = $80d "Program"
|
||||
.label SCREEN = $400
|
||||
.const OFFSET_STRUCT_POINT_Y = 1
|
||||
.const STACK_BASE = $103
|
||||
.label idx = 2
|
||||
.const OFFSET_STRUCT_POINT_Y = 1
|
||||
.label idx = 3
|
||||
__bbegin:
|
||||
// idx = 0
|
||||
lda #0
|
||||
@ -39,20 +39,14 @@ print: {
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// get(byte register(X) i)
|
||||
get: {
|
||||
.const OFFSET_STACK_I = 0
|
||||
.label p = 6
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_I,x
|
||||
tax
|
||||
// i/2
|
||||
txa
|
||||
lsr
|
||||
// p = { i, i/2 }
|
||||
stx.z p
|
||||
sta p+OFFSET_STRUCT_POINT_Y
|
||||
// return p;
|
||||
tay
|
||||
// }
|
||||
txa
|
||||
@ -64,9 +58,7 @@ get: {
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
.label i = 3
|
||||
.label p = 4
|
||||
// i=0
|
||||
.label i = 2
|
||||
lda #0
|
||||
sta.z i
|
||||
__b1:
|
||||
@ -82,16 +74,15 @@ main: {
|
||||
pha
|
||||
pha
|
||||
jsr get
|
||||
// p = get(i)
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
tax
|
||||
pla
|
||||
// p = get(i)
|
||||
stx.z p
|
||||
sta p+OFFSET_STRUCT_POINT_Y
|
||||
// print(p)
|
||||
txa
|
||||
tya
|
||||
pha
|
||||
lda p+OFFSET_STRUCT_POINT_Y
|
||||
txa
|
||||
pha
|
||||
jsr print
|
||||
pla
|
||||
|
@ -23,40 +23,35 @@ print::@return: scope:[print] from print
|
||||
|
||||
__stackcall (struct Point()) get((byte) get::i)
|
||||
get: scope:[get] from
|
||||
[11] (byte) get::i#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I)
|
||||
[12] (byte~) get::$0 ← (byte) get::i#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)
|
||||
[11] (byte) get::return_x#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I)
|
||||
[12] (byte) get::return_y#0 ← (byte) get::return_x#0 >> (byte) 1
|
||||
to:get::@return
|
||||
get::@return: scope:[get] from get
|
||||
[17] stackidx(byte,(byte) 0) ← (byte) get::return_x#0
|
||||
[18] stackidx(byte,(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_y#0
|
||||
[19] return
|
||||
[13] stackidx(byte,(byte) 0) ← (byte) get::return_x#0
|
||||
[14] stackidx(byte,(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_y#0
|
||||
[15] return
|
||||
to:@return
|
||||
|
||||
__stackcall (void()) main()
|
||||
main: scope:[main] from
|
||||
[20] (byte) main::i ← (byte) 0
|
||||
[16] phi()
|
||||
to:main::@1
|
||||
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
|
||||
main::@return: scope:[main] from main::@1
|
||||
[22] return
|
||||
[19] return
|
||||
to:@return
|
||||
main::@2: scope:[main] from main::@1
|
||||
[23] stackpush(byte) ← (byte) main::i
|
||||
[20] stackpush(byte) ← (byte) main::i#2
|
||||
sideeffect stackpushbytes((number) 1)
|
||||
[25] callexecute get
|
||||
[26] (byte~) main::$1_x ← stackpull(byte)
|
||||
[27] (byte~) main::$1_y ← stackpull(byte)
|
||||
[28] *((byte*)&(struct Point) main::p) ← (byte~) main::$1_x
|
||||
[29] *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_y
|
||||
[30] stackpush(byte) ← *((byte*)&(struct Point) main::p)
|
||||
[31] stackpush(byte) ← *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y)
|
||||
[32] callexecute print
|
||||
[22] callexecute get
|
||||
[23] (byte) main::p_x#0 ← stackpull(byte)
|
||||
[24] (byte) main::p_y#0 ← stackpull(byte)
|
||||
[25] stackpush(byte) ← (byte) main::p_x#0
|
||||
[26] stackpush(byte) ← (byte) main::p_y#0
|
||||
[27] callexecute print
|
||||
sideeffect stackpullbytes((number) 2)
|
||||
[34] (byte) main::i ← ++ (byte) main::i
|
||||
[29] (byte) main::i#1 ← ++ (byte) main::i#2
|
||||
to:main::@1
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2,31 +2,33 @@
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const byte) OFFSET_STRUCT_POINT_Y = (byte) 1
|
||||
(byte) Point::x loadstore
|
||||
(byte) Point::y loadstore
|
||||
(byte) Point::x
|
||||
(byte) Point::y
|
||||
(const byte*) SCREEN = (byte*) 1024
|
||||
(const word) STACK_BASE = (word) $103
|
||||
__stackcall (struct Point()) get((byte) get::i)
|
||||
(byte~) get::$0 reg byte a 2.0
|
||||
(label) get::@return
|
||||
(const byte) get::OFFSET_STACK_I = (byte) 0
|
||||
(byte) get::i
|
||||
(byte) get::i#0 reg byte x 3.0
|
||||
(struct Point) get::p loadstore zp[2]:6
|
||||
(byte) get::p_x
|
||||
(byte) get::p_y
|
||||
(struct Point) get::return
|
||||
(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#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()
|
||||
(byte~) main::$1_x reg byte x 11.0
|
||||
(byte~) main::$1_y reg byte a 11.0
|
||||
(label) main::@1
|
||||
(label) main::@2
|
||||
(label) main::@return
|
||||
(byte) main::i loadstore zp[1]:3 3.2857142857142856
|
||||
(struct Point) main::p loadstore zp[2]:4
|
||||
(byte) main::i
|
||||
(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)
|
||||
(label) print::@return
|
||||
(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#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 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 y [ get::return_y#0 ]
|
||||
zp[1]:3 [ main::i ]
|
||||
reg byte x [ main::$1_x ]
|
||||
reg byte a [ main::$1_y ]
|
||||
zp[2]:4 [ main::p ]
|
||||
zp[2]:6 [ get::p ]
|
||||
reg byte y [ main::p_x#0 ]
|
||||
reg byte x [ main::p_y#0 ]
|
||||
|
@ -4,24 +4,24 @@
|
||||
:BasicUpstart(__bbegin)
|
||||
.pc = $80d "Program"
|
||||
.label SCREEN = $400
|
||||
.const STACK_BASE = $103
|
||||
.const OFFSET_STRUCT_POINT_Y = 1
|
||||
.const OFFSET_STRUCT_VECTOR_P2 = 2
|
||||
.const STACK_BASE = $103
|
||||
.label idx = 2
|
||||
.label idx = 3
|
||||
__bbegin:
|
||||
// idx = 0
|
||||
lda #0
|
||||
sta.z idx
|
||||
jsr main
|
||||
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: {
|
||||
.const OFFSET_STACK_V_P1_X = 3
|
||||
.const OFFSET_STACK_V_P1_Y = 2
|
||||
.const OFFSET_STACK_V_P2_X = 1
|
||||
.const OFFSET_STACK_V_P2_Y = 0
|
||||
.label v_p1_y = 3
|
||||
.label v_p2_x = 4
|
||||
.label v_p1_y = 4
|
||||
.label v_p2_x = 5
|
||||
// }
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_V_P1_X,x
|
||||
@ -68,51 +68,33 @@ print: {
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// get(byte register(Y) i)
|
||||
get: {
|
||||
.const OFFSET_STACK_I = 0
|
||||
.label __0 = 3
|
||||
.label __2 = 4
|
||||
.label v = $10
|
||||
.label return_p2_x = 6
|
||||
.label return_p2_y = 7
|
||||
.label return_p1_y = 4
|
||||
.label return_p2_y = 5
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_I,x
|
||||
tay
|
||||
// i/2
|
||||
tya
|
||||
lsr
|
||||
sta.z __0
|
||||
// i+1
|
||||
tya
|
||||
tax
|
||||
inx
|
||||
// i/2
|
||||
txa
|
||||
lsr
|
||||
sta.z return_p1_y
|
||||
// i+1
|
||||
txa
|
||||
tay
|
||||
iny
|
||||
// i*2
|
||||
tya
|
||||
txa
|
||||
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
|
||||
// }
|
||||
txa
|
||||
tsx
|
||||
sta STACK_BASE+0,x
|
||||
tya
|
||||
lda.z return_p1_y
|
||||
tsx
|
||||
sta STACK_BASE+OFFSET_STRUCT_POINT_Y,x
|
||||
lda.z return_p2_x
|
||||
tya
|
||||
tsx
|
||||
sta STACK_BASE+OFFSET_STRUCT_VECTOR_P2,x
|
||||
lda.z return_p2_y
|
||||
@ -121,11 +103,9 @@ get: {
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
.label i = 5
|
||||
.label v = $c
|
||||
.label __1_p2_x = 6
|
||||
.label __1_p2_y = 7
|
||||
// i=0
|
||||
.label v_p2_x = 4
|
||||
.label v_p2_y = 5
|
||||
.label i = 2
|
||||
lda #0
|
||||
sta.z i
|
||||
__b1:
|
||||
@ -143,29 +123,23 @@ main: {
|
||||
pha
|
||||
pha
|
||||
jsr get
|
||||
// v = get(i)
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
tax
|
||||
pla
|
||||
sta.z __1_p2_x
|
||||
sta.z v_p2_x
|
||||
pla
|
||||
sta.z __1_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
|
||||
sta.z v_p2_y
|
||||
// print(v)
|
||||
tya
|
||||
pha
|
||||
txa
|
||||
pha
|
||||
lda v+OFFSET_STRUCT_VECTOR_P2
|
||||
lda.z v_p2_x
|
||||
pha
|
||||
lda v+OFFSET_STRUCT_VECTOR_P2+OFFSET_STRUCT_POINT_Y
|
||||
lda.z v_p2_y
|
||||
pha
|
||||
jsr print
|
||||
tsx
|
||||
|
@ -31,54 +31,43 @@ print::@return: scope:[print] from print
|
||||
|
||||
__stackcall (struct Vector()) get((byte) get::i)
|
||||
get: scope:[get] from
|
||||
[19] (byte) get::i#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I)
|
||||
[20] (byte~) get::$0 ← (byte) get::i#0 >> (byte) 1
|
||||
[21] (byte~) get::$1 ← (byte) get::i#0 + (byte) 1
|
||||
[22] (byte~) get::$2 ← (byte) get::i#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)
|
||||
[19] (byte) get::return_p1_x#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I)
|
||||
[20] (byte) get::return_p1_y#0 ← (byte) get::return_p1_x#0 >> (byte) 1
|
||||
[21] (byte) get::return_p2_x#0 ← (byte) get::return_p1_x#0 + (byte) 1
|
||||
[22] (byte) get::return_p2_y#0 ← (byte) get::return_p1_x#0 << (byte) 1
|
||||
to:get::@return
|
||||
get::@return: scope:[get] from get
|
||||
[31] 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
|
||||
[33] 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
|
||||
[35] return
|
||||
[23] stackidx(byte,(byte) 0) ← (byte) get::return_p1_x#0
|
||||
[24] stackidx(byte,(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_p1_y#0
|
||||
[25] stackidx(byte,(const byte) OFFSET_STRUCT_VECTOR_P2) ← (byte) get::return_p2_x#0
|
||||
[26] stackidx(byte,(const byte) OFFSET_STRUCT_VECTOR_P2+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_p2_y#0
|
||||
[27] return
|
||||
to:@return
|
||||
|
||||
__stackcall (void()) main()
|
||||
main: scope:[main] from
|
||||
[36] (byte) main::i ← (byte) 0
|
||||
[28] phi()
|
||||
to:main::@1
|
||||
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
|
||||
main::@return: scope:[main] from main::@1
|
||||
[38] return
|
||||
[31] return
|
||||
to:@return
|
||||
main::@2: scope:[main] from main::@1
|
||||
[39] stackpush(byte) ← (byte) main::i
|
||||
[32] stackpush(byte) ← (byte) main::i#2
|
||||
sideeffect stackpushbytes((number) 3)
|
||||
[41] callexecute get
|
||||
[42] (byte~) main::$1_p1_x ← stackpull(byte)
|
||||
[43] (byte~) main::$1_p1_y ← stackpull(byte)
|
||||
[44] (byte~) main::$1_p2_x ← stackpull(byte)
|
||||
[45] (byte~) main::$1_p2_y ← stackpull(byte)
|
||||
[46] *((byte*)(struct Point*)&(struct Vector) main::v) ← (byte~) main::$1_p1_x
|
||||
[47] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_p1_y
|
||||
[48] *((byte*)(struct Point*)&(struct Vector) main::v+(const byte) OFFSET_STRUCT_VECTOR_P2) ← (byte~) main::$1_p2_x
|
||||
[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
|
||||
[50] stackpush(byte) ← *((byte*)(struct Point*)&(struct Vector) main::v)
|
||||
[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
|
||||
[34] callexecute get
|
||||
[35] (byte) main::v_p1_x#0 ← stackpull(byte)
|
||||
[36] (byte) main::v_p1_y#0 ← stackpull(byte)
|
||||
[37] (byte) main::v_p2_x#0 ← stackpull(byte)
|
||||
[38] (byte) main::v_p2_y#0 ← stackpull(byte)
|
||||
[39] stackpush(byte) ← (byte) main::v_p1_x#0
|
||||
[40] stackpush(byte) ← (byte) main::v_p1_y#0
|
||||
[41] stackpush(byte) ← (byte) main::v_p2_x#0
|
||||
[42] stackpush(byte) ← (byte) main::v_p2_y#0
|
||||
[43] callexecute print
|
||||
sideeffect stackpullbytes((number) 4)
|
||||
[56] (byte) main::i ← ++ (byte) main::i
|
||||
[45] (byte) main::i#1 ← ++ (byte) main::i#2
|
||||
to:main::@1
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -3,43 +3,51 @@
|
||||
(label) @end
|
||||
(const byte) OFFSET_STRUCT_POINT_Y = (byte) 1
|
||||
(const byte) OFFSET_STRUCT_VECTOR_P2 = (byte) 2
|
||||
(byte) Point::x loadstore
|
||||
(byte) Point::y loadstore
|
||||
(byte) Point::x
|
||||
(byte) Point::y
|
||||
(const byte*) SCREEN = (byte*) 1024
|
||||
(const word) STACK_BASE = (word) $103
|
||||
(struct Point) Vector::p1 loadstore zp[2]:8
|
||||
(struct Point) Vector::p2 loadstore zp[2]:10
|
||||
(struct Point) Vector::p1
|
||||
(struct Point) Vector::p2
|
||||
__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
|
||||
(const byte) get::OFFSET_STACK_I = (byte) 0
|
||||
(byte) get::i
|
||||
(byte) get::i#0 reg byte y 2.5
|
||||
(struct Vector) get::return
|
||||
(struct Point) get::return_p1
|
||||
(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#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
|
||||
(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#0 return_p2_y zp[1]:7 1.0
|
||||
(struct Vector) get::v loadstore zp[4]:16
|
||||
(byte) idx loadstore zp[1]:2 0.8648648648648649
|
||||
(byte) get::return_p2_y#0 return_p2_y zp[1]:5 1.0
|
||||
(struct Point) get::v_p1
|
||||
(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()
|
||||
(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::@2
|
||||
(label) main::@return
|
||||
(byte) main::i loadstore zp[1]:5 2.3000000000000003
|
||||
(struct Vector) main::v loadstore zp[4]:12
|
||||
(byte) main::i
|
||||
(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)
|
||||
(label) print::@return
|
||||
(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#0 reg byte y 1.0
|
||||
(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
|
||||
(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#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 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 y [ get::return_p1_y#0 ]
|
||||
zp[1]:5 [ main::i ]
|
||||
reg byte y [ main::$1_p1_x ]
|
||||
reg byte x [ main::$1_p1_y ]
|
||||
zp[1]:6 [ main::$1_p2_x get::return_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 ]
|
||||
reg byte y [ get::return_p2_x#0 ]
|
||||
reg byte y [ main::v_p1_x#0 ]
|
||||
reg byte x [ main::v_p1_y#0 ]
|
||||
zp[1]:4 [ main::v_p2_x#0 get::return_p1_y#0 print::v_p1_y#0 ]
|
||||
zp[1]:5 [ main::v_p2_y#0 get::return_p2_y#0 print::v_p2_x#0 ]
|
||||
|
@ -16,7 +16,6 @@ __bbegin:
|
||||
print: {
|
||||
.const OFFSET_STACK_STR = 1
|
||||
.const OFFSET_STACK_SPACING = 0
|
||||
.label c = 6
|
||||
.label str = 2
|
||||
.label spacing = 5
|
||||
// }
|
||||
@ -48,13 +47,10 @@ print: {
|
||||
bne !+
|
||||
inc.z str+1
|
||||
!:
|
||||
// c=0
|
||||
lda #0
|
||||
sta.z c
|
||||
ldx #0
|
||||
__b3:
|
||||
// for(char c=0;c<spacing;c++)
|
||||
lda.z c
|
||||
cmp.z spacing
|
||||
cpx.z spacing
|
||||
bcc __b4
|
||||
jmp __b1
|
||||
__b4:
|
||||
@ -65,7 +61,7 @@ print: {
|
||||
// SCREEN[idx++] = ' ';
|
||||
inc.z idx
|
||||
// for(char c=0;c<spacing;c++)
|
||||
inc.z c
|
||||
inx
|
||||
jmp __b3
|
||||
}
|
||||
main: {
|
||||
|
@ -24,15 +24,15 @@ print::@2: scope:[print] from print::@1
|
||||
[9] *((const byte*) SCREEN + (byte) idx) ← *((byte*) print::str#2)
|
||||
[10] (byte) idx ← ++ (byte) idx
|
||||
[11] (byte*) print::str#1 ← ++ (byte*) print::str#2
|
||||
[12] (byte) print::c ← (byte) 0
|
||||
to:print::@3
|
||||
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
|
||||
print::@4: scope:[print] from print::@3
|
||||
[14] *((const byte*) SCREEN + (byte) idx) ← (byte) ' '
|
||||
[15] (byte) idx ← ++ (byte) idx
|
||||
[16] (byte) print::c ← ++ (byte) print::c
|
||||
[16] (byte) print::c#1 ← ++ (byte) print::c#2
|
||||
to:print::@3
|
||||
|
||||
__stackcall (void()) main()
|
||||
|
@ -8,6 +8,7 @@ Culled Empty Block (label) print::@6
|
||||
Culled Empty Block (label) print::@8
|
||||
Culled Empty Block (label) print::@9
|
||||
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::str1 (number) 2
|
||||
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)
|
||||
(byte) idx ← ++ (byte) idx
|
||||
(byte*) print::str#1 ← ++ (byte*) print::str#3
|
||||
(byte) print::c ← (byte) 0
|
||||
(byte) print::c#0 ← (byte) 0
|
||||
to:print::@4
|
||||
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::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
|
||||
to:print::@1
|
||||
print::@5: scope:[print] from print::@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::c#3 ← phi( print::@4/(byte) print::c#2 )
|
||||
*((const byte*) SCREEN + (byte) idx) ← (byte) ' '
|
||||
(byte) idx ← ++ (byte) idx
|
||||
(byte) print::c ← ++ (byte) print::c
|
||||
(byte) print::c#1 ← ++ (byte) print::c#3
|
||||
to:print::@4
|
||||
print::@return: scope:[print] from print::@1
|
||||
return
|
||||
@ -99,7 +102,11 @@ __stackcall (void()) print((byte*) print::str , (byte) print::spacing)
|
||||
(label) print::@return
|
||||
(const byte) print::OFFSET_STACK_SPACING = (byte) 0
|
||||
(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#0
|
||||
(byte) print::spacing#1
|
||||
@ -132,6 +139,7 @@ Finalized unsigned number type (byte) 0
|
||||
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||
Alias (byte*) print::str#2 = (byte*) print::str#3
|
||||
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::str#4 = (byte*) print::str#5
|
||||
Successful SSA optimization Pass2AliasElimination
|
||||
@ -141,19 +149,25 @@ Successful SSA optimization Pass2IdenticalPhiElimination
|
||||
Identical Phi Values (byte) print::spacing#2 (byte) print::spacing#0
|
||||
Successful SSA optimization Pass2IdenticalPhiElimination
|
||||
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
|
||||
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)
|
||||
Adding NOP phi() at start of @2
|
||||
Adding NOP phi() at start of @end
|
||||
CALL GRAPH
|
||||
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 [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
|
||||
Renumbering block @2 to @1
|
||||
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)
|
||||
[10] (byte) idx ← ++ (byte) idx
|
||||
[11] (byte*) print::str#1 ← ++ (byte*) print::str#2
|
||||
[12] (byte) print::c ← (byte) 0
|
||||
to:print::@3
|
||||
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
|
||||
print::@4: scope:[print] from print::@3
|
||||
[14] *((const byte*) SCREEN + (byte) idx) ← (byte) ' '
|
||||
[15] (byte) idx ← ++ (byte) idx
|
||||
[16] (byte) print::c ← ++ (byte) print::c
|
||||
[16] (byte) print::c#1 ← ++ (byte) print::c#2
|
||||
to:print::@3
|
||||
|
||||
__stackcall (void()) main()
|
||||
@ -219,7 +233,9 @@ VARIABLE REGISTER WEIGHTS
|
||||
(byte) idx loadstore 16.095238095238095
|
||||
__stackcall (void()) main()
|
||||
__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#0 9.363636363636363
|
||||
(byte*) print::str
|
||||
@ -229,18 +245,18 @@ __stackcall (void()) print((byte*) print::str , (byte) print::spacing)
|
||||
|
||||
Initial phi equivalence classes
|
||||
[ 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 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
|
||||
[ print::str#2 print::str#0 print::str#1 ]
|
||||
[ print::c#2 print::c#1 ]
|
||||
[ idx ]
|
||||
[ print::spacing#0 ]
|
||||
[ print::c ]
|
||||
Allocated zp[2]:2 [ print::str#2 print::str#0 print::str#1 ]
|
||||
Allocated zp[1]:4 [ idx ]
|
||||
Allocated zp[1]:5 [ print::spacing#0 ]
|
||||
Allocated zp[1]:6 [ print::c ]
|
||||
Allocated zp[1]:4 [ print::c#2 print::c#1 ]
|
||||
Allocated zp[1]:5 [ idx ]
|
||||
Allocated zp[1]:6 [ print::spacing#0 ]
|
||||
|
||||
INITIAL ASM
|
||||
Target platform is c64basic / MOS6502X
|
||||
@ -254,7 +270,7 @@ Target platform is c64basic / MOS6502X
|
||||
// Global Constants & labels
|
||||
.label SCREEN = $400
|
||||
.const STACK_BASE = $103
|
||||
.label idx = 4
|
||||
.label idx = 5
|
||||
// @begin
|
||||
__bbegin:
|
||||
// [0] (byte) idx ← (byte) 0 -- vbuz1=vbuc1
|
||||
@ -273,13 +289,13 @@ __bend_from___b1:
|
||||
// @end
|
||||
__bend:
|
||||
// print
|
||||
// print(byte* zp(2) str, byte zp(5) spacing)
|
||||
// print(byte* zp(2) str, byte zp(6) spacing)
|
||||
print: {
|
||||
.const OFFSET_STACK_STR = 1
|
||||
.const OFFSET_STACK_SPACING = 0
|
||||
.label c = 6
|
||||
.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
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_STR,x
|
||||
@ -321,13 +337,15 @@ print: {
|
||||
bne !+
|
||||
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
|
||||
sta.z c
|
||||
jmp __b3
|
||||
// print::@3
|
||||
__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
|
||||
cmp.z spacing
|
||||
bcc __b4
|
||||
@ -340,8 +358,11 @@ print: {
|
||||
sta SCREEN,y
|
||||
// [15] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1
|
||||
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
|
||||
// [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
|
||||
}
|
||||
// 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 [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
|
||||
Removing always clobbered register reg byte a as potential for zp[1]:5 [ 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 a as potential for zp[1]:6 [ 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
|
||||
Removing always clobbered register reg byte x as potential for zp[1]:5 [ 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 [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
|
||||
Removing always clobbered register reg byte x as potential for zp[1]:6 [ print::spacing#0 ]
|
||||
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
|
||||
Removing always clobbered register reg byte a as potential for zp[1]:4 [ print::c#2 print::c#1 ]
|
||||
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 [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
|
||||
@ -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 [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 [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 [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 [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 [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 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 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[1]:4 [ idx ] : zp[1]:4 ,
|
||||
Potential registers zp[1]:5 [ print::spacing#0 ] : zp[1]:5 ,
|
||||
Potential registers zp[1]:6 [ print::c ] : zp[1]:6 ,
|
||||
Potential registers zp[1]:4 [ print::c#2 print::c#1 ] : zp[1]:4 , reg byte x ,
|
||||
Potential registers zp[1]:5 [ idx ] : zp[1]:5 ,
|
||||
Potential registers zp[1]:6 [ print::spacing#0 ] : zp[1]:6 ,
|
||||
|
||||
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 [] 16.1: zp[1]:4 [ idx ]
|
||||
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]:5 [ idx ]
|
||||
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 [] best 4156 combination zp[1]:4 [ idx ]
|
||||
Uplifting [main] best 4156 combination
|
||||
Attempting to uplift remaining variables inzp[1]:6 [ print::c ]
|
||||
Uplifting [print] best 4156 combination zp[1]:6 [ print::c ]
|
||||
Attempting to uplift remaining variables inzp[1]:4 [ idx ]
|
||||
Uplifting [] best 4156 combination zp[1]:4 [ idx ]
|
||||
Attempting to uplift remaining variables inzp[1]:5 [ print::spacing#0 ]
|
||||
Uplifting [print] best 4156 combination 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 3976 combination zp[1]:5 [ idx ]
|
||||
Uplifting [main] best 3976 combination
|
||||
Attempting to uplift remaining variables inzp[1]:5 [ idx ]
|
||||
Uplifting [] best 3976 combination zp[1]:5 [ idx ]
|
||||
Attempting to uplift remaining variables inzp[1]:6 [ print::spacing#0 ]
|
||||
Uplifting [print] best 3976 combination zp[1]:6 [ print::spacing#0 ]
|
||||
Allocated (was zp[1]:5) zp[1]:4 [ idx ]
|
||||
Allocated (was zp[1]:6) zp[1]:5 [ print::spacing#0 ]
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
// File Comments
|
||||
@ -476,7 +495,6 @@ __bend:
|
||||
print: {
|
||||
.const OFFSET_STACK_STR = 1
|
||||
.const OFFSET_STACK_SPACING = 0
|
||||
.label c = 6
|
||||
.label str = 2
|
||||
.label spacing = 5
|
||||
// [4] (byte*) print::str#0 ← stackidx(byte*,(const byte) print::OFFSET_STACK_STR) -- pbuz1=_stackidxptr_vbuc1
|
||||
@ -520,15 +538,15 @@ print: {
|
||||
bne !+
|
||||
inc.z str+1
|
||||
!:
|
||||
// [12] (byte) print::c ← (byte) 0 -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z c
|
||||
// [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] -- vbuxx=vbuc1
|
||||
ldx #0
|
||||
jmp __b3
|
||||
// print::@3
|
||||
__b3:
|
||||
// [13] if((byte) print::c<(byte) print::spacing#0) goto print::@4 -- vbuz1_lt_vbuz2_then_la1
|
||||
lda.z c
|
||||
cmp.z spacing
|
||||
// [13] if((byte) print::c#2<(byte) print::spacing#0) goto print::@4 -- vbuxx_lt_vbuz1_then_la1
|
||||
cpx.z spacing
|
||||
bcc __b4
|
||||
jmp __b1_from___b3
|
||||
// print::@4
|
||||
@ -539,8 +557,11 @@ print: {
|
||||
sta SCREEN,y
|
||||
// [15] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1
|
||||
inc.z idx
|
||||
// [16] (byte) print::c ← ++ (byte) print::c -- vbuz1=_inc_vbuz1
|
||||
inc.z c
|
||||
// [16] (byte) print::c#1 ← ++ (byte) print::c#2 -- vbuxx=_inc_vbuxx
|
||||
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
|
||||
}
|
||||
// main
|
||||
@ -606,6 +627,8 @@ Succesful ASM optimization Pass5RedundantLabelElimination
|
||||
Removing instruction __b1:
|
||||
Removing instruction __bend:
|
||||
Removing instruction __breturn:
|
||||
Removing instruction __b3_from___b2:
|
||||
Removing instruction __b3_from___b4:
|
||||
Removing instruction __breturn:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
Adding RTS to root block
|
||||
@ -630,7 +653,9 @@ __stackcall (void()) print((byte*) print::str , (byte) print::spacing)
|
||||
(label) print::@return
|
||||
(const byte) print::OFFSET_STACK_SPACING = (byte) 0
|
||||
(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#0 spacing zp[1]:5 9.363636363636363
|
||||
(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
|
||||
|
||||
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]:5 [ print::spacing#0 ]
|
||||
zp[1]:6 [ print::c ]
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 4063
|
||||
Score: 3613
|
||||
|
||||
// File Comments
|
||||
// Test a procedure with calling convention stack
|
||||
@ -676,7 +701,6 @@ __bbegin:
|
||||
print: {
|
||||
.const OFFSET_STACK_STR = 1
|
||||
.const OFFSET_STACK_SPACING = 0
|
||||
.label c = 6
|
||||
.label str = 2
|
||||
.label spacing = 5
|
||||
// }
|
||||
@ -720,16 +744,14 @@ print: {
|
||||
bne !+
|
||||
inc.z str+1
|
||||
!:
|
||||
// c=0
|
||||
// [12] (byte) print::c ← (byte) 0 -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z c
|
||||
// [12] phi from print::@2 to print::@3 [phi:print::@2->print::@3]
|
||||
// [12] phi (byte) print::c#2 = (byte) 0 [phi:print::@2->print::@3#0] -- vbuxx=vbuc1
|
||||
ldx #0
|
||||
// print::@3
|
||||
__b3:
|
||||
// for(char c=0;c<spacing;c++)
|
||||
// [13] if((byte) print::c<(byte) print::spacing#0) goto print::@4 -- vbuz1_lt_vbuz2_then_la1
|
||||
lda.z c
|
||||
cmp.z spacing
|
||||
// [13] if((byte) print::c#2<(byte) print::spacing#0) goto print::@4 -- vbuxx_lt_vbuz1_then_la1
|
||||
cpx.z spacing
|
||||
bcc __b4
|
||||
jmp __b1
|
||||
// print::@4
|
||||
@ -743,8 +765,10 @@ print: {
|
||||
// [15] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1
|
||||
inc.z idx
|
||||
// for(char c=0;c<spacing;c++)
|
||||
// [16] (byte) print::c ← ++ (byte) print::c -- vbuz1=_inc_vbuz1
|
||||
inc.z c
|
||||
// [16] (byte) print::c#1 ← ++ (byte) print::c#2 -- vbuxx=_inc_vbuxx
|
||||
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
|
||||
}
|
||||
// main
|
||||
|
@ -16,7 +16,9 @@ __stackcall (void()) print((byte*) print::str , (byte) print::spacing)
|
||||
(label) print::@return
|
||||
(const byte) print::OFFSET_STACK_SPACING = (byte) 0
|
||||
(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#0 spacing zp[1]:5 9.363636363636363
|
||||
(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
|
||||
|
||||
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]:5 [ print::spacing#0 ]
|
||||
zp[1]:6 [ print::c ]
|
||||
|
@ -1,16 +1,24 @@
|
||||
// Test a procedure with calling convention stack
|
||||
// A slightly more complex call
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
:BasicUpstart(__bbegin)
|
||||
.pc = $80d "Program"
|
||||
.label SCREEN = $400
|
||||
.const STACK_BASE = $103
|
||||
.label i = 3
|
||||
__bbegin:
|
||||
// i = 0
|
||||
lda #0
|
||||
sta.z i
|
||||
jsr main
|
||||
rts
|
||||
main: {
|
||||
ldy #0
|
||||
.label a = 2
|
||||
lda #0
|
||||
sta.z a
|
||||
__b1:
|
||||
// v = a+1
|
||||
tya
|
||||
tax
|
||||
ldx.z a
|
||||
inx
|
||||
// plus('0', v)
|
||||
lda #'0'
|
||||
@ -22,29 +30,32 @@ main: {
|
||||
// w = plus('0', v)
|
||||
pla
|
||||
// w+a
|
||||
sty.z $ff
|
||||
clc
|
||||
adc.z $ff
|
||||
adc.z a
|
||||
// SCREEN[i] = w+a
|
||||
sta SCREEN
|
||||
ldy.z i
|
||||
sta SCREEN,y
|
||||
// for(char a:0..1)
|
||||
iny
|
||||
cpy #2
|
||||
inc.z a
|
||||
lda #2
|
||||
cmp.z a
|
||||
bne __b1
|
||||
// }
|
||||
rts
|
||||
}
|
||||
// plus(byte zp(2) a, byte register(A) b)
|
||||
// plus(byte zp(4) a, byte register(A) b)
|
||||
plus: {
|
||||
.const OFFSET_STACK_A = 1
|
||||
.const OFFSET_STACK_B = 0
|
||||
.const OFFSET_STACK_RETURN = 1
|
||||
.label a = 2
|
||||
.label a = 4
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_A,x
|
||||
sta.z a
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_B,x
|
||||
// i++;
|
||||
inc.z i
|
||||
// return a+b;
|
||||
clc
|
||||
adc.z a
|
||||
|
@ -1,5 +1,5 @@
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
[0] (byte) i ← (byte) 0
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
@ -21,7 +21,7 @@ main::@1: scope:[main] from main main::@1
|
||||
sideeffect stackpullbytes((number) 1)
|
||||
[11] (byte) main::w#0 ← stackpull(byte)
|
||||
[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
|
||||
[15] if((byte) main::a#1!=(byte) 2) goto main::@1
|
||||
to:main::@return
|
||||
@ -33,9 +33,10 @@ __stackcall (byte()) plus((byte) plus::a , (byte) plus::b)
|
||||
plus: scope:[plus] from
|
||||
[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)
|
||||
[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
|
||||
plus::@return: scope:[plus] from plus
|
||||
[20] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0
|
||||
[21] return
|
||||
[21] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0
|
||||
[22] return
|
||||
to:@return
|
||||
|
@ -1,6 +1,7 @@
|
||||
Culled Empty Block (label) main::@2
|
||||
Culled Empty Block (label) @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 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)
|
||||
@ -11,16 +12,14 @@ Calling convention STACK_CALL adding stack push stackpush(byte) ← main::v
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
@begin: scope:[] from
|
||||
(byte) i#0 ← (byte) 0
|
||||
(byte) i ← (byte) 0
|
||||
to:@2
|
||||
|
||||
(void()) main()
|
||||
main: scope:[main] from @2
|
||||
(byte) i#8 ← phi( @2/(byte) i#9 )
|
||||
(byte) main::a#0 ← (byte) 0
|
||||
to: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 )
|
||||
(number~) main::$0 ← (byte) main::a#2 + (number) 1
|
||||
(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::w#0 ← (byte~) main::$1
|
||||
(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)
|
||||
(bool~) main::$3 ← (byte) main::a#1 != rangelast(0,1)
|
||||
if((bool~) main::$3) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
(byte) i#5 ← phi( main::@1/(byte) i#4 )
|
||||
(byte) i#1 ← (byte) i#5
|
||||
return
|
||||
to:@return
|
||||
|
||||
__stackcall (byte()) plus((byte) plus::a , (byte) plus::b)
|
||||
plus: scope:[plus] from
|
||||
(byte) i#6 ← phi( )
|
||||
(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) i#2 ← ++ (byte) i#6
|
||||
(byte) i ← ++ (byte) i
|
||||
(byte~) plus::$0 ← (byte) plus::a#0 + (byte) plus::b#0
|
||||
(byte) plus::return#0 ← (byte~) plus::$0
|
||||
to:plus::@return
|
||||
@ -57,12 +53,9 @@ plus::@return: scope:[plus] from plus
|
||||
return
|
||||
to:@return
|
||||
@2: scope:[] from @begin
|
||||
(byte) i#9 ← phi( @begin/(byte) i#0 )
|
||||
call main
|
||||
to:@3
|
||||
@3: scope:[] from @2
|
||||
(byte) i#7 ← phi( @2/(byte) i#1 )
|
||||
(byte) i#3 ← (byte) i#7
|
||||
to:@end
|
||||
@end: scope:[] from @3
|
||||
|
||||
@ -73,17 +66,7 @@ SYMBOL TABLE SSA
|
||||
(label) @end
|
||||
(const byte*) SCREEN = (byte*)(number) $400
|
||||
(const word) STACK_BASE = (word) $103
|
||||
(byte) i
|
||||
(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
|
||||
(byte) i loadstore
|
||||
(void()) main()
|
||||
(number~) main::$0
|
||||
(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
|
||||
Alias (byte) main::v#0 = (byte~) main::$0
|
||||
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) i#0 = (byte) i#9
|
||||
Alias (byte) i#3 = (byte) i#7
|
||||
Successful SSA optimization Pass2AliasElimination
|
||||
Identical Phi Values (byte) i#8 (byte) i#0
|
||||
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
|
||||
Simple Condition (bool~) main::$3 [13] if((byte) main::a#1!=rangelast(0,1)) goto main::@1
|
||||
Successful SSA optimization Pass2ConditionalJumpSimplification
|
||||
Constant (const byte) i#0 = 0
|
||||
Constant (const byte) main::a#0 = 0
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Resolved ranged next value [12] 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
|
||||
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
|
||||
Resolved ranged next value [11] main::a#1 ← ++ main::a#2 to ++
|
||||
Resolved ranged comparison value [13] if(main::a#1!=rangelast(0,1)) goto main::@1 to (number) 2
|
||||
Adding number conversion cast (unumber) 2 in if((byte) main::a#1!=(number) 2) goto main::@1
|
||||
Successful SSA optimization PassNAddNumberTypeConversions
|
||||
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
|
||||
Successful SSA optimization Pass2ConstantInlining
|
||||
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 @3
|
||||
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) main::@3
|
||||
Renumbering block @2 to @1
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @1
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of main
|
||||
|
||||
FINAL CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
[0] phi()
|
||||
[0] (byte) i ← (byte) 0
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
@ -201,7 +167,7 @@ main::@1: scope:[main] from main main::@1
|
||||
sideeffect stackpullbytes((number) 1)
|
||||
[11] (byte) main::w#0 ← stackpull(byte)
|
||||
[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
|
||||
[15] if((byte) main::a#1!=(byte) 2) goto main::@1
|
||||
to:main::@return
|
||||
@ -213,16 +179,17 @@ __stackcall (byte()) plus((byte) plus::a , (byte) plus::b)
|
||||
plus: scope:[plus] from
|
||||
[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)
|
||||
[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
|
||||
plus::@return: scope:[plus] from plus
|
||||
[20] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0
|
||||
[21] return
|
||||
[21] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0
|
||||
[22] return
|
||||
to:@return
|
||||
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
(byte) i
|
||||
(byte) i loadstore 0.85
|
||||
(void()) main()
|
||||
(byte~) main::$2 22.0
|
||||
(byte) main::a
|
||||
@ -234,14 +201,15 @@ VARIABLE REGISTER WEIGHTS
|
||||
(byte) main::w#0 22.0
|
||||
__stackcall (byte()) plus((byte) plus::a , (byte) plus::b)
|
||||
(byte) plus::a
|
||||
(byte) plus::a#0 2.0
|
||||
(byte) plus::a#0 1.3333333333333333
|
||||
(byte) plus::b
|
||||
(byte) plus::b#0 4.0
|
||||
(byte) plus::b#0 2.0
|
||||
(byte) plus::return
|
||||
(byte) plus::return#0 4.0
|
||||
|
||||
Initial phi equivalence classes
|
||||
[ 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::w#0 to live range equivalence class [ main::w#0 ]
|
||||
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 ]
|
||||
Complete equivalence classes
|
||||
[ main::a#2 main::a#1 ]
|
||||
[ i ]
|
||||
[ main::v#0 ]
|
||||
[ main::w#0 ]
|
||||
[ main::$2 ]
|
||||
@ -257,12 +226,13 @@ Complete equivalence classes
|
||||
[ plus::b#0 ]
|
||||
[ plus::return#0 ]
|
||||
Allocated zp[1]:2 [ main::a#2 main::a#1 ]
|
||||
Allocated zp[1]:3 [ main::v#0 ]
|
||||
Allocated zp[1]:4 [ main::w#0 ]
|
||||
Allocated zp[1]:5 [ main::$2 ]
|
||||
Allocated zp[1]:6 [ plus::a#0 ]
|
||||
Allocated zp[1]:7 [ plus::b#0 ]
|
||||
Allocated zp[1]:8 [ plus::return#0 ]
|
||||
Allocated zp[1]:3 [ i ]
|
||||
Allocated zp[1]:4 [ main::v#0 ]
|
||||
Allocated zp[1]:5 [ main::w#0 ]
|
||||
Allocated zp[1]:6 [ main::$2 ]
|
||||
Allocated zp[1]:7 [ plus::a#0 ]
|
||||
Allocated zp[1]:8 [ plus::b#0 ]
|
||||
Allocated zp[1]:9 [ plus::return#0 ]
|
||||
|
||||
INITIAL ASM
|
||||
Target platform is c64basic / MOS6502X
|
||||
@ -276,8 +246,12 @@ Target platform is c64basic / MOS6502X
|
||||
// Global Constants & labels
|
||||
.label SCREEN = $400
|
||||
.const STACK_BASE = $103
|
||||
.label i = 3
|
||||
// @begin
|
||||
__bbegin:
|
||||
// [0] (byte) i ← (byte) 0 -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z i
|
||||
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
__b1_from___bbegin:
|
||||
jmp __b1
|
||||
@ -294,9 +268,9 @@ __bend_from___b1:
|
||||
__bend:
|
||||
// main
|
||||
main: {
|
||||
.label __2 = 5
|
||||
.label v = 3
|
||||
.label w = 4
|
||||
.label __2 = 6
|
||||
.label v = 4
|
||||
.label w = 5
|
||||
.label a = 2
|
||||
// [5] phi from main to main::@1 [phi:main->main::@1]
|
||||
__b1_from_main:
|
||||
@ -332,9 +306,10 @@ main: {
|
||||
clc
|
||||
adc.z a
|
||||
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
|
||||
sta SCREEN
|
||||
ldy.z i
|
||||
sta SCREEN,y
|
||||
// [14] (byte) main::a#1 ← ++ (byte) main::a#2 -- vbuz1=_inc_vbuz1
|
||||
inc.z a
|
||||
// [15] if((byte) main::a#1!=(byte) 2) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
|
||||
@ -348,14 +323,14 @@ main: {
|
||||
rts
|
||||
}
|
||||
// plus
|
||||
// plus(byte zp(6) a, byte zp(7) b)
|
||||
// plus(byte zp(7) a, byte zp(8) b)
|
||||
plus: {
|
||||
.const OFFSET_STACK_A = 1
|
||||
.const OFFSET_STACK_B = 0
|
||||
.const OFFSET_STACK_RETURN = 1
|
||||
.label a = 6
|
||||
.label b = 7
|
||||
.label return = 8
|
||||
.label a = 7
|
||||
.label b = 8
|
||||
.label return = 9
|
||||
// [17] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_A,x
|
||||
@ -364,7 +339,9 @@ plus: {
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_B,x
|
||||
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
|
||||
clc
|
||||
adc.z b
|
||||
@ -372,58 +349,69 @@ plus: {
|
||||
jmp __breturn
|
||||
// plus::@return
|
||||
__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
|
||||
tsx
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN,x
|
||||
// [21] return
|
||||
// [22] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
||||
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]:3 [ main::v#0 ]
|
||||
Statement [8] stackpush(byte) ← (byte) main::v#0 [ main::a#2 ] ( main:2 [ main::a#2 ] ) always clobbers reg byte a
|
||||
Removing always clobbered register reg byte a as potential for zp[1]:4 [ main::v#0 ]
|
||||
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 [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 [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 [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 [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 [ i main::a#2 main::$2 ] ( main:2 [ i main::a#2 main::$2 ] ) always clobbers reg byte a
|
||||
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 ]
|
||||
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
|
||||
Removing always clobbered register reg byte a as potential for zp[1]:6 [ plus::a#0 ]
|
||||
Removing always clobbered register reg byte x as potential for zp[1]:6 [ 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] 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 [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 [8] stackpush(byte) ← (byte) main::v#0 [ main::a#2 ] ( main:2 [ main::a#2 ] ) always clobbers reg byte a
|
||||
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]:7 [ plus::a#0 ]
|
||||
Removing always clobbered register reg byte x as potential for zp[1]:7 [ plus::a#0 ]
|
||||
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 [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 [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
|
||||
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 [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 [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 [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 [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 [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] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 [ ] ( main:2::plus:9 [ main::a#2 ] ) always clobbers reg byte x
|
||||
Potential registers zp[1]:2 [ main::a#2 main::a#1 ] : zp[1]:2 , reg byte y ,
|
||||
Potential registers zp[1]:3 [ main::v#0 ] : zp[1]:3 , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:4 [ main::w#0 ] : zp[1]:4 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:5 [ main::$2 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:6 [ plus::a#0 ] : zp[1]:6 , 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]:8 [ plus::return#0 ] : zp[1]:8 , reg byte a , reg byte x , reg byte y ,
|
||||
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 [ i main::a#2 main::$2 ] ( main:2 [ i main::a#2 main::$2 ] ) always clobbers reg byte a
|
||||
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 [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 [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 [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
|
||||
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 [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]:2 [ main::a#2 main::a#1 ] : zp[1]:2 ,
|
||||
Potential registers zp[1]:3 [ i ] : zp[1]:3 ,
|
||||
Potential registers zp[1]:4 [ main::v#0 ] : zp[1]:4 , 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]: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
|
||||
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 [plus] 4: zp[1]:7 [ plus::b#0 ] 4: zp[1]:8 [ plus::return#0 ] 2: zp[1]:6 [ plus::a#0 ]
|
||||
Uplift Scope []
|
||||
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]:9 [ plus::return#0 ] 2: zp[1]:8 [ plus::b#0 ] 1.33: zp[1]:7 [ plus::a#0 ]
|
||||
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 [plus] best 649 combination reg byte a [ plus::b#0 ] reg byte a [ plus::return#0 ] zp[1]:6 [ plus::a#0 ]
|
||||
Uplifting [] best 649 combination
|
||||
Attempting to uplift remaining variables inzp[1]:6 [ plus::a#0 ]
|
||||
Uplifting [plus] best 649 combination zp[1]:6 [ plus::a#0 ]
|
||||
Allocated (was zp[1]:6) zp[1]:2 [ plus::a#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 749 combination reg byte a [ plus::return#0 ] reg byte a [ plus::b#0 ] zp[1]:7 [ plus::a#0 ]
|
||||
Uplifting [] best 749 combination zp[1]:3 [ i ]
|
||||
Attempting to uplift remaining variables inzp[1]:2 [ main::a#2 main::a#1 ]
|
||||
Uplifting [main] best 749 combination zp[1]:2 [ main::a#2 main::a#1 ]
|
||||
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
|
||||
// File Comments
|
||||
@ -436,8 +424,12 @@ ASSEMBLER BEFORE OPTIMIZATION
|
||||
// Global Constants & labels
|
||||
.label SCREEN = $400
|
||||
.const STACK_BASE = $103
|
||||
.label i = 3
|
||||
// @begin
|
||||
__bbegin:
|
||||
// [0] (byte) i ← (byte) 0 -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z i
|
||||
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
__b1_from___bbegin:
|
||||
jmp __b1
|
||||
@ -454,10 +446,12 @@ __bend_from___b1:
|
||||
__bend:
|
||||
// main
|
||||
main: {
|
||||
.label a = 2
|
||||
// [5] phi from main to main::@1 [phi:main->main::@1]
|
||||
__b1_from_main:
|
||||
// [5] phi (byte) main::a#2 = (byte) 0 [phi:main->main::@1#0] -- vbuyy=vbuc1
|
||||
ldy #0
|
||||
// [5] phi (byte) main::a#2 = (byte) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z a
|
||||
jmp __b1
|
||||
// [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
|
||||
__b1_from___b1:
|
||||
@ -465,9 +459,8 @@ main: {
|
||||
jmp __b1
|
||||
// main::@1
|
||||
__b1:
|
||||
// [6] (byte) main::v#0 ← (byte) main::a#2 + (byte) 1 -- vbuxx=vbuyy_plus_1
|
||||
tya
|
||||
tax
|
||||
// [6] (byte) main::v#0 ← (byte) main::a#2 + (byte) 1 -- vbuxx=vbuz1_plus_1
|
||||
ldx.z a
|
||||
inx
|
||||
// [7] stackpush(byte) ← (byte) '0' -- _stackpushbyte_=vbuc1
|
||||
lda #'0'
|
||||
@ -481,16 +474,17 @@ main: {
|
||||
pla
|
||||
// [11] (byte) main::w#0 ← stackpull(byte) -- vbuaa=_stackpullbyte_
|
||||
pla
|
||||
// [12] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 -- vbuaa=vbuaa_plus_vbuyy
|
||||
sty.z $ff
|
||||
// [12] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 -- vbuaa=vbuaa_plus_vbuz1
|
||||
clc
|
||||
adc.z $ff
|
||||
// [13] *((const byte*) SCREEN) ← (byte~) main::$2 -- _deref_pbuc1=vbuaa
|
||||
sta SCREEN
|
||||
// [14] (byte) main::a#1 ← ++ (byte) main::a#2 -- vbuyy=_inc_vbuyy
|
||||
iny
|
||||
// [15] if((byte) main::a#1!=(byte) 2) goto main::@1 -- vbuyy_neq_vbuc1_then_la1
|
||||
cpy #2
|
||||
adc.z a
|
||||
// [13] *((const byte*) SCREEN + (byte) i) ← (byte~) main::$2 -- pbuc1_derefidx_vbuz1=vbuaa
|
||||
ldy.z i
|
||||
sta SCREEN,y
|
||||
// [14] (byte) main::a#1 ← ++ (byte) main::a#2 -- vbuz1=_inc_vbuz1
|
||||
inc.z a
|
||||
// [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
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
@ -499,12 +493,12 @@ main: {
|
||||
rts
|
||||
}
|
||||
// plus
|
||||
// plus(byte zp(2) a, byte register(A) b)
|
||||
// plus(byte zp(4) a, byte register(A) b)
|
||||
plus: {
|
||||
.const OFFSET_STACK_A = 1
|
||||
.const OFFSET_STACK_B = 0
|
||||
.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
|
||||
tsx
|
||||
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
|
||||
tsx
|
||||
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
|
||||
adc.z a
|
||||
jmp __breturn
|
||||
// plus::@return
|
||||
__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
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN,x
|
||||
// [21] return
|
||||
// [22] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
@ -535,23 +531,20 @@ Removing instruction jmp __breturn
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Replacing label __b1_from___b1 with __b1
|
||||
Removing instruction __b1_from___bbegin:
|
||||
Removing instruction __b1:
|
||||
Removing instruction main_from___b1:
|
||||
Removing instruction __bend_from___b1:
|
||||
Removing instruction __b1_from___b1:
|
||||
Succesful ASM optimization Pass5RedundantLabelElimination
|
||||
Removing instruction __b1:
|
||||
Removing instruction __bend:
|
||||
Removing instruction __b1_from_main:
|
||||
Removing instruction __breturn:
|
||||
Removing instruction __breturn:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
Updating BasicUpstart to call main directly
|
||||
Removing instruction jsr main
|
||||
Succesful ASM optimization Pass5SkipBegin
|
||||
Adding RTS to root block
|
||||
Succesful ASM optimization Pass5AddMainRts
|
||||
Removing instruction jmp __b1
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Removing instruction __bbegin:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
|
||||
FINAL SYMBOL TABLE
|
||||
(label) @1
|
||||
@ -559,14 +552,14 @@ FINAL SYMBOL TABLE
|
||||
(label) @end
|
||||
(const byte*) SCREEN = (byte*) 1024
|
||||
(const word) STACK_BASE = (word) $103
|
||||
(byte) i
|
||||
(byte) i loadstore zp[1]:3 0.85
|
||||
(void()) main()
|
||||
(byte~) main::$2 reg byte a 22.0
|
||||
(label) main::@1
|
||||
(label) main::@return
|
||||
(byte) main::a
|
||||
(byte) main::a#1 reg byte y 16.5
|
||||
(byte) main::a#2 reg byte y 4.888888888888889
|
||||
(byte) main::a#1 a zp[1]:2 16.5
|
||||
(byte) main::a#2 a zp[1]:2 4.888888888888889
|
||||
(byte) main::v
|
||||
(byte) main::v#0 reg byte x 11.0
|
||||
(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_RETURN = (byte) 1
|
||||
(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#0 reg byte a 4.0
|
||||
(byte) plus::b#0 reg byte a 2.0
|
||||
(byte) plus::return
|
||||
(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 a [ main::w#0 ]
|
||||
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::return#0 ]
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 544
|
||||
Score: 656
|
||||
|
||||
// File Comments
|
||||
// Test a procedure with calling convention stack
|
||||
// A slightly more complex call
|
||||
// Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
:BasicUpstart(__bbegin)
|
||||
.pc = $80d "Program"
|
||||
// Global Constants & labels
|
||||
.label SCREEN = $400
|
||||
.const STACK_BASE = $103
|
||||
.label i = 3
|
||||
// @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
|
||||
// [2] call main
|
||||
// [4] phi from @1 to main [phi:@1->main]
|
||||
jsr main
|
||||
rts
|
||||
// [3] phi from @1 to @end [phi:@1->@end]
|
||||
// @end
|
||||
// main
|
||||
main: {
|
||||
.label a = 2
|
||||
// [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
|
||||
ldy #0
|
||||
// [5] phi (byte) main::a#2 = (byte) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z a
|
||||
// [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
|
||||
// main::@1
|
||||
__b1:
|
||||
// v = a+1
|
||||
// [6] (byte) main::v#0 ← (byte) main::a#2 + (byte) 1 -- vbuxx=vbuyy_plus_1
|
||||
tya
|
||||
tax
|
||||
// [6] (byte) main::v#0 ← (byte) main::a#2 + (byte) 1 -- vbuxx=vbuz1_plus_1
|
||||
ldx.z a
|
||||
inx
|
||||
// plus('0', v)
|
||||
// [7] stackpush(byte) ← (byte) '0' -- _stackpushbyte_=vbuc1
|
||||
@ -641,18 +644,19 @@ main: {
|
||||
// [11] (byte) main::w#0 ← stackpull(byte) -- vbuaa=_stackpullbyte_
|
||||
pla
|
||||
// w+a
|
||||
// [12] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 -- vbuaa=vbuaa_plus_vbuyy
|
||||
sty.z $ff
|
||||
// [12] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 -- vbuaa=vbuaa_plus_vbuz1
|
||||
clc
|
||||
adc.z $ff
|
||||
adc.z a
|
||||
// SCREEN[i] = w+a
|
||||
// [13] *((const byte*) SCREEN) ← (byte~) main::$2 -- _deref_pbuc1=vbuaa
|
||||
sta SCREEN
|
||||
// [13] *((const byte*) SCREEN + (byte) i) ← (byte~) main::$2 -- pbuc1_derefidx_vbuz1=vbuaa
|
||||
ldy.z i
|
||||
sta SCREEN,y
|
||||
// for(char a:0..1)
|
||||
// [14] (byte) main::a#1 ← ++ (byte) main::a#2 -- vbuyy=_inc_vbuyy
|
||||
iny
|
||||
// [15] if((byte) main::a#1!=(byte) 2) goto main::@1 -- vbuyy_neq_vbuc1_then_la1
|
||||
cpy #2
|
||||
// [14] (byte) main::a#1 ← ++ (byte) main::a#2 -- vbuz1=_inc_vbuz1
|
||||
inc.z a
|
||||
// [15] if((byte) main::a#1!=(byte) 2) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
|
||||
lda #2
|
||||
cmp.z a
|
||||
bne __b1
|
||||
// main::@return
|
||||
// }
|
||||
@ -660,12 +664,12 @@ main: {
|
||||
rts
|
||||
}
|
||||
// plus
|
||||
// plus(byte zp(2) a, byte register(A) b)
|
||||
// plus(byte zp(4) a, byte register(A) b)
|
||||
plus: {
|
||||
.const OFFSET_STACK_A = 1
|
||||
.const OFFSET_STACK_B = 0
|
||||
.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
|
||||
tsx
|
||||
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
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_B,x
|
||||
// i++;
|
||||
// [19] (byte) i ← ++ (byte) i -- vbuz1=_inc_vbuz1
|
||||
inc.z i
|
||||
// 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
|
||||
adc.z a
|
||||
// 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
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN,x
|
||||
// [21] return
|
||||
// [22] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
@ -3,14 +3,14 @@
|
||||
(label) @end
|
||||
(const byte*) SCREEN = (byte*) 1024
|
||||
(const word) STACK_BASE = (word) $103
|
||||
(byte) i
|
||||
(byte) i loadstore zp[1]:3 0.85
|
||||
(void()) main()
|
||||
(byte~) main::$2 reg byte a 22.0
|
||||
(label) main::@1
|
||||
(label) main::@return
|
||||
(byte) main::a
|
||||
(byte) main::a#1 reg byte y 16.5
|
||||
(byte) main::a#2 reg byte y 4.888888888888889
|
||||
(byte) main::a#1 a zp[1]:2 16.5
|
||||
(byte) main::a#2 a zp[1]:2 4.888888888888889
|
||||
(byte) main::v
|
||||
(byte) main::v#0 reg byte x 11.0
|
||||
(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_RETURN = (byte) 1
|
||||
(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#0 reg byte a 4.0
|
||||
(byte) plus::b#0 reg byte a 2.0
|
||||
(byte) plus::return
|
||||
(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 a [ main::w#0 ]
|
||||
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::return#0 ]
|
||||
|
@ -1,15 +1,23 @@
|
||||
// Test a procedure with calling convention stack
|
||||
// Return value larger than parameter
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
:BasicUpstart(__bbegin)
|
||||
.pc = $80d "Program"
|
||||
.label SCREEN = $400
|
||||
.const SIZEOF_SIGNED_WORD = 2
|
||||
.const STACK_BASE = $103
|
||||
.label current = 2
|
||||
__bbegin:
|
||||
// current = 48
|
||||
lda #<$30
|
||||
sta.z current
|
||||
lda #>$30
|
||||
sta.z current+1
|
||||
jsr main
|
||||
rts
|
||||
main: {
|
||||
.label __0 = 2
|
||||
.label __1 = 4
|
||||
.label __0 = 4
|
||||
.label __1 = 2
|
||||
// next()
|
||||
pha
|
||||
pha
|
||||
@ -41,8 +49,16 @@ main: {
|
||||
}
|
||||
next: {
|
||||
.const OFFSET_STACK_RETURN = 0
|
||||
.label return = 2
|
||||
.label return = 4
|
||||
// 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
|
||||
lda.z return
|
||||
|
@ -2,33 +2,36 @@
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call main
|
||||
[1] (signed word) current ← (signed word) $30
|
||||
to:@2
|
||||
@2: scope:[] from @1
|
||||
[2] phi()
|
||||
[3] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi()
|
||||
@end: scope:[] from @2
|
||||
[4] phi()
|
||||
|
||||
(void()) main()
|
||||
main: scope:[main] from @1
|
||||
main: scope:[main] from @2
|
||||
sideeffect stackpushbytes((number) 2)
|
||||
[5] callexecute next
|
||||
[6] (signed word~) main::$0 ← stackpull(signed word)
|
||||
[7] *((const signed word*) SCREEN) ← (signed word~) main::$0
|
||||
[6] callexecute next
|
||||
[7] (signed word~) main::$0 ← stackpull(signed word)
|
||||
[8] *((const signed word*) SCREEN) ← (signed word~) main::$0
|
||||
sideeffect stackpushbytes((number) 2)
|
||||
[9] callexecute next
|
||||
[10] (signed word~) main::$1 ← stackpull(signed word)
|
||||
[11] *((const signed word*) SCREEN+(byte) 1*(const byte) SIZEOF_SIGNED_WORD) ← (signed word~) main::$1
|
||||
[10] callexecute next
|
||||
[11] (signed word~) main::$1 ← stackpull(signed word)
|
||||
[12] *((const signed word*) SCREEN+(byte) 1*(const byte) SIZEOF_SIGNED_WORD) ← (signed word~) main::$1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[12] return
|
||||
[13] return
|
||||
to:@return
|
||||
|
||||
__stackcall (signed word()) next()
|
||||
next: scope:[next] from
|
||||
[13] (signed word) current#5 ← phi( )
|
||||
[14] (signed word) next::return#0 ← (signed word) current#5
|
||||
[14] (signed word) next::return#0 ← (signed word) current
|
||||
[15] (signed word) current ← ++ (signed word) current
|
||||
to:next::@return
|
||||
next::@return: scope:[next] from next
|
||||
[15] stackidx(signed word,(const byte) next::OFFSET_STACK_RETURN) ← (signed word) next::return#0
|
||||
[16] return
|
||||
[16] stackidx(signed word,(const byte) next::OFFSET_STACK_RETURN) ← (signed word) next::return#0
|
||||
[17] return
|
||||
to:@return
|
||||
|
@ -1,6 +1,7 @@
|
||||
Fixing pointer array-indexing *((const signed word*) SCREEN + (number) 0)
|
||||
Fixing pointer array-indexing *((const signed word*) SCREEN + (number) 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::$1 ← call next
|
||||
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()
|
||||
main: scope:[main] from @2
|
||||
(signed word) current#7 ← phi( @2/(signed word) current#8 )
|
||||
sideeffect stackpushbytes((number) 2)
|
||||
callexecute next
|
||||
(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
|
||||
to:main::@return
|
||||
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
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
(signed word) current#1 ← (signed word) $30
|
||||
(signed word) current ← (signed word) $30
|
||||
to:@2
|
||||
|
||||
__stackcall (signed word()) next()
|
||||
next: scope:[next] from
|
||||
(signed word) current#5 ← phi( )
|
||||
(signed word) next::return#0 ← (signed word) current#5
|
||||
(signed word) current#2 ← ++ (signed word) current#5
|
||||
(signed word) next::return#0 ← (signed word) current
|
||||
(signed word) current ← ++ (signed word) current
|
||||
to:next::@return
|
||||
next::@return: scope:[next] from next
|
||||
(signed word) next::return#1 ← phi( next/(signed word) next::return#0 )
|
||||
@ -46,12 +43,9 @@ next::@return: scope:[next] from next
|
||||
return
|
||||
to:@return
|
||||
@2: scope:[] from @1
|
||||
(signed word) current#8 ← phi( @1/(signed word) current#1 )
|
||||
call main
|
||||
to:@3
|
||||
@3: scope:[] from @2
|
||||
(signed word) current#6 ← phi( @2/(signed word) current#0 )
|
||||
(signed word) current#3 ← (signed word) current#6
|
||||
to:@end
|
||||
@end: scope:[] from @3
|
||||
|
||||
@ -64,16 +58,7 @@ SYMBOL TABLE SSA
|
||||
(const signed word*) SCREEN = (signed word*)(number) $400
|
||||
(const byte) SIZEOF_SIGNED_WORD = (byte) 2
|
||||
(const word) STACK_BASE = (word) $103
|
||||
(signed word) current
|
||||
(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
|
||||
(signed word) current loadstore
|
||||
(void()) main()
|
||||
(signed word~) main::$0
|
||||
(signed word~) main::$1
|
||||
@ -101,35 +86,25 @@ Finalized unsigned number type (byte) 1
|
||||
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::$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) current#1 = (signed word) current#8
|
||||
Alias (signed word) current#3 = (signed word) current#6
|
||||
Successful SSA optimization Pass2AliasElimination
|
||||
Identical Phi Values (signed word) current#0 (signed word) current#1
|
||||
Identical Phi Values (signed word) current#3 (signed word) current#0
|
||||
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
|
||||
Constant right-side identified [3] (byte~) main::$2 ← (byte) 0 * (const byte) SIZEOF_SIGNED_WORD
|
||||
Constant right-side identified [8] (byte~) main::$3 ← (byte) 1 * (const byte) SIZEOF_SIGNED_WORD
|
||||
Successful SSA optimization Pass2ConstantRValueConsolidation
|
||||
Constant (const byte) main::$2 = 0*SIZEOF_SIGNED_WORD
|
||||
Constant (const byte) main::$3 = 1*SIZEOF_SIGNED_WORD
|
||||
Constant (const signed word) current#1 = $30
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Simplifying constant evaluating to zero (byte) 0*(const byte) SIZEOF_SIGNED_WORD in
|
||||
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
|
||||
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 signed word) current#1
|
||||
Successful SSA optimization PassNEliminateUnusedVars
|
||||
Constant inlined main::$3 = (byte) 1*(const byte) SIZEOF_SIGNED_WORD
|
||||
Successful SSA optimization Pass2ConstantInlining
|
||||
Consolidated array index constant in *(SCREEN+1*SIZEOF_SIGNED_WORD)
|
||||
Successful SSA optimization Pass2ConstantAdditionElimination
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @1
|
||||
Adding NOP phi() at start of @2
|
||||
Adding NOP phi() at start of @3
|
||||
Adding NOP phi() at start of @end
|
||||
@ -137,13 +112,11 @@ CALL GRAPH
|
||||
Calls in [] to main:3
|
||||
Calls in [main] to next:7 next:11
|
||||
|
||||
Created 1 initial phi equivalence classes
|
||||
Coalesced down to 1 phi equivalence classes
|
||||
Culled Empty Block (label) @1
|
||||
Created 0 initial phi equivalence classes
|
||||
Coalesced down to 0 phi equivalence classes
|
||||
Culled Empty Block (label) @3
|
||||
Renumbering block @2 to @1
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @1
|
||||
Adding NOP phi() at start of @2
|
||||
Adding NOP phi() at start of @end
|
||||
|
||||
FINAL CONTROL FLOW GRAPH
|
||||
@ -151,59 +124,61 @@ FINAL CONTROL FLOW GRAPH
|
||||
[0] phi()
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi()
|
||||
[2] call main
|
||||
[1] (signed word) current ← (signed word) $30
|
||||
to:@2
|
||||
@2: scope:[] from @1
|
||||
[2] phi()
|
||||
[3] call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi()
|
||||
@end: scope:[] from @2
|
||||
[4] phi()
|
||||
|
||||
(void()) main()
|
||||
main: scope:[main] from @1
|
||||
main: scope:[main] from @2
|
||||
sideeffect stackpushbytes((number) 2)
|
||||
[5] callexecute next
|
||||
[6] (signed word~) main::$0 ← stackpull(signed word)
|
||||
[7] *((const signed word*) SCREEN) ← (signed word~) main::$0
|
||||
[6] callexecute next
|
||||
[7] (signed word~) main::$0 ← stackpull(signed word)
|
||||
[8] *((const signed word*) SCREEN) ← (signed word~) main::$0
|
||||
sideeffect stackpushbytes((number) 2)
|
||||
[9] callexecute next
|
||||
[10] (signed word~) main::$1 ← stackpull(signed word)
|
||||
[11] *((const signed word*) SCREEN+(byte) 1*(const byte) SIZEOF_SIGNED_WORD) ← (signed word~) main::$1
|
||||
[10] callexecute next
|
||||
[11] (signed word~) main::$1 ← stackpull(signed word)
|
||||
[12] *((const signed word*) SCREEN+(byte) 1*(const byte) SIZEOF_SIGNED_WORD) ← (signed word~) main::$1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[12] return
|
||||
[13] return
|
||||
to:@return
|
||||
|
||||
__stackcall (signed word()) next()
|
||||
next: scope:[next] from
|
||||
[13] (signed word) current#5 ← phi( )
|
||||
[14] (signed word) next::return#0 ← (signed word) current#5
|
||||
[14] (signed word) next::return#0 ← (signed word) current
|
||||
[15] (signed word) current ← ++ (signed word) current
|
||||
to:next::@return
|
||||
next::@return: scope:[next] from next
|
||||
[15] stackidx(signed word,(const byte) next::OFFSET_STACK_RETURN) ← (signed word) next::return#0
|
||||
[16] return
|
||||
[16] stackidx(signed word,(const byte) next::OFFSET_STACK_RETURN) ← (signed word) next::return#0
|
||||
[17] return
|
||||
to:@return
|
||||
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
(signed word) current
|
||||
(signed word) current#5 2.0
|
||||
(signed word) current loadstore 0.7272727272727273
|
||||
(void()) main()
|
||||
(signed word~) main::$0 4.0
|
||||
(signed word~) main::$1 4.0
|
||||
__stackcall (signed word()) next()
|
||||
(signed word) next::return
|
||||
(signed word) next::return#0 4.0
|
||||
(signed word) next::return#0 2.0
|
||||
|
||||
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::$1 to live range equivalence class [ main::$1 ]
|
||||
Added variable next::return#0 to live range equivalence class [ next::return#0 ]
|
||||
Complete equivalence classes
|
||||
[ current#5 ]
|
||||
[ current ]
|
||||
[ main::$0 ]
|
||||
[ main::$1 ]
|
||||
[ next::return#0 ]
|
||||
Allocated zp[2]:2 [ current#5 ]
|
||||
Allocated zp[2]:2 [ current ]
|
||||
Allocated zp[2]:4 [ main::$0 ]
|
||||
Allocated zp[2]:6 [ main::$1 ]
|
||||
Allocated zp[2]:8 [ next::return#0 ]
|
||||
@ -224,15 +199,23 @@ Target platform is c64basic / MOS6502X
|
||||
.label current = 2
|
||||
// @begin
|
||||
__bbegin:
|
||||
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
__b1_from___bbegin:
|
||||
jmp __b1
|
||||
// @1
|
||||
__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
|
||||
// [3] phi from @1 to @end [phi:@1->@end]
|
||||
__bend_from___b1:
|
||||
// [4] phi from @2 to @end [phi:@2->@end]
|
||||
__bend_from___b2:
|
||||
jmp __bend
|
||||
// @end
|
||||
__bend:
|
||||
@ -243,14 +226,14 @@ main: {
|
||||
// sideeffect stackpushbytes((number) 2) -- _stackpushbyte_2
|
||||
pha
|
||||
pha
|
||||
// [5] callexecute next -- jsr
|
||||
// [6] callexecute next -- jsr
|
||||
jsr next
|
||||
// [6] (signed word~) main::$0 ← stackpull(signed word) -- vwsz1=_stackpullsword_
|
||||
// [7] (signed word~) main::$0 ← stackpull(signed word) -- vwsz1=_stackpullsword_
|
||||
pla
|
||||
sta.z __0
|
||||
pla
|
||||
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
|
||||
sta SCREEN
|
||||
lda.z __0+1
|
||||
@ -258,14 +241,14 @@ main: {
|
||||
// sideeffect stackpushbytes((number) 2) -- _stackpushbyte_2
|
||||
pha
|
||||
pha
|
||||
// [9] callexecute next -- jsr
|
||||
// [10] callexecute next -- jsr
|
||||
jsr next
|
||||
// [10] (signed word~) main::$1 ← stackpull(signed word) -- vwsz1=_stackpullsword_
|
||||
// [11] (signed word~) main::$1 ← stackpull(signed word) -- vwsz1=_stackpullsword_
|
||||
pla
|
||||
sta.z __1
|
||||
pla
|
||||
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
|
||||
sta SCREEN+1*SIZEOF_SIGNED_WORD
|
||||
lda.z __1+1
|
||||
@ -273,56 +256,62 @@ main: {
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [12] return
|
||||
// [13] return
|
||||
rts
|
||||
}
|
||||
// next
|
||||
next: {
|
||||
.const OFFSET_STACK_RETURN = 0
|
||||
.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
|
||||
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
|
||||
// next::@return
|
||||
__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
|
||||
lda.z return
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN,x
|
||||
lda.z return+1
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN+1,x
|
||||
// [16] return
|
||||
// [17] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
||||
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 [7] *((const signed word*) SCREEN) ← (signed word~) main::$0 [ ] ( main:2 [ ] ) 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 [11] *((const signed word*) SCREEN+(byte) 1*(const byte) SIZEOF_SIGNED_WORD) ← (signed word~) main::$1 [ ] ( main:2 [ ] ) 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 [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
|
||||
Potential registers zp[2]:2 [ current#5 ] : zp[2]:2 ,
|
||||
Statement [1] (signed word) current ← (signed word) $30 [ current ] ( [ current ] ) 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 [8] *((const signed word*) SCREEN) ← (signed word~) main::$0 [ current ] ( main:3 [ current ] ) 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 [12] *((const signed word*) SCREEN+(byte) 1*(const byte) SIZEOF_SIGNED_WORD) ← (signed word~) main::$1 [ ] ( main:3 [ ] ) always clobbers reg byte a
|
||||
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
|
||||
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]:6 [ main::$1 ] : zp[2]:6 ,
|
||||
Potential registers zp[2]:8 [ next::return#0 ] : zp[2]:8 ,
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
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 [] 2: zp[2]:2 [ current#5 ]
|
||||
Uplift Scope [next] 2: zp[2]:8 [ next::return#0 ]
|
||||
Uplift Scope [] 0.73: zp[2]:2 [ current ]
|
||||
|
||||
Uplifting [main] best 140 combination zp[2]:4 [ main::$0 ] zp[2]:6 [ main::$1 ]
|
||||
Uplifting [next] best 140 combination zp[2]:8 [ next::return#0 ]
|
||||
Uplifting [] best 140 combination zp[2]:2 [ current#5 ]
|
||||
Coalescing zero page register [ zp[2]:2 [ current#5 ] ] with [ zp[2]:8 [ next::return#0 ] ] - score: 1
|
||||
Coalescing zero page register [ zp[2]:4 [ main::$0 ] ] with [ zp[2]:2 [ current#5 next::return#0 ] ]
|
||||
Allocated (was zp[2]:4) zp[2]:2 [ main::$0 current#5 next::return#0 ]
|
||||
Allocated (was zp[2]:6) zp[2]:4 [ main::$1 ]
|
||||
Uplifting [main] best 192 combination zp[2]:4 [ main::$0 ] zp[2]:6 [ main::$1 ]
|
||||
Uplifting [next] best 192 combination zp[2]:8 [ next::return#0 ]
|
||||
Uplifting [] best 192 combination zp[2]:2 [ current ]
|
||||
Coalescing zero page register [ zp[2]:6 [ main::$1 ] ] with [ zp[2]:2 [ current ] ]
|
||||
Coalescing zero page register [ zp[2]:8 [ next::return#0 ] ] with [ zp[2]:4 [ main::$0 ] ]
|
||||
Allocated (was zp[2]:6) zp[2]:2 [ main::$1 current ]
|
||||
Allocated (was zp[2]:8) zp[2]:4 [ next::return#0 main::$0 ]
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
// File Comments
|
||||
@ -339,33 +328,41 @@ ASSEMBLER BEFORE OPTIMIZATION
|
||||
.label current = 2
|
||||
// @begin
|
||||
__bbegin:
|
||||
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
__b1_from___bbegin:
|
||||
jmp __b1
|
||||
// @1
|
||||
__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
|
||||
// [3] phi from @1 to @end [phi:@1->@end]
|
||||
__bend_from___b1:
|
||||
// [4] phi from @2 to @end [phi:@2->@end]
|
||||
__bend_from___b2:
|
||||
jmp __bend
|
||||
// @end
|
||||
__bend:
|
||||
// main
|
||||
main: {
|
||||
.label __0 = 2
|
||||
.label __1 = 4
|
||||
.label __0 = 4
|
||||
.label __1 = 2
|
||||
// sideeffect stackpushbytes((number) 2) -- _stackpushbyte_2
|
||||
pha
|
||||
pha
|
||||
// [5] callexecute next -- jsr
|
||||
// [6] callexecute next -- jsr
|
||||
jsr next
|
||||
// [6] (signed word~) main::$0 ← stackpull(signed word) -- vwsz1=_stackpullsword_
|
||||
// [7] (signed word~) main::$0 ← stackpull(signed word) -- vwsz1=_stackpullsword_
|
||||
pla
|
||||
sta.z __0
|
||||
pla
|
||||
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
|
||||
sta SCREEN
|
||||
lda.z __0+1
|
||||
@ -373,14 +370,14 @@ main: {
|
||||
// sideeffect stackpushbytes((number) 2) -- _stackpushbyte_2
|
||||
pha
|
||||
pha
|
||||
// [9] callexecute next -- jsr
|
||||
// [10] callexecute next -- jsr
|
||||
jsr next
|
||||
// [10] (signed word~) main::$1 ← stackpull(signed word) -- vwsz1=_stackpullsword_
|
||||
// [11] (signed word~) main::$1 ← stackpull(signed word) -- vwsz1=_stackpullsword_
|
||||
pla
|
||||
sta.z __1
|
||||
pla
|
||||
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
|
||||
sta SCREEN+1*SIZEOF_SIGNED_WORD
|
||||
lda.z __1+1
|
||||
@ -388,80 +385,88 @@ main: {
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [12] return
|
||||
// [13] return
|
||||
rts
|
||||
}
|
||||
// next
|
||||
next: {
|
||||
.const OFFSET_STACK_RETURN = 0
|
||||
.label return = 2
|
||||
// [14] (signed word) next::return#0 ← (signed word) current#5
|
||||
.label return = 4
|
||||
// [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
|
||||
// next::@return
|
||||
__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
|
||||
lda.z return
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN,x
|
||||
lda.z return+1
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN+1,x
|
||||
// [16] return
|
||||
// [17] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
||||
ASSEMBLER OPTIMIZATIONS
|
||||
Removing instruction jmp __b1
|
||||
Removing instruction jmp __b2
|
||||
Removing instruction jmp __bend
|
||||
Removing instruction jmp __breturn
|
||||
Removing instruction jmp __breturn
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Removing instruction __b1_from___bbegin:
|
||||
Removing instruction __b1:
|
||||
Removing instruction __bend_from___b1:
|
||||
Removing instruction __b2_from___b1:
|
||||
Removing instruction __bend_from___b2:
|
||||
Succesful ASM optimization Pass5RedundantLabelElimination
|
||||
Removing instruction __b2:
|
||||
Removing instruction __bend:
|
||||
Removing instruction __breturn:
|
||||
Removing instruction __breturn:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
Updating BasicUpstart to call main directly
|
||||
Removing instruction jsr main
|
||||
Succesful ASM optimization Pass5SkipBegin
|
||||
Removing instruction __bbegin:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
Adding RTS to root block
|
||||
Succesful ASM optimization Pass5AddMainRts
|
||||
|
||||
FINAL SYMBOL TABLE
|
||||
(label) @1
|
||||
(label) @2
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const signed word*) SCREEN = (signed word*) 1024
|
||||
(const byte) SIZEOF_SIGNED_WORD = (byte) 2
|
||||
(const word) STACK_BASE = (word) $103
|
||||
(signed word) current
|
||||
(signed word) current#5 current zp[2]:2 2.0
|
||||
(signed word) current loadstore zp[2]:2 0.7272727272727273
|
||||
(void()) main()
|
||||
(signed word~) main::$0 zp[2]:2 4.0
|
||||
(signed word~) main::$1 zp[2]:4 4.0
|
||||
(signed word~) main::$0 zp[2]:4 4.0
|
||||
(signed word~) main::$1 zp[2]:2 4.0
|
||||
(label) main::@return
|
||||
__stackcall (signed word()) next()
|
||||
(label) next::@return
|
||||
(const byte) next::OFFSET_STACK_RETURN = (byte) 0
|
||||
(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]:4 [ main::$1 ]
|
||||
zp[2]:2 [ main::$1 current ]
|
||||
zp[2]:4 [ next::return#0 main::$0 ]
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 110
|
||||
Score: 156
|
||||
|
||||
// File Comments
|
||||
// Test a procedure with calling convention stack
|
||||
// Return value larger than parameter
|
||||
// Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
:BasicUpstart(__bbegin)
|
||||
.pc = $80d "Program"
|
||||
// Global Constants & labels
|
||||
.label SCREEN = $400
|
||||
@ -469,28 +474,38 @@ Score: 110
|
||||
.const STACK_BASE = $103
|
||||
.label current = 2
|
||||
// @begin
|
||||
// [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
__bbegin:
|
||||
// @1
|
||||
// [2] call main
|
||||
// [3] phi from @1 to @end [phi:@1->@end]
|
||||
// current = 48
|
||||
// [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
|
||||
// main
|
||||
main: {
|
||||
.label __0 = 2
|
||||
.label __1 = 4
|
||||
.label __0 = 4
|
||||
.label __1 = 2
|
||||
// next()
|
||||
// sideeffect stackpushbytes((number) 2) -- _stackpushbyte_2
|
||||
pha
|
||||
pha
|
||||
// [5] callexecute next -- jsr
|
||||
// [6] callexecute next -- jsr
|
||||
jsr next
|
||||
// [6] (signed word~) main::$0 ← stackpull(signed word) -- vwsz1=_stackpullsword_
|
||||
// [7] (signed word~) main::$0 ← stackpull(signed word) -- vwsz1=_stackpullsword_
|
||||
pla
|
||||
sta.z __0
|
||||
pla
|
||||
sta.z __0+1
|
||||
// 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
|
||||
sta SCREEN
|
||||
lda.z __0+1
|
||||
@ -499,39 +514,48 @@ main: {
|
||||
// sideeffect stackpushbytes((number) 2) -- _stackpushbyte_2
|
||||
pha
|
||||
pha
|
||||
// [9] callexecute next -- jsr
|
||||
// [10] callexecute next -- jsr
|
||||
jsr next
|
||||
// [10] (signed word~) main::$1 ← stackpull(signed word) -- vwsz1=_stackpullsword_
|
||||
// [11] (signed word~) main::$1 ← stackpull(signed word) -- vwsz1=_stackpullsword_
|
||||
pla
|
||||
sta.z __1
|
||||
pla
|
||||
sta.z __1+1
|
||||
// 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
|
||||
sta SCREEN+1*SIZEOF_SIGNED_WORD
|
||||
lda.z __1+1
|
||||
sta SCREEN+1*SIZEOF_SIGNED_WORD+1
|
||||
// main::@return
|
||||
// }
|
||||
// [12] return
|
||||
// [13] return
|
||||
rts
|
||||
}
|
||||
// next
|
||||
next: {
|
||||
.const OFFSET_STACK_RETURN = 0
|
||||
.label return = 2
|
||||
.label return = 4
|
||||
// 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
|
||||
// }
|
||||
// [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
|
||||
lda.z return
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN,x
|
||||
lda.z return+1
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN+1,x
|
||||
// [16] return
|
||||
// [17] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
@ -1,20 +1,20 @@
|
||||
(label) @1
|
||||
(label) @2
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const signed word*) SCREEN = (signed word*) 1024
|
||||
(const byte) SIZEOF_SIGNED_WORD = (byte) 2
|
||||
(const word) STACK_BASE = (word) $103
|
||||
(signed word) current
|
||||
(signed word) current#5 current zp[2]:2 2.0
|
||||
(signed word) current loadstore zp[2]:2 0.7272727272727273
|
||||
(void()) main()
|
||||
(signed word~) main::$0 zp[2]:2 4.0
|
||||
(signed word~) main::$1 zp[2]:4 4.0
|
||||
(signed word~) main::$0 zp[2]:4 4.0
|
||||
(signed word~) main::$1 zp[2]:2 4.0
|
||||
(label) main::@return
|
||||
__stackcall (signed word()) next()
|
||||
(label) next::@return
|
||||
(const byte) next::OFFSET_STACK_RETURN = (byte) 0
|
||||
(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]:4 [ main::$1 ]
|
||||
zp[2]:2 [ main::$1 current ]
|
||||
zp[2]:4 [ next::return#0 main::$0 ]
|
||||
|
@ -5,39 +5,28 @@
|
||||
.pc = $80d "Program"
|
||||
.label SCREEN = $400
|
||||
printline: {
|
||||
.label i = 2
|
||||
// i=0
|
||||
lda #0
|
||||
sta.z i
|
||||
ldx #0
|
||||
__b1:
|
||||
// for(char i=0; i<40; i++)
|
||||
lda.z i
|
||||
cmp #$28
|
||||
cpx #$28
|
||||
bcc __b2
|
||||
// }
|
||||
rts
|
||||
__b2:
|
||||
// SCREEN[i] = '*'
|
||||
lda #'*'
|
||||
ldy.z i
|
||||
sta SCREEN,y
|
||||
sta SCREEN,x
|
||||
// for(char i=0; i<40; i++)
|
||||
inc.z i
|
||||
inx
|
||||
jmp __b1
|
||||
}
|
||||
main: {
|
||||
.label val = 3
|
||||
// val
|
||||
lda #0
|
||||
sta.z val
|
||||
// val = *SCREEN
|
||||
lda SCREEN
|
||||
sta.z val
|
||||
ldy SCREEN
|
||||
// printline()
|
||||
jsr printline
|
||||
// SCREEN[80] = val
|
||||
lda.z val
|
||||
sta SCREEN+$50
|
||||
sty SCREEN+$50
|
||||
// }
|
||||
rts
|
||||
}
|
||||
|
@ -10,25 +10,25 @@
|
||||
|
||||
__stackcall (void()) printline()
|
||||
printline: scope:[printline] from
|
||||
[4] (byte) printline::i ← (byte) 0
|
||||
[4] phi()
|
||||
to:printline::@1
|
||||
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
|
||||
printline::@return: scope:[printline] from printline::@1
|
||||
[6] return
|
||||
[7] return
|
||||
to:@return
|
||||
printline::@2: scope:[printline] from printline::@1
|
||||
[7] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*'
|
||||
[8] (byte) printline::i ← ++ (byte) printline::i
|
||||
[8] *((const byte*) SCREEN + (byte) printline::i#2) ← (byte) '*'
|
||||
[9] (byte) printline::i#1 ← ++ (byte) printline::i#2
|
||||
to:printline::@1
|
||||
|
||||
__stackcall (void()) main()
|
||||
main: scope:[main] from
|
||||
[9] (byte) main::val ← (byte) 0
|
||||
[10] (byte) main::val ← *((const byte*) SCREEN)
|
||||
[10] (byte) main::val#1 ← *((const byte*) SCREEN)
|
||||
[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
|
||||
main::@return: scope:[main] from main
|
||||
[13] return
|
||||
|
@ -12,10 +12,10 @@ CONTROL FLOW GRAPH SSA
|
||||
|
||||
__stackcall (void()) main()
|
||||
main: scope:[main] from
|
||||
(byte) main::val ← (byte) 0
|
||||
(byte) main::val ← *((const byte*) SCREEN)
|
||||
(byte) main::val#0 ← (byte) 0
|
||||
(byte) main::val#1 ← *((const byte*) SCREEN)
|
||||
callexecute printline
|
||||
*((const byte*) SCREEN + (number) $50) ← (byte) main::val
|
||||
*((const byte*) SCREEN + (number) $50) ← (byte) main::val#1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
return
|
||||
@ -23,15 +23,17 @@ main::@return: scope:[main] from main
|
||||
|
||||
__stackcall (void()) printline()
|
||||
printline: scope:[printline] from
|
||||
(byte) printline::i ← (byte) 0
|
||||
(byte) printline::i#0 ← (byte) 0
|
||||
to:printline::@1
|
||||
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
|
||||
to:printline::@return
|
||||
printline::@2: scope:[printline] from printline::@1
|
||||
*((const byte*) SCREEN + (byte) printline::i) ← (byte) '*'
|
||||
(byte) printline::i ← ++ (byte) printline::i
|
||||
(byte) printline::i#3 ← phi( printline::@1/(byte) printline::i#2 )
|
||||
*((const byte*) SCREEN + (byte) printline::i#3) ← (byte) '*'
|
||||
(byte) printline::i#1 ← ++ (byte) printline::i#3
|
||||
to:printline::@1
|
||||
printline::@return: scope:[printline] from printline::@1
|
||||
return
|
||||
@ -48,16 +50,22 @@ SYMBOL TABLE SSA
|
||||
(const byte*) SCREEN = (byte*)(number) $400
|
||||
__stackcall (void()) main()
|
||||
(label) main::@return
|
||||
(byte) main::val loadstore
|
||||
(byte) main::val
|
||||
(byte) main::val#0
|
||||
(byte) main::val#1
|
||||
__stackcall (void()) printline()
|
||||
(bool~) printline::$0
|
||||
(label) printline::@1
|
||||
(label) printline::@2
|
||||
(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) $28 in (bool~) printline::$0 ← (byte) printline::i < (number) $28
|
||||
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#2 < (number) $28
|
||||
Successful SSA optimization PassNAddNumberTypeConversions
|
||||
Simplifying constant pointer cast (byte*) 1024
|
||||
Simplifying constant integer cast $50
|
||||
@ -66,23 +74,36 @@ Successful SSA optimization PassNCastSimplification
|
||||
Finalized unsigned number type (byte) $50
|
||||
Finalized unsigned number type (byte) $28
|
||||
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
|
||||
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)
|
||||
Successful SSA optimization Pass2ConstantAdditionElimination
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @2
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of printline
|
||||
CALL GRAPH
|
||||
Calls in [] to main:2
|
||||
Calls in [main] to printline:11
|
||||
Calls in [main] to printline:12
|
||||
|
||||
Created 0 initial phi equivalence classes
|
||||
Coalesced down to 0 phi equivalence classes
|
||||
Created 1 initial phi equivalence classes
|
||||
Coalesced [10] printline::i#4 ← printline::i#1
|
||||
Coalesced down to 1 phi equivalence classes
|
||||
Renumbering block @2 to @1
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @1
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of printline
|
||||
|
||||
FINAL CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
@ -97,25 +118,25 @@ FINAL CONTROL FLOW GRAPH
|
||||
|
||||
__stackcall (void()) printline()
|
||||
printline: scope:[printline] from
|
||||
[4] (byte) printline::i ← (byte) 0
|
||||
[4] phi()
|
||||
to:printline::@1
|
||||
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
|
||||
printline::@return: scope:[printline] from printline::@1
|
||||
[6] return
|
||||
[7] return
|
||||
to:@return
|
||||
printline::@2: scope:[printline] from printline::@1
|
||||
[7] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*'
|
||||
[8] (byte) printline::i ← ++ (byte) printline::i
|
||||
[8] *((const byte*) SCREEN + (byte) printline::i#2) ← (byte) '*'
|
||||
[9] (byte) printline::i#1 ← ++ (byte) printline::i#2
|
||||
to:printline::@1
|
||||
|
||||
__stackcall (void()) main()
|
||||
main: scope:[main] from
|
||||
[9] (byte) main::val ← (byte) 0
|
||||
[10] (byte) main::val ← *((const byte*) SCREEN)
|
||||
[10] (byte) main::val#1 ← *((const byte*) SCREEN)
|
||||
[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
|
||||
main::@return: scope:[main] from main
|
||||
[13] return
|
||||
@ -124,18 +145,21 @@ main::@return: scope:[main] from main
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
__stackcall (void()) main()
|
||||
(byte) main::val loadstore 3.0
|
||||
(byte) main::val
|
||||
(byte) main::val#1 2.0
|
||||
__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
|
||||
Added variable printline::i to live range equivalence class [ printline::i ]
|
||||
Added variable main::val to live range equivalence class [ main::val ]
|
||||
[ printline::i#2 printline::i#1 ]
|
||||
Added variable main::val#1 to live range equivalence class [ main::val#1 ]
|
||||
Complete equivalence classes
|
||||
[ printline::i ]
|
||||
[ main::val ]
|
||||
Allocated zp[1]:2 [ printline::i ]
|
||||
Allocated zp[1]:3 [ main::val ]
|
||||
[ printline::i#2 printline::i#1 ]
|
||||
[ main::val#1 ]
|
||||
Allocated zp[1]:2 [ printline::i#2 printline::i#1 ]
|
||||
Allocated zp[1]:3 [ main::val#1 ]
|
||||
|
||||
INITIAL ASM
|
||||
Target platform is c64basic / MOS6502X
|
||||
@ -165,43 +189,45 @@ __bend:
|
||||
// printline
|
||||
printline: {
|
||||
.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
|
||||
sta.z i
|
||||
jmp __b1
|
||||
// printline::@1
|
||||
__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
|
||||
cmp #$28
|
||||
bcc __b2
|
||||
jmp __breturn
|
||||
// printline::@return
|
||||
__breturn:
|
||||
// [6] return
|
||||
// [7] return
|
||||
rts
|
||||
// printline::@2
|
||||
__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 #'*'
|
||||
ldy.z i
|
||||
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
|
||||
// [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
|
||||
}
|
||||
// main
|
||||
main: {
|
||||
.label val = 3
|
||||
// [9] (byte) main::val ← (byte) 0 -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z val
|
||||
// [10] (byte) main::val ← *((const byte*) SCREEN) -- vbuz1=_deref_pbuc1
|
||||
// [10] (byte) main::val#1 ← *((const byte*) SCREEN) -- vbuz1=_deref_pbuc1
|
||||
lda SCREEN
|
||||
sta.z val
|
||||
// [11] callexecute printline -- jsr
|
||||
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
|
||||
sta SCREEN+$50
|
||||
jmp __breturn
|
||||
@ -213,27 +239,21 @@ main: {
|
||||
// File Data
|
||||
|
||||
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 [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
|
||||
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
|
||||
Statement [9] (byte) main::val ← (byte) 0 [ ] ( main: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
|
||||
Statement [12] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
Potential registers zp[1]:2 [ printline::i ] : zp[1]:2 ,
|
||||
Potential registers zp[1]:3 [ main::val ] : zp[1]:3 ,
|
||||
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
|
||||
Removing always clobbered register reg byte a as potential for zp[1]:3 [ main::val#1 ]
|
||||
Removing always clobbered register reg byte a as potential for zp[1]:2 [ printline::i#2 printline::i#1 ]
|
||||
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
|
||||
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 [ main::val#1 ] : zp[1]:3 , reg byte x , reg byte y ,
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [printline] 11.5: zp[1]:2 [ printline::i ]
|
||||
Uplift Scope [main] 3: zp[1]:3 [ main::val ]
|
||||
Uplift Scope [printline] 36.67: zp[1]:2 [ printline::i#2 printline::i#1 ]
|
||||
Uplift Scope [main] 2: zp[1]:3 [ main::val#1 ]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [printline] best 345 combination zp[1]:2 [ printline::i ]
|
||||
Uplifting [main] best 345 combination zp[1]:3 [ main::val ]
|
||||
Uplifting [] best 345 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 ]
|
||||
Uplifting [printline] best 292 combination reg byte x [ printline::i#2 printline::i#1 ]
|
||||
Uplifting [main] best 286 combination reg byte y [ main::val#1 ]
|
||||
Uplifting [] best 286 combination
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
// File Comments
|
||||
@ -261,46 +281,41 @@ __bend_from___b1:
|
||||
__bend:
|
||||
// printline
|
||||
printline: {
|
||||
.label i = 2
|
||||
// [4] (byte) printline::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z i
|
||||
// [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] -- vbuxx=vbuc1
|
||||
ldx #0
|
||||
jmp __b1
|
||||
// printline::@1
|
||||
__b1:
|
||||
// [5] if((byte) printline::i<(byte) $28) goto printline::@2 -- vbuz1_lt_vbuc1_then_la1
|
||||
lda.z i
|
||||
cmp #$28
|
||||
// [6] if((byte) printline::i#2<(byte) $28) goto printline::@2 -- vbuxx_lt_vbuc1_then_la1
|
||||
cpx #$28
|
||||
bcc __b2
|
||||
jmp __breturn
|
||||
// printline::@return
|
||||
__breturn:
|
||||
// [6] return
|
||||
// [7] return
|
||||
rts
|
||||
// printline::@2
|
||||
__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 #'*'
|
||||
ldy.z i
|
||||
sta SCREEN,y
|
||||
// [8] (byte) printline::i ← ++ (byte) printline::i -- vbuz1=_inc_vbuz1
|
||||
inc.z i
|
||||
sta SCREEN,x
|
||||
// [9] (byte) printline::i#1 ← ++ (byte) printline::i#2 -- vbuxx=_inc_vbuxx
|
||||
inx
|
||||
// [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
|
||||
}
|
||||
// main
|
||||
main: {
|
||||
.label val = 3
|
||||
// [9] (byte) main::val ← (byte) 0 -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z val
|
||||
// [10] (byte) main::val ← *((const byte*) SCREEN) -- vbuz1=_deref_pbuc1
|
||||
lda SCREEN
|
||||
sta.z val
|
||||
// [10] (byte) main::val#1 ← *((const byte*) SCREEN) -- vbuyy=_deref_pbuc1
|
||||
ldy SCREEN
|
||||
// [11] callexecute printline -- jsr
|
||||
jsr printline
|
||||
// [12] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val -- _deref_pbuc1=vbuz1
|
||||
lda.z val
|
||||
sta SCREEN+$50
|
||||
// [12] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val#1 -- _deref_pbuc1=vbuyy
|
||||
sty SCREEN+$50
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
@ -321,7 +336,9 @@ Removing instruction __b1:
|
||||
Removing instruction __bend_from___b1:
|
||||
Succesful ASM optimization Pass5RedundantLabelElimination
|
||||
Removing instruction __bend:
|
||||
Removing instruction __b1_from_printline:
|
||||
Removing instruction __breturn:
|
||||
Removing instruction __b1_from___b2:
|
||||
Removing instruction __breturn:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
Updating BasicUpstart to call main directly
|
||||
@ -337,19 +354,22 @@ FINAL SYMBOL TABLE
|
||||
(const byte*) SCREEN = (byte*) 1024
|
||||
__stackcall (void()) main()
|
||||
(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()
|
||||
(label) printline::@1
|
||||
(label) printline::@2
|
||||
(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 ]
|
||||
zp[1]:3 [ main::val ]
|
||||
reg byte x [ printline::i#2 printline::i#1 ]
|
||||
reg byte y [ main::val#1 ]
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 297
|
||||
Score: 211
|
||||
|
||||
// File Comments
|
||||
// Test a procedure with calling convention stack
|
||||
@ -368,52 +388,43 @@ Score: 297
|
||||
// @end
|
||||
// printline
|
||||
printline: {
|
||||
.label i = 2
|
||||
// i=0
|
||||
// [4] (byte) printline::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z i
|
||||
// [5] phi from printline to printline::@1 [phi:printline->printline::@1]
|
||||
// [5] phi (byte) printline::i#2 = (byte) 0 [phi:printline->printline::@1#0] -- vbuxx=vbuc1
|
||||
ldx #0
|
||||
// printline::@1
|
||||
__b1:
|
||||
// for(char i=0; i<40; i++)
|
||||
// [5] if((byte) printline::i<(byte) $28) goto printline::@2 -- vbuz1_lt_vbuc1_then_la1
|
||||
lda.z i
|
||||
cmp #$28
|
||||
// [6] if((byte) printline::i#2<(byte) $28) goto printline::@2 -- vbuxx_lt_vbuc1_then_la1
|
||||
cpx #$28
|
||||
bcc __b2
|
||||
// printline::@return
|
||||
// }
|
||||
// [6] return
|
||||
// [7] return
|
||||
rts
|
||||
// printline::@2
|
||||
__b2:
|
||||
// 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 #'*'
|
||||
ldy.z i
|
||||
sta SCREEN,y
|
||||
sta SCREEN,x
|
||||
// for(char i=0; i<40; i++)
|
||||
// [8] (byte) printline::i ← ++ (byte) printline::i -- vbuz1=_inc_vbuz1
|
||||
inc.z i
|
||||
// [9] (byte) printline::i#1 ← ++ (byte) printline::i#2 -- vbuxx=_inc_vbuxx
|
||||
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
|
||||
}
|
||||
// main
|
||||
main: {
|
||||
.label val = 3
|
||||
// val
|
||||
// [9] (byte) main::val ← (byte) 0 -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z val
|
||||
// val = *SCREEN
|
||||
// [10] (byte) main::val ← *((const byte*) SCREEN) -- vbuz1=_deref_pbuc1
|
||||
lda SCREEN
|
||||
sta.z val
|
||||
// [10] (byte) main::val#1 ← *((const byte*) SCREEN) -- vbuyy=_deref_pbuc1
|
||||
ldy SCREEN
|
||||
// printline()
|
||||
// [11] callexecute printline -- jsr
|
||||
jsr printline
|
||||
// SCREEN[80] = val
|
||||
// [12] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val -- _deref_pbuc1=vbuz1
|
||||
lda.z val
|
||||
sta SCREEN+$50
|
||||
// [12] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val#1 -- _deref_pbuc1=vbuyy
|
||||
sty SCREEN+$50
|
||||
// main::@return
|
||||
// }
|
||||
// [13] return
|
||||
|
@ -4,12 +4,15 @@
|
||||
(const byte*) SCREEN = (byte*) 1024
|
||||
__stackcall (void()) main()
|
||||
(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()
|
||||
(label) printline::@1
|
||||
(label) printline::@2
|
||||
(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 ]
|
||||
zp[1]:3 [ main::val ]
|
||||
reg byte x [ printline::i#2 printline::i#1 ]
|
||||
reg byte y [ main::val#1 ]
|
||||
|
@ -12,24 +12,19 @@ __bbegin:
|
||||
jsr main
|
||||
rts
|
||||
printline: {
|
||||
.label i = 3
|
||||
// i=0
|
||||
lda #0
|
||||
sta.z i
|
||||
ldx #0
|
||||
__b1:
|
||||
// for(char i=0; i<40; i++)
|
||||
lda.z i
|
||||
cmp #$28
|
||||
cpx #$28
|
||||
bcc __b2
|
||||
// }
|
||||
rts
|
||||
__b2:
|
||||
// SCREEN[i] = '*'
|
||||
lda #'*'
|
||||
ldy.z i
|
||||
sta SCREEN,y
|
||||
sta SCREEN,x
|
||||
// for(char i=0; i<40; i++)
|
||||
inc.z i
|
||||
inx
|
||||
jmp __b1
|
||||
}
|
||||
main: {
|
||||
|
@ -10,25 +10,26 @@
|
||||
|
||||
__stackcall (void()) printline()
|
||||
printline: scope:[printline] from
|
||||
[4] (byte) printline::i ← (byte) 0
|
||||
[4] phi()
|
||||
to:printline::@1
|
||||
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
|
||||
printline::@return: scope:[printline] from printline::@1
|
||||
[6] return
|
||||
[7] return
|
||||
to:@return
|
||||
printline::@2: scope:[printline] from printline::@1
|
||||
[7] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*'
|
||||
[8] (byte) printline::i ← ++ (byte) printline::i
|
||||
[8] *((const byte*) SCREEN + (byte) printline::i#2) ← (byte) '*'
|
||||
[9] (byte) printline::i#1 ← ++ (byte) printline::i#2
|
||||
to:printline::@1
|
||||
|
||||
__stackcall (void()) main()
|
||||
main: scope:[main] from
|
||||
[9] (byte) val ← (byte) '-'
|
||||
[10] callexecute printline
|
||||
[11] *((const byte*) SCREEN+(byte) $50) ← (byte) val
|
||||
[10] (byte) val ← (byte) '-'
|
||||
[11] callexecute printline
|
||||
[12] *((const byte*) SCREEN+(byte) $50) ← (byte) val
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[12] return
|
||||
[13] return
|
||||
to:@return
|
||||
|
@ -3,6 +3,7 @@ Culled Empty Block (label) printline::@4
|
||||
Culled Empty Block (label) printline::@3
|
||||
Culled Empty Block (label) printline::@5
|
||||
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 main
|
||||
|
||||
@ -23,15 +24,17 @@ main::@return: scope:[main] from main
|
||||
|
||||
__stackcall (void()) printline()
|
||||
printline: scope:[printline] from
|
||||
(byte) printline::i ← (byte) 0
|
||||
(byte) printline::i#0 ← (byte) 0
|
||||
to:printline::@1
|
||||
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
|
||||
to:printline::@return
|
||||
printline::@2: scope:[printline] from printline::@1
|
||||
*((const byte*) SCREEN + (byte) printline::i) ← (byte) '*'
|
||||
(byte) printline::i ← ++ (byte) printline::i
|
||||
(byte) printline::i#3 ← phi( printline::@1/(byte) printline::i#2 )
|
||||
*((const byte*) SCREEN + (byte) printline::i#3) ← (byte) '*'
|
||||
(byte) printline::i#1 ← ++ (byte) printline::i#3
|
||||
to:printline::@1
|
||||
printline::@return: scope:[printline] from printline::@1
|
||||
return
|
||||
@ -53,11 +56,15 @@ __stackcall (void()) printline()
|
||||
(label) printline::@1
|
||||
(label) printline::@2
|
||||
(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
|
||||
|
||||
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
|
||||
Simplifying constant pointer cast (byte*) 1024
|
||||
Simplifying constant integer cast $50
|
||||
@ -66,21 +73,31 @@ Successful SSA optimization PassNCastSimplification
|
||||
Finalized unsigned number type (byte) $50
|
||||
Finalized unsigned number type (byte) $28
|
||||
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
|
||||
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)
|
||||
Successful SSA optimization Pass2ConstantAdditionElimination
|
||||
Adding NOP phi() at start of @2
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of printline
|
||||
CALL GRAPH
|
||||
Calls in [] to main:2
|
||||
Calls in [main] to printline:10
|
||||
Calls in [main] to printline:12
|
||||
|
||||
Created 0 initial phi equivalence classes
|
||||
Coalesced down to 0 phi equivalence classes
|
||||
Created 1 initial phi equivalence classes
|
||||
Coalesced [10] printline::i#4 ← printline::i#1
|
||||
Coalesced down to 1 phi equivalence classes
|
||||
Renumbering block @2 to @1
|
||||
Adding NOP phi() at start of @1
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of printline
|
||||
|
||||
FINAL CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
@ -95,44 +112,47 @@ FINAL CONTROL FLOW GRAPH
|
||||
|
||||
__stackcall (void()) printline()
|
||||
printline: scope:[printline] from
|
||||
[4] (byte) printline::i ← (byte) 0
|
||||
[4] phi()
|
||||
to:printline::@1
|
||||
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
|
||||
printline::@return: scope:[printline] from printline::@1
|
||||
[6] return
|
||||
[7] return
|
||||
to:@return
|
||||
printline::@2: scope:[printline] from printline::@1
|
||||
[7] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*'
|
||||
[8] (byte) printline::i ← ++ (byte) printline::i
|
||||
[8] *((const byte*) SCREEN + (byte) printline::i#2) ← (byte) '*'
|
||||
[9] (byte) printline::i#1 ← ++ (byte) printline::i#2
|
||||
to:printline::@1
|
||||
|
||||
__stackcall (void()) main()
|
||||
main: scope:[main] from
|
||||
[9] (byte) val ← (byte) '-'
|
||||
[10] callexecute printline
|
||||
[11] *((const byte*) SCREEN+(byte) $50) ← (byte) val
|
||||
[10] (byte) val ← (byte) '-'
|
||||
[11] callexecute printline
|
||||
[12] *((const byte*) SCREEN+(byte) $50) ← (byte) val
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[12] return
|
||||
[13] return
|
||||
to:@return
|
||||
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
__stackcall (void()) main()
|
||||
__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
|
||||
|
||||
Initial phi equivalence classes
|
||||
[ printline::i#2 printline::i#1 ]
|
||||
Added variable val to live range equivalence class [ val ]
|
||||
Added variable printline::i to live range equivalence class [ printline::i ]
|
||||
Complete equivalence classes
|
||||
[ printline::i#2 printline::i#1 ]
|
||||
[ val ]
|
||||
[ printline::i ]
|
||||
Allocated zp[1]:2 [ val ]
|
||||
Allocated zp[1]:3 [ printline::i ]
|
||||
Allocated zp[1]:2 [ printline::i#2 printline::i#1 ]
|
||||
Allocated zp[1]:3 [ val ]
|
||||
|
||||
INITIAL ASM
|
||||
Target platform is c64basic / MOS6502X
|
||||
@ -145,7 +165,7 @@ Target platform is c64basic / MOS6502X
|
||||
.pc = $80d "Program"
|
||||
// Global Constants & labels
|
||||
.label SCREEN = $400
|
||||
.label val = 2
|
||||
.label val = 3
|
||||
// @begin
|
||||
__bbegin:
|
||||
// [0] (byte) val ← (byte) 0 -- vbuz1=vbuc1
|
||||
@ -165,72 +185,79 @@ __bend_from___b1:
|
||||
__bend:
|
||||
// printline
|
||||
printline: {
|
||||
.label i = 3
|
||||
// [4] (byte) printline::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
.label i = 2
|
||||
// [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
|
||||
sta.z i
|
||||
jmp __b1
|
||||
// printline::@1
|
||||
__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
|
||||
cmp #$28
|
||||
bcc __b2
|
||||
jmp __breturn
|
||||
// printline::@return
|
||||
__breturn:
|
||||
// [6] return
|
||||
// [7] return
|
||||
rts
|
||||
// printline::@2
|
||||
__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 #'*'
|
||||
ldy.z i
|
||||
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
|
||||
// [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
|
||||
}
|
||||
// main
|
||||
main: {
|
||||
// [9] (byte) val ← (byte) '-' -- vbuz1=vbuc1
|
||||
// [10] (byte) val ← (byte) '-' -- vbuz1=vbuc1
|
||||
lda #'-'
|
||||
sta.z val
|
||||
// [10] callexecute printline -- jsr
|
||||
// [11] callexecute printline -- jsr
|
||||
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
|
||||
sta SCREEN+$50
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [12] return
|
||||
// [13] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
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 [5] if((byte) printline::i<(byte) $28) goto printline::@2 [ printline::i ] ( main:2::printline:10 [ val printline::i ] ) always clobbers reg byte a
|
||||
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 [9] (byte) val ← (byte) '-' [ val ] ( main:2 [ val ] ) always clobbers reg byte a
|
||||
Statement [11] *((const byte*) SCREEN+(byte) $50) ← (byte) val [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
Potential registers zp[1]:2 [ val ] : zp[1]:2 ,
|
||||
Potential registers zp[1]:3 [ printline::i ] : zp[1]:3 ,
|
||||
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
|
||||
Removing always clobbered register reg byte a as potential for zp[1]:2 [ printline::i#2 printline::i#1 ]
|
||||
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
|
||||
Statement [0] (byte) val ← (byte) 0 [ ] ( [ ] ) 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 [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
|
||||
Uplift Scope [printline] 11.5: zp[1]:3 [ printline::i ]
|
||||
Uplift Scope [] 3: zp[1]:2 [ val ]
|
||||
Uplift Scope [printline] 36.67: zp[1]:2 [ printline::i#2 printline::i#1 ]
|
||||
Uplift Scope [] 3: zp[1]:3 [ val ]
|
||||
Uplift Scope [main]
|
||||
|
||||
Uplifting [printline] best 343 combination zp[1]:3 [ printline::i ]
|
||||
Uplifting [] best 343 combination zp[1]:2 [ val ]
|
||||
Uplifting [main] best 343 combination
|
||||
Attempting to uplift remaining variables inzp[1]:3 [ printline::i ]
|
||||
Uplifting [printline] best 343 combination zp[1]:3 [ printline::i ]
|
||||
Attempting to uplift remaining variables inzp[1]:2 [ val ]
|
||||
Uplifting [] best 343 combination zp[1]:2 [ val ]
|
||||
Uplifting [printline] best 295 combination reg byte x [ printline::i#2 printline::i#1 ]
|
||||
Uplifting [] best 295 combination zp[1]:3 [ val ]
|
||||
Uplifting [main] best 295 combination
|
||||
Attempting to uplift remaining variables inzp[1]:3 [ val ]
|
||||
Uplifting [] best 295 combination zp[1]:3 [ val ]
|
||||
Allocated (was zp[1]:3) zp[1]:2 [ val ]
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
// File Comments
|
||||
@ -262,46 +289,47 @@ __bend_from___b1:
|
||||
__bend:
|
||||
// printline
|
||||
printline: {
|
||||
.label i = 3
|
||||
// [4] (byte) printline::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z i
|
||||
// [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] -- vbuxx=vbuc1
|
||||
ldx #0
|
||||
jmp __b1
|
||||
// printline::@1
|
||||
__b1:
|
||||
// [5] if((byte) printline::i<(byte) $28) goto printline::@2 -- vbuz1_lt_vbuc1_then_la1
|
||||
lda.z i
|
||||
cmp #$28
|
||||
// [6] if((byte) printline::i#2<(byte) $28) goto printline::@2 -- vbuxx_lt_vbuc1_then_la1
|
||||
cpx #$28
|
||||
bcc __b2
|
||||
jmp __breturn
|
||||
// printline::@return
|
||||
__breturn:
|
||||
// [6] return
|
||||
// [7] return
|
||||
rts
|
||||
// printline::@2
|
||||
__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 #'*'
|
||||
ldy.z i
|
||||
sta SCREEN,y
|
||||
// [8] (byte) printline::i ← ++ (byte) printline::i -- vbuz1=_inc_vbuz1
|
||||
inc.z i
|
||||
sta SCREEN,x
|
||||
// [9] (byte) printline::i#1 ← ++ (byte) printline::i#2 -- vbuxx=_inc_vbuxx
|
||||
inx
|
||||
// [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
|
||||
}
|
||||
// main
|
||||
main: {
|
||||
// [9] (byte) val ← (byte) '-' -- vbuz1=vbuc1
|
||||
// [10] (byte) val ← (byte) '-' -- vbuz1=vbuc1
|
||||
lda #'-'
|
||||
sta.z val
|
||||
// [10] callexecute printline -- jsr
|
||||
// [11] callexecute printline -- jsr
|
||||
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
|
||||
sta SCREEN+$50
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [12] return
|
||||
// [13] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
@ -318,7 +346,9 @@ Removing instruction __bend_from___b1:
|
||||
Succesful ASM optimization Pass5RedundantLabelElimination
|
||||
Removing instruction __b1:
|
||||
Removing instruction __bend:
|
||||
Removing instruction __b1_from_printline:
|
||||
Removing instruction __breturn:
|
||||
Removing instruction __b1_from___b2:
|
||||
Removing instruction __breturn:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
Adding RTS to root block
|
||||
@ -335,15 +365,17 @@ __stackcall (void()) printline()
|
||||
(label) printline::@1
|
||||
(label) printline::@2
|
||||
(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
|
||||
|
||||
reg byte x [ printline::i#2 printline::i#1 ]
|
||||
zp[1]:2 [ val ]
|
||||
zp[1]:3 [ printline::i ]
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 307
|
||||
Score: 232
|
||||
|
||||
// File Comments
|
||||
// Test a procedure with calling convention stack
|
||||
@ -370,50 +402,48 @@ __bbegin:
|
||||
// @end
|
||||
// printline
|
||||
printline: {
|
||||
.label i = 3
|
||||
// i=0
|
||||
// [4] (byte) printline::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z i
|
||||
// [5] phi from printline to printline::@1 [phi:printline->printline::@1]
|
||||
// [5] phi (byte) printline::i#2 = (byte) 0 [phi:printline->printline::@1#0] -- vbuxx=vbuc1
|
||||
ldx #0
|
||||
// printline::@1
|
||||
__b1:
|
||||
// for(char i=0; i<40; i++)
|
||||
// [5] if((byte) printline::i<(byte) $28) goto printline::@2 -- vbuz1_lt_vbuc1_then_la1
|
||||
lda.z i
|
||||
cmp #$28
|
||||
// [6] if((byte) printline::i#2<(byte) $28) goto printline::@2 -- vbuxx_lt_vbuc1_then_la1
|
||||
cpx #$28
|
||||
bcc __b2
|
||||
// printline::@return
|
||||
// }
|
||||
// [6] return
|
||||
// [7] return
|
||||
rts
|
||||
// printline::@2
|
||||
__b2:
|
||||
// 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 #'*'
|
||||
ldy.z i
|
||||
sta SCREEN,y
|
||||
sta SCREEN,x
|
||||
// for(char i=0; i<40; i++)
|
||||
// [8] (byte) printline::i ← ++ (byte) printline::i -- vbuz1=_inc_vbuz1
|
||||
inc.z i
|
||||
// [9] (byte) printline::i#1 ← ++ (byte) printline::i#2 -- vbuxx=_inc_vbuxx
|
||||
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
|
||||
}
|
||||
// main
|
||||
main: {
|
||||
// val = '-'
|
||||
// [9] (byte) val ← (byte) '-' -- vbuz1=vbuc1
|
||||
// [10] (byte) val ← (byte) '-' -- vbuz1=vbuc1
|
||||
lda #'-'
|
||||
sta.z val
|
||||
// printline()
|
||||
// [10] callexecute printline -- jsr
|
||||
// [11] callexecute printline -- jsr
|
||||
jsr printline
|
||||
// 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
|
||||
sta SCREEN+$50
|
||||
// main::@return
|
||||
// }
|
||||
// [12] return
|
||||
// [13] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
@ -8,8 +8,10 @@ __stackcall (void()) printline()
|
||||
(label) printline::@1
|
||||
(label) printline::@2
|
||||
(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
|
||||
|
||||
reg byte x [ printline::i#2 printline::i#1 ]
|
||||
zp[1]:2 [ val ]
|
||||
zp[1]:3 [ printline::i ]
|
||||
|
@ -12,18 +12,13 @@ __bbegin:
|
||||
jsr main
|
||||
rts
|
||||
printother: {
|
||||
.label i = 3
|
||||
// for(char i:0..5)
|
||||
lda #0
|
||||
sta.z i
|
||||
ldx #0
|
||||
__b1:
|
||||
// (SCREEN+40)[i]++;
|
||||
ldx.z i
|
||||
inc SCREEN+$28,x
|
||||
// for(char i:0..5)
|
||||
inc.z i
|
||||
lda #6
|
||||
cmp.z i
|
||||
inx
|
||||
cpx #6
|
||||
bne __b1
|
||||
// }
|
||||
rts
|
||||
@ -54,10 +49,7 @@ pval: {
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
.label i = 4
|
||||
// for(char i:0..5)
|
||||
lda #0
|
||||
sta.z i
|
||||
ldy #0
|
||||
__b1:
|
||||
// pval()
|
||||
jsr pval
|
||||
@ -66,9 +58,8 @@ main: {
|
||||
// ival()
|
||||
jsr ival
|
||||
// for(char i:0..5)
|
||||
inc.z i
|
||||
lda #6
|
||||
cmp.z i
|
||||
iny
|
||||
cpy #6
|
||||
bne __b1
|
||||
// }
|
||||
rts
|
||||
|
@ -10,63 +10,64 @@
|
||||
|
||||
__stackcall (void()) printother()
|
||||
printother: scope:[printother] from
|
||||
[4] (byte) printother::i ← (byte) 0
|
||||
[4] phi()
|
||||
to: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)
|
||||
[6] (byte) printother::i ← ++ (byte) printother::i
|
||||
[7] if((byte) printother::i!=(byte) 6) goto printother::@1
|
||||
[5] (byte) printother::i#2 ← phi( printother/(byte) 0 printother::@1/(byte) printother::i#1 )
|
||||
[6] *((const byte*) SCREEN+(byte) $28 + (byte) printother::i#2) ← ++ *((const byte*) SCREEN+(byte) $28 + (byte) printother::i#2)
|
||||
[7] (byte) printother::i#1 ← ++ (byte) printother::i#2
|
||||
[8] if((byte) printother::i#1!=(byte) 6) goto printother::@1
|
||||
to:printother::@return
|
||||
printother::@return: scope:[printother] from printother::@1
|
||||
[8] return
|
||||
[9] return
|
||||
to:@return
|
||||
|
||||
__stackcall (void()) incval()
|
||||
incval: scope:[incval] from
|
||||
[9] (byte) val ← ++ (byte) val
|
||||
[10] (byte) val ← ++ (byte) val
|
||||
to:incval::@return
|
||||
incval::@return: scope:[incval] from incval
|
||||
[10] return
|
||||
[11] return
|
||||
to:@return
|
||||
|
||||
__stackcall (void()) printval()
|
||||
printval: scope:[printval] from
|
||||
[11] *((const byte*) SCREEN) ← (byte) val
|
||||
[12] *((const byte*) SCREEN) ← (byte) val
|
||||
to:printval::@return
|
||||
printval::@return: scope:[printval] from printval
|
||||
[12] return
|
||||
[13] return
|
||||
to:@return
|
||||
|
||||
__stackcall (void()) ival()
|
||||
ival: scope:[ival] from
|
||||
[13] phi()
|
||||
[14] callexecute incval
|
||||
[14] phi()
|
||||
[15] callexecute incval
|
||||
to:ival::@return
|
||||
ival::@return: scope:[ival] from ival
|
||||
[15] return
|
||||
[16] return
|
||||
to:@return
|
||||
|
||||
__stackcall (void()) pval()
|
||||
pval: scope:[pval] from
|
||||
[16] phi()
|
||||
[17] callexecute printval
|
||||
[17] phi()
|
||||
[18] callexecute printval
|
||||
to:pval::@return
|
||||
pval::@return: scope:[pval] from pval
|
||||
[18] return
|
||||
[19] return
|
||||
to:@return
|
||||
|
||||
__stackcall (void()) main()
|
||||
main: scope:[main] from
|
||||
[19] (byte) main::i ← (byte) 0
|
||||
[20] phi()
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
[20] phi()
|
||||
[21] callexecute pval
|
||||
[22] callexecute printother
|
||||
[23] callexecute ival
|
||||
[24] (byte) main::i ← ++ (byte) main::i
|
||||
[25] if((byte) main::i!=(byte) 6) goto main::@1
|
||||
[21] (byte) main::i#2 ← phi( main/(byte) 0 main::@1/(byte) main::i#1 )
|
||||
[22] callexecute pval
|
||||
[23] callexecute printother
|
||||
[24] callexecute ival
|
||||
[25] (byte) main::i#1 ← ++ (byte) main::i#2
|
||||
[26] if((byte) main::i#1!=(byte) 6) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[26] return
|
||||
[27] return
|
||||
to:@return
|
||||
|
@ -5,6 +5,7 @@ Culled Empty Block (label) @3
|
||||
Culled Empty Block (label) @4
|
||||
Culled Empty Block (label) @5
|
||||
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 printother
|
||||
Calling convention STACK_CALL adding prepare/execute/finalize for call ival
|
||||
@ -19,14 +20,15 @@ CONTROL FLOW GRAPH SSA
|
||||
|
||||
__stackcall (void()) main()
|
||||
main: scope:[main] from
|
||||
(byte) main::i ← (byte) 0
|
||||
(byte) main::i#0 ← (byte) 0
|
||||
to: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 printother
|
||||
callexecute ival
|
||||
(byte) main::i ← (byte) main::i + rangenext(0,5)
|
||||
(bool~) main::$3 ← (byte) main::i != rangelast(0,5)
|
||||
(byte) main::i#1 ← (byte) main::i#2 + rangenext(0,5)
|
||||
(bool~) main::$3 ← (byte) main::i#1 != rangelast(0,5)
|
||||
if((bool~) main::$3) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
@ -67,12 +69,13 @@ incval::@return: scope:[incval] from incval
|
||||
|
||||
__stackcall (void()) printother()
|
||||
printother: scope:[printother] from
|
||||
(byte) printother::i ← (byte) 0
|
||||
(byte) printother::i#0 ← (byte) 0
|
||||
to: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 ← (byte) printother::i + rangenext(0,5)
|
||||
(bool~) printother::$1 ← (byte) printother::i != rangelast(0,5)
|
||||
(byte) printother::i#2 ← phi( printother/(byte) printother::i#0 printother::@1/(byte) printother::i#1 )
|
||||
*((const byte*) SCREEN+(number) $28 + (byte) printother::i#2) ← ++ *((const byte*) SCREEN+(number) $28 + (byte) printother::i#2)
|
||||
(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
|
||||
to:printother::@return
|
||||
printother::@return: scope:[printother] from printother::@1
|
||||
@ -96,12 +99,18 @@ __stackcall (void()) main()
|
||||
(bool~) main::$3
|
||||
(label) main::@1
|
||||
(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()
|
||||
(bool~) printother::$1
|
||||
(label) printother::@1
|
||||
(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()
|
||||
(label) printval::@return
|
||||
__stackcall (void()) pval()
|
||||
@ -109,7 +118,7 @@ __stackcall (void()) pval()
|
||||
(byte) val loadstore
|
||||
|
||||
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
|
||||
Simplifying constant pointer cast (byte*) 1024
|
||||
Simplifying constant integer cast 0
|
||||
@ -118,17 +127,20 @@ Successful SSA optimization PassNCastSimplification
|
||||
Finalized unsigned number type (byte) 0
|
||||
Finalized unsigned number type (byte) $28
|
||||
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||
Simple Condition (bool~) main::$3 [7] if((byte) main::i!=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~) main::$3 [8] if((byte) main::i#1!=rangelast(0,5)) goto main::@1
|
||||
Simple Condition (bool~) printother::$1 [23] if((byte) printother::i#1!=rangelast(0,5)) goto printother::@1
|
||||
Successful SSA optimization Pass2ConditionalJumpSimplification
|
||||
Resolved ranged next value [5] main::i ← ++ main::i to ++
|
||||
Resolved ranged comparison value [7] if(main::i!=rangelast(0,5)) goto main::@1 to (number) 6
|
||||
Resolved ranged next value [19] printother::i ← ++ printother::i to ++
|
||||
Resolved ranged comparison value [21] if(printother::i!=rangelast(0,5)) goto printother::@1 to (number) 6
|
||||
Simplifying expression containing zero SCREEN in [13] *((const byte*) SCREEN + (byte) 0) ← (byte) val
|
||||
Constant (const byte) main::i#0 = 0
|
||||
Constant (const byte) printother::i#0 = 0
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Resolved ranged next value [6] main::i#1 ← ++ main::i#2 to ++
|
||||
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
|
||||
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) printother::i!=(number) 6) goto printother::@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#1!=(number) 6) goto printother::@1
|
||||
Successful SSA optimization PassNAddNumberTypeConversions
|
||||
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
|
||||
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 @end
|
||||
Adding NOP phi() at start of printother
|
||||
Adding NOP phi() at start of ival
|
||||
Adding NOP phi() at start of pval
|
||||
Adding NOP phi() at start of main::@1
|
||||
Adding NOP phi() at start of main
|
||||
CALL GRAPH
|
||||
Calls in [] to main:2
|
||||
Calls in [ival] to incval:14
|
||||
Calls in [pval] to printval:17
|
||||
Calls in [main] to pval:21 printother:22 ival:23
|
||||
Calls in [ival] to incval:16
|
||||
Calls in [pval] to printval:19
|
||||
Calls in [main] to pval:23 printother:24 ival:25
|
||||
|
||||
Created 0 initial phi equivalence classes
|
||||
Coalesced down to 0 phi equivalence classes
|
||||
Created 2 initial 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
|
||||
Adding NOP phi() at start of @1
|
||||
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 pval
|
||||
Adding NOP phi() at start of main::@1
|
||||
Adding NOP phi() at start of main
|
||||
|
||||
FINAL CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
@ -169,65 +194,66 @@ FINAL CONTROL FLOW GRAPH
|
||||
|
||||
__stackcall (void()) printother()
|
||||
printother: scope:[printother] from
|
||||
[4] (byte) printother::i ← (byte) 0
|
||||
[4] phi()
|
||||
to: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)
|
||||
[6] (byte) printother::i ← ++ (byte) printother::i
|
||||
[7] if((byte) printother::i!=(byte) 6) goto printother::@1
|
||||
[5] (byte) printother::i#2 ← phi( printother/(byte) 0 printother::@1/(byte) printother::i#1 )
|
||||
[6] *((const byte*) SCREEN+(byte) $28 + (byte) printother::i#2) ← ++ *((const byte*) SCREEN+(byte) $28 + (byte) printother::i#2)
|
||||
[7] (byte) printother::i#1 ← ++ (byte) printother::i#2
|
||||
[8] if((byte) printother::i#1!=(byte) 6) goto printother::@1
|
||||
to:printother::@return
|
||||
printother::@return: scope:[printother] from printother::@1
|
||||
[8] return
|
||||
[9] return
|
||||
to:@return
|
||||
|
||||
__stackcall (void()) incval()
|
||||
incval: scope:[incval] from
|
||||
[9] (byte) val ← ++ (byte) val
|
||||
[10] (byte) val ← ++ (byte) val
|
||||
to:incval::@return
|
||||
incval::@return: scope:[incval] from incval
|
||||
[10] return
|
||||
[11] return
|
||||
to:@return
|
||||
|
||||
__stackcall (void()) printval()
|
||||
printval: scope:[printval] from
|
||||
[11] *((const byte*) SCREEN) ← (byte) val
|
||||
[12] *((const byte*) SCREEN) ← (byte) val
|
||||
to:printval::@return
|
||||
printval::@return: scope:[printval] from printval
|
||||
[12] return
|
||||
[13] return
|
||||
to:@return
|
||||
|
||||
__stackcall (void()) ival()
|
||||
ival: scope:[ival] from
|
||||
[13] phi()
|
||||
[14] callexecute incval
|
||||
[14] phi()
|
||||
[15] callexecute incval
|
||||
to:ival::@return
|
||||
ival::@return: scope:[ival] from ival
|
||||
[15] return
|
||||
[16] return
|
||||
to:@return
|
||||
|
||||
__stackcall (void()) pval()
|
||||
pval: scope:[pval] from
|
||||
[16] phi()
|
||||
[17] callexecute printval
|
||||
[17] phi()
|
||||
[18] callexecute printval
|
||||
to:pval::@return
|
||||
pval::@return: scope:[pval] from pval
|
||||
[18] return
|
||||
[19] return
|
||||
to:@return
|
||||
|
||||
__stackcall (void()) main()
|
||||
main: scope:[main] from
|
||||
[19] (byte) main::i ← (byte) 0
|
||||
[20] phi()
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
[20] phi()
|
||||
[21] callexecute pval
|
||||
[22] callexecute printother
|
||||
[23] callexecute ival
|
||||
[24] (byte) main::i ← ++ (byte) main::i
|
||||
[25] if((byte) main::i!=(byte) 6) goto main::@1
|
||||
[21] (byte) main::i#2 ← phi( main/(byte) 0 main::@1/(byte) main::i#1 )
|
||||
[22] callexecute pval
|
||||
[23] callexecute printother
|
||||
[24] callexecute ival
|
||||
[25] (byte) main::i#1 ← ++ (byte) main::i#2
|
||||
[26] if((byte) main::i#1!=(byte) 6) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[26] return
|
||||
[27] return
|
||||
to:@return
|
||||
|
||||
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()) ival()
|
||||
__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()
|
||||
(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()) pval()
|
||||
(byte) val loadstore 0.42105263157894735
|
||||
|
||||
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 printother::i to live range equivalence class [ printother::i ]
|
||||
Added variable main::i to live range equivalence class [ main::i ]
|
||||
Complete equivalence classes
|
||||
[ printother::i#2 printother::i#1 ]
|
||||
[ main::i#2 main::i#1 ]
|
||||
[ val ]
|
||||
[ printother::i ]
|
||||
[ main::i ]
|
||||
Allocated zp[1]:2 [ val ]
|
||||
Allocated zp[1]:3 [ printother::i ]
|
||||
Allocated zp[1]:4 [ main::i ]
|
||||
Allocated zp[1]:2 [ printother::i#2 printother::i#1 ]
|
||||
Allocated zp[1]:3 [ main::i#2 main::i#1 ]
|
||||
Allocated zp[1]:4 [ val ]
|
||||
|
||||
INITIAL ASM
|
||||
Target platform is c64basic / MOS6502X
|
||||
@ -270,7 +300,7 @@ Target platform is c64basic / MOS6502X
|
||||
.pc = $80d "Program"
|
||||
// Global Constants & labels
|
||||
.label SCREEN = $400
|
||||
.label val = 2
|
||||
.label val = 4
|
||||
// @begin
|
||||
__bbegin:
|
||||
// [0] (byte) val ← (byte) 0 -- vbuz1=vbuc1
|
||||
@ -290,135 +320,139 @@ __bend_from___b1:
|
||||
__bend:
|
||||
// printother
|
||||
printother: {
|
||||
.label i = 3
|
||||
// [4] (byte) printother::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
.label i = 2
|
||||
// [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
|
||||
sta.z i
|
||||
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
|
||||
__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
|
||||
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
|
||||
// [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
|
||||
cmp.z i
|
||||
bne __b1
|
||||
bne __b1_from___b1
|
||||
jmp __breturn
|
||||
// printother::@return
|
||||
__breturn:
|
||||
// [8] return
|
||||
// [9] return
|
||||
rts
|
||||
}
|
||||
// incval
|
||||
incval: {
|
||||
// [9] (byte) val ← ++ (byte) val -- vbuz1=_inc_vbuz1
|
||||
// [10] (byte) val ← ++ (byte) val -- vbuz1=_inc_vbuz1
|
||||
inc.z val
|
||||
jmp __breturn
|
||||
// incval::@return
|
||||
__breturn:
|
||||
// [10] return
|
||||
// [11] return
|
||||
rts
|
||||
}
|
||||
// printval
|
||||
printval: {
|
||||
// [11] *((const byte*) SCREEN) ← (byte) val -- _deref_pbuc1=vbuz1
|
||||
// [12] *((const byte*) SCREEN) ← (byte) val -- _deref_pbuc1=vbuz1
|
||||
lda.z val
|
||||
sta SCREEN
|
||||
jmp __breturn
|
||||
// printval::@return
|
||||
__breturn:
|
||||
// [12] return
|
||||
// [13] return
|
||||
rts
|
||||
}
|
||||
// ival
|
||||
ival: {
|
||||
// [14] callexecute incval -- jsr
|
||||
// [15] callexecute incval -- jsr
|
||||
jsr incval
|
||||
jmp __breturn
|
||||
// ival::@return
|
||||
__breturn:
|
||||
// [15] return
|
||||
// [16] return
|
||||
rts
|
||||
}
|
||||
// pval
|
||||
pval: {
|
||||
// [17] callexecute printval -- jsr
|
||||
// [18] callexecute printval -- jsr
|
||||
jsr printval
|
||||
jmp __breturn
|
||||
// pval::@return
|
||||
__breturn:
|
||||
// [18] return
|
||||
// [19] return
|
||||
rts
|
||||
}
|
||||
// main
|
||||
main: {
|
||||
.label i = 4
|
||||
// [19] (byte) main::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
.label i = 3
|
||||
// [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
|
||||
sta.z i
|
||||
// [20] phi from main main::@1 to main::@1 [phi:main/main::@1->main::@1]
|
||||
__b1_from_main:
|
||||
jmp __b1
|
||||
// [21] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
|
||||
__b1_from___b1:
|
||||
// [21] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy
|
||||
jmp __b1
|
||||
// main::@1
|
||||
__b1:
|
||||
// [21] callexecute pval -- jsr
|
||||
// [22] callexecute pval -- jsr
|
||||
jsr pval
|
||||
// [22] callexecute printother -- jsr
|
||||
// [23] callexecute printother -- jsr
|
||||
jsr printother
|
||||
// [23] callexecute ival -- jsr
|
||||
// [24] callexecute ival -- jsr
|
||||
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
|
||||
// [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
|
||||
cmp.z i
|
||||
bne __b1_from___b1
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [26] return
|
||||
// [27] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
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 [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
|
||||
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 [11] *((const byte*) SCREEN) ← (byte) val [ val ] ( main:2::pval:21::printval:17 [ main::i 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
|
||||
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]:2 [ val ] : zp[1]:2 ,
|
||||
Potential registers zp[1]:3 [ printother::i ] : zp[1]:3 ,
|
||||
Potential registers zp[1]:4 [ main::i ] : zp[1]:4 ,
|
||||
Statement [12] *((const byte*) SCREEN) ← (byte) val [ val ] ( main:2::pval:22::printval:18 [ main::i#2 val ] ) always clobbers reg byte a
|
||||
Removing always clobbered register reg byte a as potential for zp[1]:3 [ main::i#2 main::i#1 ]
|
||||
Statement [0] (byte) val ← (byte) 0 [ val ] ( [ 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
|
||||
Potential registers zp[1]:2 [ printother::i#2 printother::i#1 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:3 [ main::i#2 main::i#1 ] : zp[1]:3 , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:4 [ val ] : zp[1]:4 ,
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [printother] 14.25: zp[1]:3 [ printother::i ]
|
||||
Uplift Scope [main] 5: zp[1]:4 [ main::i ]
|
||||
Uplift Scope [] 0.42: zp[1]:2 [ val ]
|
||||
Uplift Scope [printother] 38.5: zp[1]:2 [ printother::i#2 printother::i#1 ]
|
||||
Uplift Scope [main] 22: zp[1]:3 [ main::i#2 main::i#1 ]
|
||||
Uplift Scope [] 0.42: zp[1]:4 [ val ]
|
||||
Uplift Scope [pval]
|
||||
Uplift Scope [ival]
|
||||
Uplift Scope [printval]
|
||||
Uplift Scope [incval]
|
||||
|
||||
Uplifting [printother] best 722 combination zp[1]:3 [ printother::i ]
|
||||
Uplifting [main] best 722 combination zp[1]:4 [ main::i ]
|
||||
Uplifting [] best 722 combination zp[1]:2 [ val ]
|
||||
Uplifting [pval] best 722 combination
|
||||
Uplifting [ival] best 722 combination
|
||||
Uplifting [printval] best 722 combination
|
||||
Uplifting [incval] best 722 combination
|
||||
Attempting to uplift remaining variables inzp[1]:3 [ printother::i ]
|
||||
Uplifting [printother] best 722 combination zp[1]:3 [ printother::i ]
|
||||
Attempting to uplift remaining variables inzp[1]:4 [ main::i ]
|
||||
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 ]
|
||||
Uplifting [printother] best 779 combination reg byte x [ printother::i#2 printother::i#1 ]
|
||||
Uplifting [main] best 689 combination reg byte y [ main::i#2 main::i#1 ]
|
||||
Uplifting [] best 689 combination zp[1]:4 [ val ]
|
||||
Uplifting [pval] best 689 combination
|
||||
Uplifting [ival] best 689 combination
|
||||
Uplifting [printval] best 689 combination
|
||||
Uplifting [incval] best 689 combination
|
||||
Attempting to uplift remaining variables inzp[1]:4 [ val ]
|
||||
Uplifting [] best 689 combination zp[1]:4 [ val ]
|
||||
Allocated (was zp[1]:4) zp[1]:2 [ val ]
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
// File Comments
|
||||
@ -450,97 +484,99 @@ __bend_from___b1:
|
||||
__bend:
|
||||
// printother
|
||||
printother: {
|
||||
.label i = 3
|
||||
// [4] (byte) printother::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z i
|
||||
// [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] -- vbuxx=vbuc1
|
||||
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
|
||||
// printother::@1
|
||||
__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
|
||||
ldx.z i
|
||||
// [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
|
||||
inc SCREEN+$28,x
|
||||
// [6] (byte) printother::i ← ++ (byte) printother::i -- vbuz1=_inc_vbuz1
|
||||
inc.z i
|
||||
// [7] if((byte) printother::i!=(byte) 6) goto printother::@1 -- vbuz1_neq_vbuc1_then_la1
|
||||
lda #6
|
||||
cmp.z i
|
||||
bne __b1
|
||||
// [7] (byte) printother::i#1 ← ++ (byte) printother::i#2 -- vbuxx=_inc_vbuxx
|
||||
inx
|
||||
// [8] if((byte) printother::i#1!=(byte) 6) goto printother::@1 -- vbuxx_neq_vbuc1_then_la1
|
||||
cpx #6
|
||||
bne __b1_from___b1
|
||||
jmp __breturn
|
||||
// printother::@return
|
||||
__breturn:
|
||||
// [8] return
|
||||
// [9] return
|
||||
rts
|
||||
}
|
||||
// incval
|
||||
incval: {
|
||||
// [9] (byte) val ← ++ (byte) val -- vbuz1=_inc_vbuz1
|
||||
// [10] (byte) val ← ++ (byte) val -- vbuz1=_inc_vbuz1
|
||||
inc.z val
|
||||
jmp __breturn
|
||||
// incval::@return
|
||||
__breturn:
|
||||
// [10] return
|
||||
// [11] return
|
||||
rts
|
||||
}
|
||||
// printval
|
||||
printval: {
|
||||
// [11] *((const byte*) SCREEN) ← (byte) val -- _deref_pbuc1=vbuz1
|
||||
// [12] *((const byte*) SCREEN) ← (byte) val -- _deref_pbuc1=vbuz1
|
||||
lda.z val
|
||||
sta SCREEN
|
||||
jmp __breturn
|
||||
// printval::@return
|
||||
__breturn:
|
||||
// [12] return
|
||||
// [13] return
|
||||
rts
|
||||
}
|
||||
// ival
|
||||
ival: {
|
||||
// [14] callexecute incval -- jsr
|
||||
// [15] callexecute incval -- jsr
|
||||
jsr incval
|
||||
jmp __breturn
|
||||
// ival::@return
|
||||
__breturn:
|
||||
// [15] return
|
||||
// [16] return
|
||||
rts
|
||||
}
|
||||
// pval
|
||||
pval: {
|
||||
// [17] callexecute printval -- jsr
|
||||
// [18] callexecute printval -- jsr
|
||||
jsr printval
|
||||
jmp __breturn
|
||||
// pval::@return
|
||||
__breturn:
|
||||
// [18] return
|
||||
// [19] return
|
||||
rts
|
||||
}
|
||||
// main
|
||||
main: {
|
||||
.label i = 4
|
||||
// [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]
|
||||
// [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] -- vbuyy=vbuc1
|
||||
ldy #0
|
||||
jmp __b1
|
||||
// [21] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
|
||||
__b1_from___b1:
|
||||
// [21] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy
|
||||
jmp __b1
|
||||
// main::@1
|
||||
__b1:
|
||||
// [21] callexecute pval -- jsr
|
||||
// [22] callexecute pval -- jsr
|
||||
jsr pval
|
||||
// [22] callexecute printother -- jsr
|
||||
// [23] callexecute printother -- jsr
|
||||
jsr printother
|
||||
// [23] callexecute ival -- jsr
|
||||
// [24] callexecute ival -- jsr
|
||||
jsr ival
|
||||
// [24] (byte) main::i ← ++ (byte) main::i -- vbuz1=_inc_vbuz1
|
||||
inc.z i
|
||||
// [25] if((byte) main::i!=(byte) 6) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
|
||||
lda #6
|
||||
cmp.z i
|
||||
// [25] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuyy=_inc_vbuyy
|
||||
iny
|
||||
// [26] if((byte) main::i#1!=(byte) 6) goto main::@1 -- vbuyy_neq_vbuc1_then_la1
|
||||
cpy #6
|
||||
bne __b1_from___b1
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [26] return
|
||||
// [27] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
@ -558,22 +594,28 @@ Removing instruction jmp __b1
|
||||
Removing instruction jmp __breturn
|
||||
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 __bend_from___b1:
|
||||
Removing instruction __b1_from_main:
|
||||
Removing instruction __b1_from___b1:
|
||||
Removing instruction __b1_from___b1:
|
||||
Succesful ASM optimization Pass5RedundantLabelElimination
|
||||
Removing instruction __b1:
|
||||
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 __b1_from_main:
|
||||
Removing instruction __breturn:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
Adding RTS to root block
|
||||
Succesful ASM optimization Pass5AddMainRts
|
||||
Removing instruction jmp __b1
|
||||
Removing instruction jmp __b1
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
|
||||
FINAL SYMBOL TABLE
|
||||
(label) @1
|
||||
@ -587,24 +629,28 @@ __stackcall (void()) ival()
|
||||
__stackcall (void()) main()
|
||||
(label) main::@1
|
||||
(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()
|
||||
(label) printother::@1
|
||||
(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()
|
||||
(label) printval::@return
|
||||
__stackcall (void()) pval()
|
||||
(label) pval::@return
|
||||
(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]:3 [ printother::i ]
|
||||
zp[1]:4 [ main::i ]
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 617
|
||||
Score: 497
|
||||
|
||||
// File Comments
|
||||
// Test a procedure with calling convention stack
|
||||
@ -631,99 +677,95 @@ __bbegin:
|
||||
// @end
|
||||
// printother
|
||||
printother: {
|
||||
.label i = 3
|
||||
// for(char i:0..5)
|
||||
// [4] (byte) printother::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z i
|
||||
// [5] phi from printother to printother::@1 [phi:printother->printother::@1]
|
||||
// [5] phi (byte) printother::i#2 = (byte) 0 [phi:printother->printother::@1#0] -- vbuxx=vbuc1
|
||||
ldx #0
|
||||
// [5] phi from printother::@1 to printother::@1 [phi:printother::@1->printother::@1]
|
||||
// [5] phi (byte) printother::i#2 = (byte) printother::i#1 [phi:printother::@1->printother::@1#0] -- register_copy
|
||||
// printother::@1
|
||||
__b1:
|
||||
// (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
|
||||
ldx.z i
|
||||
// [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
|
||||
inc SCREEN+$28,x
|
||||
// for(char i:0..5)
|
||||
// [6] (byte) printother::i ← ++ (byte) printother::i -- vbuz1=_inc_vbuz1
|
||||
inc.z i
|
||||
// [7] if((byte) printother::i!=(byte) 6) goto printother::@1 -- vbuz1_neq_vbuc1_then_la1
|
||||
lda #6
|
||||
cmp.z i
|
||||
// [7] (byte) printother::i#1 ← ++ (byte) printother::i#2 -- vbuxx=_inc_vbuxx
|
||||
inx
|
||||
// [8] if((byte) printother::i#1!=(byte) 6) goto printother::@1 -- vbuxx_neq_vbuc1_then_la1
|
||||
cpx #6
|
||||
bne __b1
|
||||
// printother::@return
|
||||
// }
|
||||
// [8] return
|
||||
// [9] return
|
||||
rts
|
||||
}
|
||||
// incval
|
||||
incval: {
|
||||
// val++;
|
||||
// [9] (byte) val ← ++ (byte) val -- vbuz1=_inc_vbuz1
|
||||
// [10] (byte) val ← ++ (byte) val -- vbuz1=_inc_vbuz1
|
||||
inc.z val
|
||||
// incval::@return
|
||||
// }
|
||||
// [10] return
|
||||
// [11] return
|
||||
rts
|
||||
}
|
||||
// printval
|
||||
printval: {
|
||||
// SCREEN[0] = val
|
||||
// [11] *((const byte*) SCREEN) ← (byte) val -- _deref_pbuc1=vbuz1
|
||||
// [12] *((const byte*) SCREEN) ← (byte) val -- _deref_pbuc1=vbuz1
|
||||
lda.z val
|
||||
sta SCREEN
|
||||
// printval::@return
|
||||
// }
|
||||
// [12] return
|
||||
// [13] return
|
||||
rts
|
||||
}
|
||||
// ival
|
||||
ival: {
|
||||
// incval()
|
||||
// [14] callexecute incval -- jsr
|
||||
// [15] callexecute incval -- jsr
|
||||
jsr incval
|
||||
// ival::@return
|
||||
// }
|
||||
// [15] return
|
||||
// [16] return
|
||||
rts
|
||||
}
|
||||
// pval
|
||||
pval: {
|
||||
// printval()
|
||||
// [17] callexecute printval -- jsr
|
||||
// [18] callexecute printval -- jsr
|
||||
jsr printval
|
||||
// pval::@return
|
||||
// }
|
||||
// [18] return
|
||||
// [19] return
|
||||
rts
|
||||
}
|
||||
// main
|
||||
main: {
|
||||
.label i = 4
|
||||
// for(char i:0..5)
|
||||
// [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]
|
||||
// [21] phi from main to main::@1 [phi:main->main::@1]
|
||||
// [21] phi (byte) main::i#2 = (byte) 0 [phi:main->main::@1#0] -- vbuyy=vbuc1
|
||||
ldy #0
|
||||
// [21] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
|
||||
// [21] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy
|
||||
// main::@1
|
||||
__b1:
|
||||
// pval()
|
||||
// [21] callexecute pval -- jsr
|
||||
// [22] callexecute pval -- jsr
|
||||
jsr pval
|
||||
// printother()
|
||||
// [22] callexecute printother -- jsr
|
||||
// [23] callexecute printother -- jsr
|
||||
jsr printother
|
||||
// ival()
|
||||
// [23] callexecute ival -- jsr
|
||||
// [24] callexecute ival -- jsr
|
||||
jsr ival
|
||||
// for(char i:0..5)
|
||||
// [24] (byte) main::i ← ++ (byte) main::i -- vbuz1=_inc_vbuz1
|
||||
inc.z i
|
||||
// [25] if((byte) main::i!=(byte) 6) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
|
||||
lda #6
|
||||
cmp.z i
|
||||
// [25] (byte) main::i#1 ← ++ (byte) main::i#2 -- vbuyy=_inc_vbuyy
|
||||
iny
|
||||
// [26] if((byte) main::i#1!=(byte) 6) goto main::@1 -- vbuyy_neq_vbuc1_then_la1
|
||||
cpy #6
|
||||
bne __b1
|
||||
// main::@return
|
||||
// }
|
||||
// [26] return
|
||||
// [27] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
@ -9,17 +9,21 @@ __stackcall (void()) ival()
|
||||
__stackcall (void()) main()
|
||||
(label) main::@1
|
||||
(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()
|
||||
(label) printother::@1
|
||||
(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()
|
||||
(label) printval::@return
|
||||
__stackcall (void()) pval()
|
||||
(label) pval::@return
|
||||
(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]:3 [ printother::i ]
|
||||
zp[1]:4 [ main::i ]
|
||||
|
Loading…
x
Reference in New Issue
Block a user