1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-01-11 20:30:08 +00:00

Working on static initialization rewrite _init(). #257

This commit is contained in:
jespergravgaard 2020-06-20 21:31:49 +02:00
parent 57d5d4500b
commit f4ef60e822
16 changed files with 814 additions and 585 deletions

View File

@ -85,7 +85,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
*/
void addStatement(Statement statement) {
ProcedureCompilation procedureCompilation = getCurrentProcedureCompilation();
if(procedureCompilation==null) {
if(procedureCompilation == null) {
// Statement outside procedure declaration - put into the _init procedure
Procedure initProc = program.getScope().getLocalProcedure(SymbolRef.INIT_PROC_NAME);
if(initProc == null) {
@ -108,24 +108,31 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
// Finalize the _init() procedure - if present
final ProcedureRef initProcedureRef = new ProcedureRef(SymbolRef.INIT_PROC_NAME);
final ProcedureCompilation initCompilation = program.getProcedureCompilation(initProcedureRef);
if(initCompilation!=null) {
initCompilation.getStatementSequence().addStatement(new StatementReturn(null, new StatementSource(RuleContext.EMPTY), Comment.NO_COMMENTS));
initCompilation.getStatementSequence().addStatement(new StatementProcedureEnd(initProcedureRef, new StatementSource(RuleContext.EMPTY), Comment.NO_COMMENTS));
if(initCompilation != null) {
final StatementSequence initSequence = initCompilation.getStatementSequence();
final Label initReturnLabel = program.getScope().getProcedure(initProcedureRef).addLabel(SymbolRef.PROCEXIT_BLOCK_NAME);
initSequence.addStatement(new StatementLabel(initReturnLabel.getRef(), new StatementSource(RuleContext.EMPTY), Comment.NO_COMMENTS));
initSequence.addStatement(new StatementReturn(null, new StatementSource(RuleContext.EMPTY), Comment.NO_COMMENTS));
initSequence.addStatement(new StatementProcedureEnd(initProcedureRef, new StatementSource(RuleContext.EMPTY), Comment.NO_COMMENTS));
}
// Add the _start() procedure to the program
program.setStartProcedure(new ProcedureRef(SymbolRef.START_PROC_NAME));
final Procedure startProcedure = new Procedure(SymbolRef.START_PROC_NAME, SymbolType.VOID, program.getScope(), Scope.SEGMENT_CODE_DEFAULT, Scope.SEGMENT_DATA_DEFAULT, Procedure.CallingConvention.STACK_CALL);
startProcedure.setParameters(new ArrayList<>());
program.getScope().add(startProcedure);
final ProcedureCompilation startProcedureCompilation = program.createProcedureCompilation(startProcedure.getRef());
final StatementSequence sequence = startProcedureCompilation.getStatementSequence();
sequence.addStatement(new StatementProcedureBegin(startProcedure.getRef(), new StatementSource(RuleContext.EMPTY), Comment.NO_COMMENTS));
if(initCompilation!=null)
sequence.addStatement(new StatementCall(null, SymbolRef.INIT_PROC_NAME, new ArrayList<>(), new StatementSource(RuleContext.EMPTY), Comment.NO_COMMENTS));
sequence.addStatement(new StatementCall(null, SymbolRef.MAIN_PROC_NAME, new ArrayList<>(), new StatementSource(RuleContext.EMPTY), Comment.NO_COMMENTS));
sequence.addStatement(new StatementReturn(null, new StatementSource(RuleContext.EMPTY), Comment.NO_COMMENTS));
sequence.addStatement(new StatementProcedureEnd(startProcedure.getRef(), new StatementSource(RuleContext.EMPTY), Comment.NO_COMMENTS));
{
program.setStartProcedure(new ProcedureRef(SymbolRef.START_PROC_NAME));
final Procedure startProcedure = new Procedure(SymbolRef.START_PROC_NAME, SymbolType.VOID, program.getScope(), Scope.SEGMENT_CODE_DEFAULT, Scope.SEGMENT_DATA_DEFAULT, Procedure.CallingConvention.PHI_CALL);
startProcedure.setParameters(new ArrayList<>());
program.getScope().add(startProcedure);
final ProcedureCompilation startProcedureCompilation = program.createProcedureCompilation(startProcedure.getRef());
final StatementSequence startSequence = startProcedureCompilation.getStatementSequence();
startSequence.addStatement(new StatementProcedureBegin(startProcedure.getRef(), new StatementSource(RuleContext.EMPTY), Comment.NO_COMMENTS));
if(initCompilation != null)
startSequence.addStatement(new StatementCall(null, SymbolRef.INIT_PROC_NAME, new ArrayList<>(), new StatementSource(RuleContext.EMPTY), Comment.NO_COMMENTS));
startSequence.addStatement(new StatementCall(null, SymbolRef.MAIN_PROC_NAME, new ArrayList<>(), new StatementSource(RuleContext.EMPTY), Comment.NO_COMMENTS));
final Label startReturnLabel = startProcedure.addLabel(SymbolRef.PROCEXIT_BLOCK_NAME);
startSequence.addStatement(new StatementLabel(startReturnLabel.getRef(), new StatementSource(RuleContext.EMPTY), Comment.NO_COMMENTS));
startSequence.addStatement(new StatementReturn(null, new StatementSource(RuleContext.EMPTY), Comment.NO_COMMENTS));
startSequence.addStatement(new StatementProcedureEnd(startProcedure.getRef(), new StatementSource(RuleContext.EMPTY), Comment.NO_COMMENTS));
}
}
@ -1026,7 +1033,14 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
}
ConstantArrayKickAsm constantArrayKickAsm = new ConstantArrayKickAsm(((SymbolTypePointer) varDecl.getEffectiveType()).getElementType(), kasm.getKickAsmCode(), kasm.getUses(), varDecl.getEffectiveArraySpec().getArraySize());
// Remove the KickAsm statement
final StatementSequence sequence = getCurrentProcedureCompilation().getStatementSequence();
ProcedureCompilation procedureCompilation = getCurrentProcedureCompilation();
if(procedureCompilation == null) {
// Statement outside procedure declaration - put into the _init procedure
Procedure initProc = program.getScope().getLocalProcedure(SymbolRef.INIT_PROC_NAME);
procedureCompilation = program.getProcedureCompilation(initProc.getRef());
}
final StatementSequence sequence = procedureCompilation.getStatementSequence();
sequence.getStatements().remove(sequence.getStatements().size() - 1);
// Add a constant variable
Scope scope = getCurrentScope();

View File

@ -27,7 +27,7 @@ public class PassNEliminateEmptyProcedure extends Pass2SsaOptimization {
// Remove all calls
removeAllCalls(procedure.getRef());
// Remove the procedure
Pass2EliminateUnusedBlocks.removeProcedure(procedure.getRef(), new HashSet<>(),getProgram() );
Pass2EliminateUnusedBlocks.removeProcedure(procedure.getRef(), new HashSet<>(), getProgram());
optimized = true;
}
}
@ -40,16 +40,19 @@ public class PassNEliminateEmptyProcedure extends Pass2SsaOptimization {
while(stmtIt.hasNext()) {
Statement statement = stmtIt.next();
if(statement instanceof StatementCalling && ((StatementCalling) statement).getProcedure().equals(ref)) {
getLog().append("Removing call to empty procedure "+statement.toString(getProgram(), false));
getLog().append("Removing call to empty procedure " + statement.toString(getProgram(), false));
stmtIt.remove();
} else if(statement instanceof StatementCallPrepare && ((StatementCallPrepare) statement).getProcedure().equals(ref)) {
getLog().append("Removing call to empty procedure "+statement.toString(getProgram(), false));
getLog().append("Removing call to empty procedure " + statement.toString(getProgram(), false));
stmtIt.remove();
} else if(statement instanceof StatementCallFinalize && ((StatementCallFinalize) statement).getProcedure().equals(ref)) {
getLog().append("Removing call to empty procedure "+statement.toString(getProgram(), false));
getLog().append("Removing call to empty procedure " + statement.toString(getProgram(), false));
stmtIt.remove();
}
}
if(ref.getLabelRef().equals(block.getCallSuccessor())) {
block.setCallSuccessor(null);
}
}
}

View File

@ -1,17 +1,8 @@
@begin: scope:[] from
[0] phi()
to:@1
@1: scope:[] from @begin
[1] phi()
[2] call main
to:@end
@end: scope:[] from @1
[3] phi()
(void()) main()
main: scope:[main] from @1
[4] *((const byte*) SCREEN) ← *((const byte*) SINTAB)
main: scope:[main] from
[0] *((const byte*) SCREEN) ← *((const byte*) SINTAB)
to:main::@return
main::@return: scope:[main] from main
[5] return
[1] return
to:@return

View File

@ -1,30 +1,44 @@
CONTROL FLOW GRAPH SSA
@begin: scope:[] from
to:@1
(void()) _init()
_init: scope:[_init] from _start
to:_init::@return
_init::@return: scope:[_init] from _init
return
to:@return
(void()) main()
main: scope:[main] from @1
main: scope:[main] from _start::@1
*((const byte*) SCREEN + (number) 0) ← *((const byte*) SINTAB + (number) 0)
to:main::@return
main::@return: scope:[main] from main
return
to:@return
@1: scope:[] from @begin
(void()) _start()
_start: scope:[_start] from
call _init
to:_start::@1
_start::@1: scope:[_start] from _start
call main
to:@2
@2: scope:[] from @1
to:@end
@end: scope:[] from @2
to:_start::@2
_start::@2: scope:[_start] from _start::@1
to:_start::@return
_start::@return: scope:[_start] from _start::@2
return
to:@return
SYMBOL TABLE SSA
(label) @1
(label) @2
(label) @begin
(label) @end
(const byte*) SCREEN = (byte*)(number) $400
(const byte*) SINTAB[(number) $100] = kickasm {{ .fill 256, 128 + 128*sin(i*2*PI/256)
}}
(void()) _init()
(label) _init::@return
(void()) _start()
(label) _start::@1
(label) _start::@2
(label) _start::@return
(void()) main()
(label) main::@return
@ -38,40 +52,33 @@ Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) 0
Finalized unsigned number type (byte) 0
Successful SSA optimization PassNFinalizeNumberTypeConversions
Simplifying expression containing zero SINTAB in [0] *((const byte*) SCREEN + (byte) 0) ← *((const byte*) SINTAB + (byte) 0)
Simplifying expression containing zero SCREEN in [0] *((const byte*) SCREEN + (byte) 0) ← *((const byte*) SINTAB)
Simplifying expression containing zero SINTAB in [1] *((const byte*) SCREEN + (byte) 0) ← *((const byte*) SINTAB + (byte) 0)
Simplifying expression containing zero SCREEN in [1] *((const byte*) SCREEN + (byte) 0) ← *((const byte*) SINTAB)
Successful SSA optimization PassNSimplifyExpressionWithZero
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
Removing call to empty procedure call _init
Removing unused procedure _init
Removing unused procedure block _init
Removing unused procedure block _init::@return
Successful SSA optimization PassNEliminateEmptyProcedure
Removing unused procedure _start
Removing unused procedure block _start
Removing unused procedure block _start::@1
Removing unused procedure block _start::@2
Removing unused procedure block _start::@return
Successful SSA optimization PassNEliminateEmptyStart
CALL GRAPH
Calls in [] to main:2
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
Culled Empty Block (label) @2
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1
Adding NOP phi() at start of @end
FINAL CONTROL FLOW GRAPH
@begin: scope:[] from
[0] phi()
to:@1
@1: scope:[] from @begin
[1] phi()
[2] call main
to:@end
@end: scope:[] from @1
[3] phi()
(void()) main()
main: scope:[main] from @1
[4] *((const byte*) SCREEN) ← *((const byte*) SINTAB)
main: scope:[main] from
[0] *((const byte*) SCREEN) ← *((const byte*) SINTAB)
to:main::@return
main::@return: scope:[main] from main
[5] return
[1] return
to:@return
@ -91,29 +98,15 @@ Target platform is c64basic / MOS6502X
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
// @begin
__bbegin:
// [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin:
jmp __b1
// @1
__b1:
// [2] call main
jsr main
// [3] phi from @1 to @end [phi:@1->@end]
__bend_from___b1:
jmp __bend
// @end
__bend:
// main
main: {
// [4] *((const byte*) SCREEN) ← *((const byte*) SINTAB) -- _deref_pbuc1=_deref_pbuc2
// [0] *((const byte*) SCREEN) ← *((const byte*) SINTAB) -- _deref_pbuc1=_deref_pbuc2
lda SINTAB
sta SCREEN
jmp __breturn
// main::@return
__breturn:
// [5] return
// [1] return
rts
}
// File Data
@ -123,14 +116,14 @@ SINTAB:
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] *((const byte*) SCREEN) ← *((const byte*) SINTAB) [ ] ( main:2 [ ] { } ) always clobbers reg byte a
Statement [0] *((const byte*) SCREEN) ← *((const byte*) SINTAB) [ ] ( [ ] { } ) always clobbers reg byte a
REGISTER UPLIFT SCOPES
Uplift Scope [main]
Uplift Scope []
Uplifting [main] best 29 combination
Uplifting [] best 29 combination
Uplifting [main] best 17 combination
Uplifting [] best 17 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
@ -141,29 +134,15 @@ ASSEMBLER BEFORE OPTIMIZATION
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
// @begin
__bbegin:
// [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin:
jmp __b1
// @1
__b1:
// [2] call main
jsr main
// [3] phi from @1 to @end [phi:@1->@end]
__bend_from___b1:
jmp __bend
// @end
__bend:
// main
main: {
// [4] *((const byte*) SCREEN) ← *((const byte*) SINTAB) -- _deref_pbuc1=_deref_pbuc2
// [0] *((const byte*) SCREEN) ← *((const byte*) SINTAB) -- _deref_pbuc1=_deref_pbuc2
lda SINTAB
sta SCREEN
jmp __breturn
// main::@return
__breturn:
// [5] return
// [1] return
rts
}
// File Data
@ -173,25 +152,12 @@ SINTAB:
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __bend
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction __b1_from___bbegin:
Removing instruction __b1:
Removing instruction __bend_from___b1:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __bbegin:
Removing instruction __bend:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
Removing instruction jsr main
Succesful ASM optimization Pass5SkipBegin
FINAL SYMBOL TABLE
(label) @1
(label) @begin
(label) @end
(const byte*) SCREEN = (byte*) 1024
(const byte*) SINTAB[(number) $100] = kickasm {{ .fill 256, 128 + 128*sin(i*2*PI/256)
}}
@ -211,21 +177,15 @@ Score: 14
.pc = $80d "Program"
// Global Constants & labels
.label SCREEN = $400
// @begin
// [1] phi from @begin to @1 [phi:@begin->@1]
// @1
// [2] call main
// [3] phi from @1 to @end [phi:@1->@end]
// @end
// main
main: {
// SCREEN[0] = SINTAB[0]
// [4] *((const byte*) SCREEN) ← *((const byte*) SINTAB) -- _deref_pbuc1=_deref_pbuc2
// [0] *((const byte*) SCREEN) ← *((const byte*) SINTAB) -- _deref_pbuc1=_deref_pbuc2
lda SINTAB
sta SCREEN
// main::@return
// }
// [5] return
// [1] return
rts
}
// File Data

