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:
parent
57d5d4500b
commit
f4ef60e822
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}}
|
||||
|
@ -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
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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]
|
||||
|
18
src/test/ref/static-init-code-2.asm
Normal file
18
src/test/ref/static-init-code-2.asm
Normal 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
|
||||
}
|
9
src/test/ref/static-init-code-2.cfg
Normal file
9
src/test/ref/static-init-code-2.cfg
Normal 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
|
207
src/test/ref/static-init-code-2.log
Normal file
207
src/test/ref/static-init-code-2.log
Normal 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
|
||||
|
6
src/test/ref/static-init-code-2.sym
Normal file
6
src/test/ref/static-init-code-2.sym
Normal 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user