1
0
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:
jespergravgaard 2020-03-08 12:57:32 +01:00
parent d217113afb
commit afe8294cd1
39 changed files with 2017 additions and 2066 deletions

View File

@ -53,6 +53,20 @@ public class Pass1CallStack extends Pass2SsaOptimization {
if(createStackBase)
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();

View File

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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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 ]

View File

@ -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

View File

@ -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

View File

@ -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 ]

View File

@ -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: {

View File

@ -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()

View File

@ -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

View File

@ -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 ]

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 ]

View File

@ -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

View File

@ -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

View File

@ -1,6 +1,7 @@
Fixing pointer array-indexing *((const signed word*) SCREEN + (number) 0)
Fixing pointer array-indexing *((const signed word*) SCREEN + (number) 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

View File

@ -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 ]

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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 ]

View File

@ -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: {

View File

@ -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

View File

@ -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

View File

@ -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 ]

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 ]