View File

@ -1,6 +1,3 @@
(label) @1
(label) @begin
(label) @end
(const byte*) SCREEN = (byte*) 1024
(const byte*) SINTAB[(number) $100] = kickasm {{ .fill 256, 128 + 128*sin(i*2*PI/256)
}}

View File

@ -1,64 +1,55 @@
@begin: scope:[] from
[0] phi()
to:@1
@1: scope:[] from @begin
[1] phi()
[2] call main
to:@end
@end: scope:[] from @1
[3] phi()
(void()) main()
main: scope:[main] from @1
[4] phi()
[5] call euclid
[6] (byte) euclid::return#0 ← (byte) euclid::a#5
main: scope:[main] from
[0] phi()
[1] call euclid
[2] (byte) euclid::return#0 ← (byte) euclid::a#5
to:main::@1
main::@1: scope:[main] from main
[7] (byte~) main::$0 ← (byte) euclid::return#0
[8] *((const nomodify byte*) SCREEN) ← (byte~) main::$0
[9] call euclid
[10] (byte) euclid::return#1 ← (byte) euclid::a#5
[3] (byte~) main::$0 ← (byte) euclid::return#0
[4] *((const nomodify byte*) SCREEN) ← (byte~) main::$0
[5] call euclid
[6] (byte) euclid::return#1 ← (byte) euclid::a#5
to:main::@2
main::@2: scope:[main] from main::@1
[11] (byte~) main::$1 ← (byte) euclid::return#1
[12] *((const nomodify byte*) SCREEN+(byte) 1) ← (byte~) main::$1
[13] call euclid
[14] (byte) euclid::return#2 ← (byte) euclid::a#5
[7] (byte~) main::$1 ← (byte) euclid::return#1
[8] *((const nomodify byte*) SCREEN+(byte) 1) ← (byte~) main::$1
[9] call euclid
[10] (byte) euclid::return#2 ← (byte) euclid::a#5
to:main::@3
main::@3: scope:[main] from main::@2
[15] (byte~) main::$2 ← (byte) euclid::return#2
[16] *((const nomodify byte*) SCREEN+(byte) 2) ← (byte~) main::$2
[17] call euclid
[18] (byte) euclid::return#3 ← (byte) euclid::a#5
[11] (byte~) main::$2 ← (byte) euclid::return#2
[12] *((const nomodify byte*) SCREEN+(byte) 2) ← (byte~) main::$2
[13] call euclid
[14] (byte) euclid::return#3 ← (byte) euclid::a#5
to:main::@4
main::@4: scope:[main] from main::@3
[19] (byte~) main::$3 ← (byte) euclid::return#3
[20] *((const nomodify byte*) SCREEN+(byte) 3) ← (byte~) main::$3
[15] (byte~) main::$3 ← (byte) euclid::return#3
[16] *((const nomodify byte*) SCREEN+(byte) 3) ← (byte~) main::$3
to:main::@return
main::@return: scope:[main] from main::@4
[21] return
[17] return
to:@return
(byte()) euclid((byte) euclid::a , (byte) euclid::b)
euclid: scope:[euclid] from main main::@1 main::@2 main::@3
[22] (byte) euclid::b#9 ← phi( main/(byte) 2 main::@1/(byte) $45 main::@2/(byte) $9b main::@3/(byte) 3 )
[22] (byte) euclid::a#10 ← phi( main/(byte) $80 main::@1/(byte) $a9 main::@2/(byte) $ff main::@3/(byte) $63 )
[18] (byte) euclid::b#9 ← phi( main/(byte) 2 main::@1/(byte) $45 main::@2/(byte) $9b main::@3/(byte) 3 )
[18] (byte) euclid::a#10 ← phi( main/(byte) $80 main::@1/(byte) $a9 main::@2/(byte) $ff main::@3/(byte) $63 )
to:euclid::@1
euclid::@1: scope:[euclid] from euclid euclid::@3 euclid::@4
[23] (byte) euclid::b#5 ← phi( euclid/(byte) euclid::b#9 euclid::@3/(byte) euclid::b#5 euclid::@4/(byte) euclid::b#4 )
[23] (byte) euclid::a#5 ← phi( euclid/(byte) euclid::a#10 euclid::@3/(byte) euclid::a#4 euclid::@4/(byte) euclid::a#5 )
[24] if((byte) euclid::a#5!=(byte) euclid::b#5) goto euclid::@2
[19] (byte) euclid::b#5 ← phi( euclid/(byte) euclid::b#9 euclid::@3/(byte) euclid::b#5 euclid::@4/(byte) euclid::b#4 )
[19] (byte) euclid::a#5 ← phi( euclid/(byte) euclid::a#10 euclid::@3/(byte) euclid::a#4 euclid::@4/(byte) euclid::a#5 )
[20] if((byte) euclid::a#5!=(byte) euclid::b#5) goto euclid::@2
to:euclid::@return
euclid::@return: scope:[euclid] from euclid::@1
[25] return
[21] return
to:@return
euclid::@2: scope:[euclid] from euclid::@1
[26] if((byte) euclid::a#5>(byte) euclid::b#5) goto euclid::@3
[22] if((byte) euclid::a#5>(byte) euclid::b#5) goto euclid::@3
to:euclid::@4
euclid::@4: scope:[euclid] from euclid::@2
[27] (byte) euclid::b#4 ← (byte) euclid::b#5 - (byte) euclid::a#5
[23] (byte) euclid::b#4 ← (byte) euclid::b#5 - (byte) euclid::a#5
to:euclid::@1
euclid::@3: scope:[euclid] from euclid::@2
[28] (byte) euclid::a#4 ← (byte) euclid::a#5 - (byte) euclid::b#5
[24] (byte) euclid::a#4 ← (byte) euclid::a#5 - (byte) euclid::b#5
to:euclid::@1

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,3 @@
(label) @1
(label) @begin
(label) @end
(const nomodify byte*) SCREEN = (byte*) 1024
(byte()) euclid((byte) euclid::a , (byte) euclid::b)
(label) euclid::@1
@ -9,24 +6,24 @@
(label) euclid::@4
(label) euclid::@return
(byte) euclid::a
(byte) euclid::a#10 a zp[1]:2 101.0
(byte) euclid::a#4 a zp[1]:2 2002.0
(byte) euclid::a#5 a zp[1]:2 794.6666666666667
(byte) euclid::a#10 a zp[1]:2 11.0
(byte) euclid::a#4 a zp[1]:2 202.0
(byte) euclid::a#5 a zp[1]:2 80.66666666666666
(byte) euclid::b
(byte) euclid::b#4 reg byte x 2002.0
(byte) euclid::b#5 reg byte x 1777.0
(byte) euclid::b#9 reg byte x 101.0
(byte) euclid::b#4 reg byte x 202.0
(byte) euclid::b#5 reg byte x 179.5
(byte) euclid::b#9 reg byte x 11.0
(byte) euclid::return
(byte) euclid::return#0 reg byte a 22.0
(byte) euclid::return#1 reg byte a 22.0
(byte) euclid::return#2 reg byte a 22.0
(byte) euclid::return#3 reg byte a 22.0
(byte) euclid::return#0 reg byte a 4.0
(byte) euclid::return#1 reg byte a 4.0
(byte) euclid::return#2 reg byte a 4.0
(byte) euclid::return#3 reg byte a 4.0
(byte) idx
(void()) main()
(byte~) main::$0 reg byte a 22.0
(byte~) main::$1 reg byte a 22.0
(byte~) main::$2 reg byte a 22.0
(byte~) main::$3 reg byte a 22.0
(byte~) main::$0 reg byte a 4.0
(byte~) main::$1 reg byte a 4.0
(byte~) main::$2 reg byte a 4.0
(byte~) main::$3 reg byte a 4.0
(label) main::@1
(label) main::@2
(label) main::@3

View File

@ -1,26 +1,31 @@
__stackcall (void()) _start()
(void()) _start()
_start: scope:[_start] from
[0] phi()
[1] callexecute _init
[2] call main
[1] call _init
to:_start::@1
_start::@1: scope:[_start] from _start
[3] return
[2] phi()
[3] call main
to:_start::@return
_start::@return: scope:[_start] from _start::@1
[4] return
to:@return
(void()) main()
main: scope:[main] from _start
[4] *((const nomodify byte*) SCREEN) ← (volatile byte) c1
[5] *((const nomodify byte*) SCREEN+(byte) 1) ← (volatile byte) c2
main: scope:[main] from _start::@1
[5] *((const nomodify byte*) SCREEN) ← (volatile byte) c1
[6] *((const nomodify byte*) SCREEN+(byte) 1) ← (volatile byte) c2
to:main::@return
main::@return: scope:[main] from main
[6] return
[7] return
to:@return
__stackcall (void()) _init()
_init: scope:[_init] from
[7] (volatile byte) c1 ← (byte) 'o'
[8] (volatile byte) c2 ← (byte) 'k'
[9] return
(void()) _init()
_init: scope:[_init] from _start
[8] (volatile byte) c1 ← (byte) 'o'
[9] (volatile byte) c2 ← (byte) 'k'
to:_init::@return
_init::@return: scope:[_init] from _init
[10] return
to:@return

View File

@ -1,17 +1,18 @@
Resolved forward reference c2 to (volatile byte) c2
Calling convention STACK_CALL adding prepare/execute/finalize for call _init
CONTROL FLOW GRAPH SSA
__stackcall (void()) _init()
_init: scope:[_init] from
(void()) _init()
_init: scope:[_init] from _start
(volatile byte) c1 ← (byte) 'o'
(volatile byte) c2 ← (byte) 'k'
to:_init::@return
_init::@return: scope:[_init] from _init
return
to:@return
(void()) main()
main: scope:[main] from _start
main: scope:[main] from _start::@1
*((const nomodify byte*) SCREEN + (number) 0) ← (volatile byte) c1
*((const nomodify byte*) SCREEN + (number) 1) ← (volatile byte) c2
to:main::@return
@ -19,20 +20,27 @@ main::@return: scope:[main] from main
return
to:@return
__stackcall (void()) _start()
(void()) _start()
_start: scope:[_start] from
callexecute _init
call main
call _init
to:_start::@1
_start::@1: scope:[_start] from _start
call main
to:_start::@2
_start::@2: scope:[_start] from _start::@1
to:_start::@return
_start::@return: scope:[_start] from _start::@2
return
to:@return
SYMBOL TABLE SSA
(const nomodify byte*) SCREEN = (byte*)(number) $400
__stackcall (void()) _init()
__stackcall (void()) _start()
(void()) _init()
(label) _init::@return
(void()) _start()
(label) _start::@1
(label) _start::@2
(label) _start::@return
(volatile byte) c1 loadstore
(volatile byte) c2 loadstore
(void()) main()
@ -53,47 +61,58 @@ Successful SSA optimization PassNSimplifyExpressionWithZero
Consolidated array index constant in *(SCREEN+1)
Successful SSA optimization Pass2ConstantAdditionElimination
Adding NOP phi() at start of _start
Adding NOP phi() at start of _start::@1
Adding NOP phi() at start of _start::@2
CALL GRAPH
Calls in [_start] to _init:1 main:2
Calls in [_start] to _init:1 main:3
Does this handle main() / _start() correctly?
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
Culled Empty Block (label) _start::@2
Adding NOP phi() at start of _start
Adding NOP phi() at start of _start::@1
Does this handle main() / _start() correctly?
FINAL CONTROL FLOW GRAPH
__stackcall (void()) _start()
(void()) _start()
_start: scope:[_start] from
[0] phi()
[1] callexecute _init
[2] call main
[1] call _init
to:_start::@1
_start::@1: scope:[_start] from _start
[3] return
[2] phi()
[3] call main
to:_start::@return
_start::@return: scope:[_start] from _start::@1
[4] return
to:@return
(void()) main()
main: scope:[main] from _start
[4] *((const nomodify byte*) SCREEN) ← (volatile byte) c1
[5] *((const nomodify byte*) SCREEN+(byte) 1) ← (volatile byte) c2
main: scope:[main] from _start::@1
[5] *((const nomodify byte*) SCREEN) ← (volatile byte) c1
[6] *((const nomodify byte*) SCREEN+(byte) 1) ← (volatile byte) c2
to:main::@return
main::@return: scope:[main] from main
[6] return
[7] return
to:@return
__stackcall (void()) _init()
_init: scope:[_init] from
[7] (volatile byte) c1 ← (byte) 'o'
[8] (volatile byte) c2 ← (byte) 'k'
[9] return
(void()) _init()
_init: scope:[_init] from _start
[8] (volatile byte) c1 ← (byte) 'o'
[9] (volatile byte) c2 ← (byte) 'k'
to:_init::@return
_init::@return: scope:[_init] from _init
[10] return
to:@return
VARIABLE REGISTER WEIGHTS
__stackcall (void()) _init()
__stackcall (void()) _start()
(volatile byte) c1 loadstore 22.0
(volatile byte) c2 loadstore 11.0
(void()) _init()
(void()) _start()
(volatile byte) c1 loadstore 4.4
(volatile byte) c2 loadstore 4.4
(void()) main()
Initial phi equivalence classes
@ -121,67 +140,75 @@ Target platform is c64basic / MOS6502X
.label c2 = 3
// _start
_start: {
// [1] callexecute _init -- jsr
// [1] call _init
jsr _init
// [2] call main
jsr main
// [2] phi from _start to _start::@1 [phi:_start->_start::@1]
__b1_from__start:
jmp __b1
// _start::@1
__b1:
// [3] return
// [3] call main
jsr main
jmp __breturn
// _start::@return
__breturn:
// [4] return
rts
}
// main
main: {
// [4] *((const nomodify byte*) SCREEN) ← (volatile byte) c1 -- _deref_pbuc1=vbuz1
// [5] *((const nomodify byte*) SCREEN) ← (volatile byte) c1 -- _deref_pbuc1=vbuz1
lda.z c1
sta SCREEN
// [5] *((const nomodify byte*) SCREEN+(byte) 1) ← (volatile byte) c2 -- _deref_pbuc1=vbuz1
// [6] *((const nomodify byte*) SCREEN+(byte) 1) ← (volatile byte) c2 -- _deref_pbuc1=vbuz1
lda.z c2
sta SCREEN+1
jmp __breturn
// main::@return
__breturn:
// [6] return
// [7] return
rts
}
// _init
_init: {
// [7] (volatile byte) c1 ← (byte) 'o' -- vbuz1=vbuc1
// [8] (volatile byte) c1 ← (byte) 'o' -- vbuz1=vbuc1
// Initialize a volatile ZP-variable (will be done in the initializer)
lda #'o'
sta.z c1
// [8] (volatile byte) c2 ← (byte) 'k' -- vbuz1=vbuc1
// [9] (volatile byte) c2 ← (byte) 'k' -- vbuz1=vbuc1
// Initialize another volatile ZP-variable (will be done in the initializer)
lda #'k'
sta.z c2
// [9] return
jmp __breturn
// _init::@return
__breturn:
// [10] return
rts
}
// File Data
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [4] *((const nomodify byte*) SCREEN) ← (volatile byte) c1 [ c2 ] ( ) always clobbers reg byte a
Statement [5] *((const nomodify byte*) SCREEN+(byte) 1) ← (volatile byte) c2 [ ] ( ) always clobbers reg byte a
Statement [7] (volatile byte) c1 ← (byte) 'o' [ ] ( ) always clobbers reg byte a
Statement [8] (volatile byte) c2 ← (byte) 'k' [ ] ( ) always clobbers reg byte a
Statement [5] *((const nomodify byte*) SCREEN) ← (volatile byte) c1 [ c2 ] ( main:3 [ c2 ] { } ) always clobbers reg byte a
Statement [6] *((const nomodify byte*) SCREEN+(byte) 1) ← (volatile byte) c2 [ ] ( main:3 [ ] { } ) always clobbers reg byte a
Statement [8] (volatile byte) c1 ← (byte) 'o' [ c1 ] ( _init:1 [ c1 ] { } ) always clobbers reg byte a
Statement [9] (volatile byte) c2 ← (byte) 'k' [ c1 c2 ] ( _init:1 [ c1 c2 ] { } ) always clobbers reg byte a
Potential registers zp[1]:2 [ c1 ] : zp[1]:2 ,
Potential registers zp[1]:3 [ c2 ] : zp[1]:3 ,
REGISTER UPLIFT SCOPES
Uplift Scope [] 22: zp[1]:2 [ c1 ] 11: zp[1]:3 [ c2 ]
Uplift Scope [] 4.4: zp[1]:2 [ c1 ] 4.4: zp[1]:3 [ c2 ]
Uplift Scope [_init]
Uplift Scope [main]
Uplift Scope [_start]
Uplifting [] best 60 combination zp[1]:2 [ c1 ] zp[1]:3 [ c2 ]
Uplifting [_init] best 60 combination
Uplifting [main] best 60 combination
Uplifting [_start] best 60 combination
Uplifting [] best 66 combination zp[1]:2 [ c1 ] zp[1]:3 [ c2 ]
Uplifting [_init] best 66 combination
Uplifting [main] best 66 combination
Uplifting [_start] best 66 combination
Attempting to uplift remaining variables inzp[1]:2 [ c1 ]
Uplifting [] best 60 combination zp[1]:2 [ c1 ]
Uplifting [] best 66 combination zp[1]:2 [ c1 ]
Attempting to uplift remaining variables inzp[1]:3 [ c2 ]
Uplifting [] best 60 combination zp[1]:3 [ c2 ]
Uplifting [] best 66 combination zp[1]:3 [ c2 ]
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
@ -198,41 +225,49 @@ ASSEMBLER BEFORE OPTIMIZATION
.label c2 = 3
// _start
_start: {
// [1] callexecute _init -- jsr
// [1] call _init
jsr _init
// [2] call main
jsr main
// [2] phi from _start to _start::@1 [phi:_start->_start::@1]
__b1_from__start:
jmp __b1
// _start::@1
__b1:
// [3] return
// [3] call main
jsr main
jmp __breturn
// _start::@return
__breturn:
// [4] return
rts
}
// main
main: {
// [4] *((const nomodify byte*) SCREEN) ← (volatile byte) c1 -- _deref_pbuc1=vbuz1
// [5] *((const nomodify byte*) SCREEN) ← (volatile byte) c1 -- _deref_pbuc1=vbuz1
lda.z c1
sta SCREEN
// [5] *((const nomodify byte*) SCREEN+(byte) 1) ← (volatile byte) c2 -- _deref_pbuc1=vbuz1
// [6] *((const nomodify byte*) SCREEN+(byte) 1) ← (volatile byte) c2 -- _deref_pbuc1=vbuz1
lda.z c2
sta SCREEN+1
jmp __breturn
// main::@return
__breturn:
// [6] return
// [7] return
rts
}
// _init
_init: {
// [7] (volatile byte) c1 ← (byte) 'o' -- vbuz1=vbuc1
// [8] (volatile byte) c1 ← (byte) 'o' -- vbuz1=vbuc1
// Initialize a volatile ZP-variable (will be done in the initializer)
lda #'o'
sta.z c1
// [8] (volatile byte) c2 ← (byte) 'k' -- vbuz1=vbuc1
// [9] (volatile byte) c2 ← (byte) 'k' -- vbuz1=vbuc1
// Initialize another volatile ZP-variable (will be done in the initializer)
lda #'k'
sta.z c2
// [9] return
jmp __breturn
// _init::@return
__breturn:
// [10] return
rts
}
// File Data
@ -240,18 +275,26 @@ _init: {
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction __b1_from__start:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __b1:
Removing instruction __breturn:
Removing instruction __breturn:
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
(const nomodify byte*) SCREEN = (byte*) 1024
__stackcall (void()) _init()
__stackcall (void()) _start()
(void()) _init()
(label) _init::@return
(void()) _start()
(label) _start::@1
(volatile byte) c1 loadstore zp[1]:2 22.0
(volatile byte) c2 loadstore zp[1]:3 11.0
(label) _start::@return
(volatile byte) c1 loadstore zp[1]:2 4.4
(volatile byte) c2 loadstore zp[1]:3 4.4
(void()) main()
(label) main::@return
@ -276,42 +319,45 @@ Score: 54
.label c2 = 3
// _start
_start: {
// [1] callexecute _init -- jsr
// [1] call _init
jsr _init
// [2] call main
jsr main
// [2] phi from _start to _start::@1 [phi:_start->_start::@1]
// _start::@1
// [3] return
// [3] call main
jsr main
// _start::@return
// [4] return
rts
}
// main
main: {
// SCREEN[0] = c1
// [4] *((const nomodify byte*) SCREEN) ← (volatile byte) c1 -- _deref_pbuc1=vbuz1
// [5] *((const nomodify byte*) SCREEN) ← (volatile byte) c1 -- _deref_pbuc1=vbuz1
lda.z c1
sta SCREEN
// SCREEN[1] = c2
// [5] *((const nomodify byte*) SCREEN+(byte) 1) ← (volatile byte) c2 -- _deref_pbuc1=vbuz1
// [6] *((const nomodify byte*) SCREEN+(byte) 1) ← (volatile byte) c2 -- _deref_pbuc1=vbuz1
lda.z c2
sta SCREEN+1
// main::@return
// }
// [6] return
// [7] return
rts
}
// _init
_init: {
// c1 = 'o'
// [7] (volatile byte) c1 ← (byte) 'o' -- vbuz1=vbuc1
// [8] (volatile byte) c1 ← (byte) 'o' -- vbuz1=vbuc1
// Initialize a volatile ZP-variable (will be done in the initializer)
lda #'o'
sta.z c1
// c2 = 'k'
// [8] (volatile byte) c2 ← (byte) 'k' -- vbuz1=vbuc1
// [9] (volatile byte) c2 ← (byte) 'k' -- vbuz1=vbuc1
// Initialize another volatile ZP-variable (will be done in the initializer)
lda #'k'
sta.z c2
// [9] return
// _init::@return
// [10] return
rts
}
// File Data

View File

@ -1,9 +1,11 @@
(const nomodify byte*) SCREEN = (byte*) 1024
__stackcall (void()) _init()
__stackcall (void()) _start()
(void()) _init()
(label) _init::@return
(void()) _start()
(label) _start::@1
(volatile byte) c1 loadstore zp[1]:2 22.0
(volatile byte) c2 loadstore zp[1]:3 11.0
(label) _start::@return
(volatile byte) c1 loadstore zp[1]:2 4.4
(volatile byte) c2 loadstore zp[1]:3 4.4
(void()) main()
(label) main::@return

View File

@ -10,18 +10,21 @@ main::@return: scope:[main] from main
return
to:@return
__stackcall (void()) _start()
(void()) _start()
_start: scope:[_start] from
call main
to:_start::@1
_start::@1: scope:[_start] from _start
to:_start::@return
_start::@return: scope:[_start] from _start::@1
return
to:@return
SYMBOL TABLE SSA
(const nomodify byte*) SCREEN = (byte*)(number) $400
__stackcall (void()) _start()
(void()) _start()
(label) _start::@1
(label) _start::@return
(void()) main()
(label) main::@return
@ -37,6 +40,11 @@ Finalized unsigned number type (byte) 1
Successful SSA optimization PassNFinalizeNumberTypeConversions
Simplifying expression containing zero SCREEN in [0] *((const nomodify byte*) SCREEN + (byte) 0) ← (byte) 'o'
Successful SSA optimization PassNSimplifyExpressionWithZero
Removing unused procedure _start
Removing unused procedure block _start
Removing unused procedure block _start::@1
Removing unused procedure block _start::@return
Successful SSA optimization PassNEliminateEmptyStart
Consolidated array index constant in *(SCREEN+1)
Successful SSA optimization Pass2ConstantAdditionElimination
CALL GRAPH
@ -90,8 +98,8 @@ main: {
// File Data
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] *((const nomodify byte*) SCREEN) ← (byte) 'o' [ ] ( ) always clobbers reg byte a
Statement [1] *((const nomodify byte*) SCREEN+(byte) 1) ← (byte) 'k' [ ] ( ) always clobbers reg byte a
Statement [0] *((const nomodify byte*) SCREEN) ← (byte) 'o' [ ] ( [ ] { } ) always clobbers reg byte a
Statement [1] *((const nomodify byte*) SCREEN+(byte) 1) ← (byte) 'k' [ ] ( [ ] { } ) always clobbers reg byte a
REGISTER UPLIFT SCOPES
Uplift Scope [main]

View File

@ -0,0 +1,18 @@
// Tests static initialization code
// No initializer code should be needed (since all values are constant)
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
.const c1 = 'o'
.const c2 = 'k'
.label SCREEN = $400
main: {
// SCREEN[0] = c1
lda #c1
sta SCREEN
// SCREEN[1] = c2
lda #c2
sta SCREEN+1
// }
rts
}

View File

@ -0,0 +1,9 @@
(void()) main()
main: scope:[main] from
[0] *((const nomodify byte*) SCREEN) ← (const byte) c1
[1] *((const nomodify byte*) SCREEN+(byte) 1) ← (const byte) c2
to:main::@return
main::@return: scope:[main] from main
[2] return
to:@return

View File

@ -0,0 +1,207 @@
CONTROL FLOW GRAPH SSA
(void()) _init()
_init: scope:[_init] from _start
to:_init::@return
_init::@return: scope:[_init] from _init
return
to:@return
(void()) main()
main: scope:[main] from _start::@1
*((const nomodify byte*) SCREEN + (number) 0) ← (const byte) c1
*((const nomodify byte*) SCREEN + (number) 1) ← (const byte) c2
to:main::@return
main::@return: scope:[main] from main
return
to:@return
(void()) _start()
_start: scope:[_start] from
call _init
to:_start::@1
_start::@1: scope:[_start] from _start
call main
to:_start::@2
_start::@2: scope:[_start] from _start::@1
to:_start::@return
_start::@return: scope:[_start] from _start::@2
return
to:@return
SYMBOL TABLE SSA
(const nomodify byte*) SCREEN = (byte*)(number) $400
(void()) _init()
(label) _init::@return
(void()) _start()
(label) _start::@1
(label) _start::@2
(label) _start::@return
(const byte) c1 = (byte) 'o'
(const byte) c2 = (byte) 'k'
(void()) main()
(label) main::@return
Adding number conversion cast (unumber) 0 in *((const nomodify byte*) SCREEN + (number) 0) ← (const byte) c1
Adding number conversion cast (unumber) 1 in *((const nomodify byte*) SCREEN + (number) 1) ← (const byte) c2
Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant pointer cast (byte*) 1024
Simplifying constant integer cast 0
Simplifying constant integer cast 1
Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) 0
Finalized unsigned number type (byte) 1
Successful SSA optimization PassNFinalizeNumberTypeConversions
Simplifying expression containing zero SCREEN in [1] *((const nomodify byte*) SCREEN + (byte) 0) ← (const byte) c1
Successful SSA optimization PassNSimplifyExpressionWithZero
Removing call to empty procedure call _init
Removing unused procedure _init
Removing unused procedure block _init
Removing unused procedure block _init::@return
Successful SSA optimization PassNEliminateEmptyProcedure
Removing unused procedure _start
Removing unused procedure block _start
Removing unused procedure block _start::@1
Removing unused procedure block _start::@2
Removing unused procedure block _start::@return
Successful SSA optimization PassNEliminateEmptyStart
Consolidated array index constant in *(SCREEN+1)
Successful SSA optimization Pass2ConstantAdditionElimination
CALL GRAPH
Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes
FINAL CONTROL FLOW GRAPH
(void()) main()
main: scope:[main] from
[0] *((const nomodify byte*) SCREEN) ← (const byte) c1
[1] *((const nomodify byte*) SCREEN+(byte) 1) ← (const byte) c2
to:main::@return
main::@return: scope:[main] from main
[2] return
to:@return
VARIABLE REGISTER WEIGHTS
(void()) main()
Initial phi equivalence classes
Complete equivalence classes
INITIAL ASM
Target platform is c64basic / MOS6502X
// File Comments
// Tests static initialization code
// No initializer code should be needed (since all values are constant)
// Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
// Global Constants & labels
.const c1 = 'o'
.const c2 = 'k'
.label SCREEN = $400
// main
main: {
// [0] *((const nomodify byte*) SCREEN) ← (const byte) c1 -- _deref_pbuc1=vbuc2
lda #c1
sta SCREEN
// [1] *((const nomodify byte*) SCREEN+(byte) 1) ← (const byte) c2 -- _deref_pbuc1=vbuc2
lda #c2
sta SCREEN+1
jmp __breturn
// main::@return
__breturn:
// [2] return
rts
}
// File Data
REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] *((const nomodify byte*) SCREEN) ← (const byte) c1 [ ] ( [ ] { } ) always clobbers reg byte a
Statement [1] *((const nomodify byte*) SCREEN+(byte) 1) ← (const byte) c2 [ ] ( [ ] { } ) always clobbers reg byte a
REGISTER UPLIFT SCOPES
Uplift Scope [main]
Uplift Scope []
Uplifting [main] best 21 combination
Uplifting [] best 21 combination
ASSEMBLER BEFORE OPTIMIZATION
// File Comments
// Tests static initialization code
// No initializer code should be needed (since all values are constant)
// Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
// Global Constants & labels
.const c1 = 'o'
.const c2 = 'k'
.label SCREEN = $400
// main
main: {
// [0] *((const nomodify byte*) SCREEN) ← (const byte) c1 -- _deref_pbuc1=vbuc2
lda #c1
sta SCREEN
// [1] *((const nomodify byte*) SCREEN+(byte) 1) ← (const byte) c2 -- _deref_pbuc1=vbuc2
lda #c2
sta SCREEN+1
jmp __breturn
// main::@return
__breturn:
// [2] return
rts
}
// File Data
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination
Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
(const nomodify byte*) SCREEN = (byte*) 1024
(const byte) c1 = (byte) 'o'
(const byte) c2 = (byte) 'k'
(void()) main()
(label) main::@return
FINAL ASSEMBLER
Score: 18
// File Comments
// Tests static initialization code
// No initializer code should be needed (since all values are constant)
// Upstart
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
// Global Constants & labels
.const c1 = 'o'
.const c2 = 'k'
.label SCREEN = $400
// main
main: {
// SCREEN[0] = c1
// [0] *((const nomodify byte*) SCREEN) ← (const byte) c1 -- _deref_pbuc1=vbuc2
lda #c1
sta SCREEN
// SCREEN[1] = c2
// [1] *((const nomodify byte*) SCREEN+(byte) 1) ← (const byte) c2 -- _deref_pbuc1=vbuc2
lda #c2
sta SCREEN+1
// main::@return
// }
// [2] return
rts
}
// File Data

View File

@ -0,0 +1,6 @@
(const nomodify byte*) SCREEN = (byte*) 1024
(const byte) c1 = (byte) 'o'
(const byte) c2 = (byte) 'k'
(void()) main()
(label) main::@return