1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-08-09 04:25:12 +00:00

Init-value of global load/store memory variables is now output directly into data-statements.

This commit is contained in:
jespergravgaard
2020-01-11 14:55:27 +01:00
parent 2eb5aaa24f
commit d5f4b1f690
23 changed files with 144 additions and 222 deletions

View File

@@ -0,0 +1,6 @@
ldy {m1}
sty $fe
ldy {m1}+1
sty $ff
ldy #{c1}
sta ($fe),y

View File

@@ -0,0 +1,7 @@
sty $fd
ldy {m1}
sty $fe
ldy {m1}+1
sty $ff
ldy $fd
sta ($fe),y

View File

@@ -569,7 +569,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
initValue = Initializers.constantify(initValue, new Initializers.ValueTypeSpec(declVarType, declArraySpec), program, statementSource); initValue = Initializers.constantify(initValue, new Initializers.ValueTypeSpec(declVarType, declArraySpec), program, statementSource);
VariableBuilder varBuilder = new VariableBuilder(varName, getCurrentScope(), false, declVarType, declArraySpec, declVarDirectives, currentDataSegment); VariableBuilder varBuilder = new VariableBuilder(varName, getCurrentScope(), false, declVarType, declArraySpec, declVarDirectives, currentDataSegment);
Variable variable = varBuilder.build(); Variable variable = varBuilder.build();
if(variable.isKindConstant() || (variable.isKindLoadStore() && Variable.MemoryArea.MAIN_MEMORY.equals(variable.getMemoryArea()) && initValue instanceof ConstantValue && !declVarStructMember)) { if(variable.isKindConstant() || (variable.isKindLoadStore() && Variable.MemoryArea.MAIN_MEMORY.equals(variable.getMemoryArea()) && initValue instanceof ConstantValue && !declVarStructMember && variable.getRegister()==null)) {
// Set constant value // Set constant value
ConstantValue constInitValue = getConstInitValue(initValue, initializer, statementSource); ConstantValue constInitValue = getConstInitValue(initValue, initializer, statementSource);
variable.setInitValue(constInitValue); variable.setInitValue(constInitValue);

View File

@@ -11,6 +11,7 @@ import dk.camelot64.kickc.model.operators.Operators;
import dk.camelot64.kickc.model.statements.Statement; import dk.camelot64.kickc.model.statements.Statement;
import dk.camelot64.kickc.model.statements.StatementAssignment; import dk.camelot64.kickc.model.statements.StatementAssignment;
import dk.camelot64.kickc.model.statements.StatementLValue; import dk.camelot64.kickc.model.statements.StatementLValue;
import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.model.values.*; import dk.camelot64.kickc.model.values.*;
import java.util.Collection; import java.util.Collection;
@@ -190,6 +191,9 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
//getLog().append("Multiple usages for variable. Not optimizing sub-constant " + variable.toString(getProgram())); //getLog().append("Multiple usages for variable. Not optimizing sub-constant " + variable.toString(getProgram()));
return null; return null;
} }
final Variable var = getScope().getVar(variable);
if(var.isKindLoadStore())
return null;
StatementLValue statementLValue = getGraph().getAssignment(variable); StatementLValue statementLValue = getGraph().getAssignment(variable);
if(statementLValue instanceof StatementAssignment) { if(statementLValue instanceof StatementAssignment) {
StatementAssignment assignment = (StatementAssignment) statementLValue; StatementAssignment assignment = (StatementAssignment) statementLValue;

View File

@@ -7,6 +7,7 @@ import dk.camelot64.kickc.model.operators.OperatorCastPtr;
import dk.camelot64.kickc.model.operators.Operators; import dk.camelot64.kickc.model.operators.Operators;
import dk.camelot64.kickc.model.statements.StatementAssignment; import dk.camelot64.kickc.model.statements.StatementAssignment;
import dk.camelot64.kickc.model.statements.StatementLValue; import dk.camelot64.kickc.model.statements.StatementLValue;
import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.model.types.SymbolType; import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.types.SymbolTypeInference; import dk.camelot64.kickc.model.types.SymbolTypeInference;
import dk.camelot64.kickc.model.types.SymbolTypePointer; import dk.camelot64.kickc.model.types.SymbolTypePointer;
@@ -48,6 +49,9 @@ public class Pass2InlineDerefIdx extends Pass2SsaOptimization {
public RValue attemptInlineDeref(RValue pointer) { public RValue attemptInlineDeref(RValue pointer) {
if(pointer instanceof VariableRef) { if(pointer instanceof VariableRef) {
VariableRef derefVar = (VariableRef) pointer; VariableRef derefVar = (VariableRef) pointer;
final Variable var = getScope().getVar(derefVar);
if(var.isKindLoadStore())
return null;
StatementLValue derefVarDefined = getGraph().getAssignment(derefVar); StatementLValue derefVarDefined = getGraph().getAssignment(derefVar);
if(derefVarDefined instanceof StatementAssignment) { if(derefVarDefined instanceof StatementAssignment) {
StatementAssignment derefAssignment = (StatementAssignment) derefVarDefined; StatementAssignment derefAssignment = (StatementAssignment) derefVarDefined;

View File

@@ -539,17 +539,13 @@ public class Pass4CodeGeneration {
String alignment = AsmFormat.getAsmNumber(declaredAlignment); String alignment = AsmFormat.getAsmNumber(declaredAlignment);
asm.addDataAlignment(alignment); asm.addDataAlignment(alignment);
} }
if(variable.getInitValue()!=null) { if(variable.getInitValue() != null) {
// Variable has a constant init Value // Variable has a constant init Value
ConstantValue constantValue = variable.getInitValue(); ConstantValue constantValue = variable.getInitValue();
if(constantValue instanceof ConstantArray || constantValue instanceof ConstantString || constantValue instanceof ConstantStructValue || constantValue instanceof StructZero) { AsmDataChunk asmDataChunk = new AsmDataChunk();
AsmDataChunk asmDataChunk = new AsmDataChunk(); addChunkData(asmDataChunk, constantValue, variable.getType(), variable.getArraySpec(), scopeRef);
addChunkData(asmDataChunk, constantValue, variable.getType(), variable.getArraySpec(), scopeRef); asmDataChunk.addToAsm(AsmFormat.asmFix(variable.getAsmName()), asm);
asmDataChunk.addToAsm(AsmFormat.asmFix(variable.getAsmName()), asm); } else {
} else {
throw new InternalError("Constant Variable not handled " + variable.toString(program));
}
} else {
// Zero-fill variable // Zero-fill variable
AsmDataChunk asmDataChunk = new AsmDataChunk(); AsmDataChunk asmDataChunk = new AsmDataChunk();
ConstantValue zeroValue = Initializers.createZeroValue(new Initializers.ValueTypeSpec(variable.getType(), variable.getArraySpec()), null); ConstantValue zeroValue = Initializers.createZeroValue(new Initializers.ValueTypeSpec(variable.getType(), variable.getArraySpec()), null);

View File

@@ -55,10 +55,13 @@ public class Pass4LiveRangeEquivalenceClassesFinalize extends Pass2Base {
EquivalenceClassAdder equivalenceClassAdder = new EquivalenceClassAdder(liveRangeEquivalenceClassSet); EquivalenceClassAdder equivalenceClassAdder = new EquivalenceClassAdder(liveRangeEquivalenceClassSet);
equivalenceClassAdder.visitGraph(getGraph()); equivalenceClassAdder.visitGraph(getGraph());
// Add any remaining struct load/store variables // Add any load/store variables with an initializer - and load/store struct variables
for(Variable variable : getSymbols().getAllVariables(true)) for(Variable variable : getSymbols().getAllVariables(true)) {
if(variable.isStructClassic()) if(variable.isKindLoadStore() && variable.getInitValue()!=null)
addToEquivalenceClassSet(variable.getVariableRef(), new ArrayList<>(), liveRangeEquivalenceClassSet ); addToEquivalenceClassSet(variable.getVariableRef(), new ArrayList<>(), liveRangeEquivalenceClassSet);
else if(variable.isStructClassic())
addToEquivalenceClassSet(variable.getVariableRef(), new ArrayList<>(), liveRangeEquivalenceClassSet);
}
getLog().append("Complete equivalence classes"); getLog().append("Complete equivalence classes");
for(LiveRangeEquivalenceClass liveRangeEquivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) { for(LiveRangeEquivalenceClass liveRangeEquivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) {

View File

@@ -1,13 +1,8 @@
// Test declaring a variable as "__mem __notssa", meaning it will be stored in memory and accessed through an implicit pointer (using load/store) // Test declaring a variable as "__mem __notssa", meaning it will be stored in memory and accessed through an implicit pointer (using load/store)
.pc = $801 "Basic" .pc = $801 "Basic"
:BasicUpstart(__bbegin) :BasicUpstart(main)
.pc = $80d "Program" .pc = $80d "Program"
.label SCREEN = $400 .label SCREEN = $400
__bbegin:
lda #0
sta idx
jsr main
rts
main: { main: {
ldx #0 ldx #0
__b1: __b1:

View File

@@ -1,5 +1,5 @@
@begin: scope:[] from @begin: scope:[] from
[0] (byte) idx ← (byte) 0 [0] phi()
to:@1 to:@1
@1: scope:[] from @begin @1: scope:[] from @begin
[1] phi() [1] phi()

View File

@@ -2,7 +2,6 @@ Culled Empty Block (label) main::@2
CONTROL FLOW GRAPH SSA CONTROL FLOW GRAPH SSA
@begin: scope:[] from @begin: scope:[] from
(byte) idx ← (byte) 0
to:@1 to:@1
(void()) main() (void()) main()
@@ -33,7 +32,7 @@ SYMBOL TABLE SSA
(label) @begin (label) @begin
(label) @end (label) @end
(const byte*) SCREEN = (byte*)(number) $400 (const byte*) SCREEN = (byte*)(number) $400
(byte) idx loadstore (byte) idx loadstore = (byte) 0
(void()) main() (void()) main()
(bool~) main::$0 (bool~) main::$0
(label) main::@1 (label) main::@1
@@ -45,12 +44,12 @@ SYMBOL TABLE SSA
Simplifying constant pointer cast (byte*) 1024 Simplifying constant pointer cast (byte*) 1024
Successful SSA optimization PassNCastSimplification Successful SSA optimization PassNCastSimplification
Simple Condition (bool~) main::$0 [7] if((byte) main::i#1!=rangelast(0,5)) goto main::@1 Simple Condition (bool~) main::$0 [6] if((byte) main::i#1!=rangelast(0,5)) goto main::@1
Successful SSA optimization Pass2ConditionalJumpSimplification Successful SSA optimization Pass2ConditionalJumpSimplification
Constant (const byte) main::i#0 = 0 Constant (const byte) main::i#0 = 0
Successful SSA optimization Pass2ConstantIdentification Successful SSA optimization Pass2ConstantIdentification
Resolved ranged next value [5] main::i#1 ← ++ main::i#2 to ++ Resolved ranged next value [4] main::i#1 ← ++ main::i#2 to ++
Resolved ranged comparison value [7] if(main::i#1!=rangelast(0,5)) goto main::@1 to (number) 6 Resolved ranged comparison value [6] if(main::i#1!=rangelast(0,5)) goto main::@1 to (number) 6
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) main::i#1!=(number) 6) goto main::@1
Successful SSA optimization PassNAddNumberTypeConversions Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant integer cast 6 Simplifying constant integer cast 6
@@ -61,6 +60,7 @@ Inlining constant with var siblings (const byte) main::i#0
Constant inlined main::i#0 = (byte) 0 Constant inlined main::i#0 = (byte) 0
Successful SSA optimization Pass2ConstantInlining Successful SSA optimization Pass2ConstantInlining
Added new block during phi lifting main::@3(between main::@1 and main::@1) Added new block during phi lifting main::@3(between main::@1 and main::@1)
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1 Adding NOP phi() at start of @1
Adding NOP phi() at start of @2 Adding NOP phi() at start of @2
Adding NOP phi() at start of @end Adding NOP phi() at start of @end
@@ -73,13 +73,14 @@ Coalesced [12] main::i#3 ← main::i#1
Coalesced down to 1 phi equivalence classes Coalesced down to 1 phi equivalence classes
Culled Empty Block (label) @2 Culled Empty Block (label) @2
Culled Empty Block (label) main::@3 Culled Empty Block (label) main::@3
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1 Adding NOP phi() at start of @1
Adding NOP phi() at start of @end Adding NOP phi() at start of @end
Adding NOP phi() at start of main Adding NOP phi() at start of main
FINAL CONTROL FLOW GRAPH FINAL CONTROL FLOW GRAPH
@begin: scope:[] from @begin: scope:[] from
[0] (byte) idx ← (byte) 0 [0] phi()
to:@1 to:@1
@1: scope:[] from @begin @1: scope:[] from @begin
[1] phi() [1] phi()
@@ -105,7 +106,7 @@ main::@return: scope:[main] from main::@1
VARIABLE REGISTER WEIGHTS VARIABLE REGISTER WEIGHTS
(byte) idx loadstore 5.0 (byte) idx loadstore 4.714285714285714 = (byte) 0
(void()) main() (void()) main()
(byte) main::i (byte) main::i
(byte) main::i#1 16.5 (byte) main::i#1 16.5
@@ -132,9 +133,6 @@ Target platform is c64basic / MOS6502X
.label SCREEN = $400 .label SCREEN = $400
// @begin // @begin
__bbegin: __bbegin:
// [0] (byte) idx ← (byte) 0 -- vbum1=vbuc1
lda #0
sta idx
// [1] phi from @begin to @1 [phi:@begin->@1] // [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin: __b1_from___bbegin:
jmp __b1 jmp __b1
@@ -189,24 +187,22 @@ main: {
idx: .byte 0 idx: .byte 0
REGISTER UPLIFT POTENTIAL REGISTERS REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] (byte) idx ← (byte) 0 [ idx ] ( [ idx ] ) always clobbers reg byte a
Statement [6] *((const byte*) SCREEN + (byte) main::i#2) ← (byte) idx [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte a Statement [6] *((const byte*) SCREEN + (byte) main::i#2) ← (byte) idx [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::i#2 main::i#1 ] Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::i#2 main::i#1 ]
Statement [7] (byte) idx ← (byte) idx + (byte) main::i#2 [ idx main::i#2 ] ( main:2 [ idx main::i#2 ] ) always clobbers reg byte a Statement [7] (byte) idx ← (byte) idx + (byte) main::i#2 [ main::i#2 idx ] ( main:2 [ main::i#2 idx ] ) always clobbers reg byte a
Statement [0] (byte) idx ← (byte) 0 [ idx ] ( [ idx ] ) always clobbers reg byte a
Statement [6] *((const byte*) SCREEN + (byte) main::i#2) ← (byte) idx [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte a Statement [6] *((const byte*) SCREEN + (byte) main::i#2) ← (byte) idx [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte a
Statement [7] (byte) idx ← (byte) idx + (byte) main::i#2 [ idx main::i#2 ] ( main:2 [ idx main::i#2 ] ) always clobbers reg byte a Statement [7] (byte) idx ← (byte) idx + (byte) main::i#2 [ main::i#2 idx ] ( main:2 [ main::i#2 idx ] ) always clobbers reg byte a
Potential registers zp[1]:2 [ main::i#2 main::i#1 ] : zp[1]:2 , reg byte x , reg byte y , Potential registers zp[1]:2 [ main::i#2 main::i#1 ] : zp[1]:2 , reg byte x , reg byte y ,
Potential registers mem[1] [ idx ] : mem[1] , Potential registers mem[1] [ idx ] : mem[1] ,
REGISTER UPLIFT SCOPES REGISTER UPLIFT SCOPES
Uplift Scope [main] 31.17: zp[1]:2 [ main::i#2 main::i#1 ] Uplift Scope [main] 31.17: zp[1]:2 [ main::i#2 main::i#1 ]
Uplift Scope [] 5: mem[1] [ idx ] Uplift Scope [] 4.71: mem[1] [ idx ]
Uplifting [main] best 409 combination reg byte x [ main::i#2 main::i#1 ] Uplifting [main] best 403 combination reg byte x [ main::i#2 main::i#1 ]
Uplifting [] best 409 combination mem[1] [ idx ] Uplifting [] best 403 combination mem[1] [ idx ]
Attempting to uplift remaining variables inmem[1] [ idx ] Attempting to uplift remaining variables inmem[1] [ idx ]
Uplifting [] best 409 combination mem[1] [ idx ] Uplifting [] best 403 combination mem[1] [ idx ]
ASSEMBLER BEFORE OPTIMIZATION ASSEMBLER BEFORE OPTIMIZATION
// File Comments // File Comments
@@ -219,9 +215,6 @@ ASSEMBLER BEFORE OPTIMIZATION
.label SCREEN = $400 .label SCREEN = $400
// @begin // @begin
__bbegin: __bbegin:
// [0] (byte) idx ← (byte) 0 -- vbum1=vbuc1
lda #0
sta idx
// [1] phi from @begin to @1 [phi:@begin->@1] // [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin: __b1_from___bbegin:
jmp __b1 jmp __b1
@@ -277,28 +270,32 @@ Removing instruction jmp __bend
Removing instruction jmp __b1 Removing instruction jmp __b1
Removing instruction jmp __breturn Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination Succesful ASM optimization Pass5NextJumpElimination
Replacing label __bbegin with __b1
Replacing label __b1_from___b1 with __b1 Replacing label __b1_from___b1 with __b1
Removing instruction __bbegin:
Removing instruction __b1_from___bbegin: Removing instruction __b1_from___bbegin:
Removing instruction main_from___b1: Removing instruction main_from___b1:
Removing instruction __bend_from___b1: Removing instruction __bend_from___b1:
Removing instruction __b1_from___b1: Removing instruction __b1_from___b1:
Succesful ASM optimization Pass5RedundantLabelElimination Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __b1:
Removing instruction __bend: Removing instruction __bend:
Removing instruction __b1_from_main: Removing instruction __b1_from_main:
Removing instruction __breturn: Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination Succesful ASM optimization Pass5UnusedLabelElimination
Adding RTS to root block Updating BasicUpstart to call main directly
Succesful ASM optimization Pass5AddMainRts Removing instruction jsr main
Succesful ASM optimization Pass5SkipBegin
Removing instruction jmp __b1 Removing instruction jmp __b1
Succesful ASM optimization Pass5NextJumpElimination Succesful ASM optimization Pass5NextJumpElimination
Removing instruction __b1:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE FINAL SYMBOL TABLE
(label) @1 (label) @1
(label) @begin (label) @begin
(label) @end (label) @end
(const byte*) SCREEN = (byte*) 1024 (const byte*) SCREEN = (byte*) 1024
(byte) idx loadstore mem[1] 5.0 (byte) idx loadstore mem[1] 4.714285714285714 = (byte) 0
(void()) main() (void()) main()
(label) main::@1 (label) main::@1
(label) main::@return (label) main::@return
@@ -311,28 +308,21 @@ mem[1] [ idx ]
FINAL ASSEMBLER FINAL ASSEMBLER
Score: 319 Score: 301
// File Comments // File Comments
// Test declaring a variable as "__mem __notssa", meaning it will be stored in memory and accessed through an implicit pointer (using load/store) // Test declaring a variable as "__mem __notssa", meaning it will be stored in memory and accessed through an implicit pointer (using load/store)
// Upstart // Upstart
.pc = $801 "Basic" .pc = $801 "Basic"
:BasicUpstart(__bbegin) :BasicUpstart(main)
.pc = $80d "Program" .pc = $80d "Program"
// Global Constants & labels // Global Constants & labels
.label SCREEN = $400 .label SCREEN = $400
// @begin // @begin
__bbegin:
// idx
// [0] (byte) idx ← (byte) 0 -- vbum1=vbuc1
lda #0
sta idx
// [1] phi from @begin to @1 [phi:@begin->@1] // [1] phi from @begin to @1 [phi:@begin->@1]
// @1 // @1
// [2] call main // [2] call main
// [4] phi from @1 to main [phi:@1->main] // [4] phi from @1 to main [phi:@1->main]
jsr main
rts
// [3] phi from @1 to @end [phi:@1->@end] // [3] phi from @1 to @end [phi:@1->@end]
// @end // @end
// main // main

View File

@@ -2,7 +2,7 @@
(label) @begin (label) @begin
(label) @end (label) @end
(const byte*) SCREEN = (byte*) 1024 (const byte*) SCREEN = (byte*) 1024
(byte) idx loadstore mem[1] 5.0 (byte) idx loadstore mem[1] 4.714285714285714 = (byte) 0
(void()) main() (void()) main()
(label) main::@1 (label) main::@1
(label) main::@return (label) main::@return

View File

@@ -1,15 +1,10 @@
// Test declaring a variable as "memory", meaning it will be stored in memory and accessed through an implicit pointer (using load/store) // Test declaring a variable as "memory", meaning it will be stored in memory and accessed through an implicit pointer (using load/store)
// Test a pointer to a memory variable // Test a pointer to a memory variable
.pc = $801 "Basic" .pc = $801 "Basic"
:BasicUpstart(__bbegin) :BasicUpstart(main)
.pc = $80d "Program" .pc = $80d "Program"
.label SCREEN = $400 .label SCREEN = $400
.label idx_p = idx .label idx_p = idx
__bbegin:
lda #0
sta idx
jsr main
rts
main: { main: {
ldx #0 ldx #0
__b1: __b1:

View File

@@ -1,5 +1,5 @@
@begin: scope:[] from @begin: scope:[] from
[0] (byte) idx ← (byte) 0 [0] phi()
to:@1 to:@1
@1: scope:[] from @begin @1: scope:[] from @begin
[1] phi() [1] phi()

View File

@@ -4,7 +4,6 @@ Culled Empty Block (label) main::@2
CONTROL FLOW GRAPH SSA CONTROL FLOW GRAPH SSA
@begin: scope:[] from @begin: scope:[] from
(byte) idx ← (byte) 0
to:@1 to:@1
(void()) main() (void()) main()
@@ -35,7 +34,7 @@ SYMBOL TABLE SSA
(label) @begin (label) @begin
(label) @end (label) @end
(const byte*) SCREEN = (byte*)(number) $400 (const byte*) SCREEN = (byte*)(number) $400
(byte) idx loadstore (byte) idx loadstore = (byte) 0
(const byte*) idx_p = &(byte) idx (const byte*) idx_p = &(byte) idx
(void()) main() (void()) main()
(bool~) main::$0 (bool~) main::$0
@@ -48,12 +47,12 @@ SYMBOL TABLE SSA
Simplifying constant pointer cast (byte*) 1024 Simplifying constant pointer cast (byte*) 1024
Successful SSA optimization PassNCastSimplification Successful SSA optimization PassNCastSimplification
Simple Condition (bool~) main::$0 [7] if((byte) main::i#1!=rangelast(0,5)) goto main::@1 Simple Condition (bool~) main::$0 [6] if((byte) main::i#1!=rangelast(0,5)) goto main::@1
Successful SSA optimization Pass2ConditionalJumpSimplification Successful SSA optimization Pass2ConditionalJumpSimplification
Constant (const byte) main::i#0 = 0 Constant (const byte) main::i#0 = 0
Successful SSA optimization Pass2ConstantIdentification Successful SSA optimization Pass2ConstantIdentification
Resolved ranged next value [5] main::i#1 ← ++ main::i#2 to ++ Resolved ranged next value [4] main::i#1 ← ++ main::i#2 to ++
Resolved ranged comparison value [7] if(main::i#1!=rangelast(0,5)) goto main::@1 to (number) 6 Resolved ranged comparison value [6] if(main::i#1!=rangelast(0,5)) goto main::@1 to (number) 6
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) main::i#1!=(number) 6) goto main::@1
Successful SSA optimization PassNAddNumberTypeConversions Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant integer cast 6 Simplifying constant integer cast 6
@@ -64,6 +63,7 @@ Inlining constant with var siblings (const byte) main::i#0
Constant inlined main::i#0 = (byte) 0 Constant inlined main::i#0 = (byte) 0
Successful SSA optimization Pass2ConstantInlining Successful SSA optimization Pass2ConstantInlining
Added new block during phi lifting main::@3(between main::@1 and main::@1) Added new block during phi lifting main::@3(between main::@1 and main::@1)
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1 Adding NOP phi() at start of @1
Adding NOP phi() at start of @2 Adding NOP phi() at start of @2
Adding NOP phi() at start of @end Adding NOP phi() at start of @end
@@ -76,13 +76,14 @@ Coalesced [12] main::i#3 ← main::i#1
Coalesced down to 1 phi equivalence classes Coalesced down to 1 phi equivalence classes
Culled Empty Block (label) @2 Culled Empty Block (label) @2
Culled Empty Block (label) main::@3 Culled Empty Block (label) main::@3
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1 Adding NOP phi() at start of @1
Adding NOP phi() at start of @end Adding NOP phi() at start of @end
Adding NOP phi() at start of main Adding NOP phi() at start of main
FINAL CONTROL FLOW GRAPH FINAL CONTROL FLOW GRAPH
@begin: scope:[] from @begin: scope:[] from
[0] (byte) idx ← (byte) 0 [0] phi()
to:@1 to:@1
@1: scope:[] from @begin @1: scope:[] from @begin
[1] phi() [1] phi()
@@ -108,7 +109,7 @@ main::@return: scope:[main] from main::@1
VARIABLE REGISTER WEIGHTS VARIABLE REGISTER WEIGHTS
(byte) idx loadstore 20.0 (byte) idx loadstore = (byte) 0
(void()) main() (void()) main()
(byte) main::i (byte) main::i
(byte) main::i#1 16.5 (byte) main::i#1 16.5
@@ -137,9 +138,6 @@ Target platform is c64basic / MOS6502X
.label idx_p = idx .label idx_p = idx
// @begin // @begin
__bbegin: __bbegin:
// [0] (byte) idx ← (byte) 0 -- vbum1=vbuc1
lda #0
sta idx
// [1] phi from @begin to @1 [phi:@begin->@1] // [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin: __b1_from___bbegin:
jmp __b1 jmp __b1
@@ -194,11 +192,9 @@ main: {
idx: .byte 0 idx: .byte 0
REGISTER UPLIFT POTENTIAL REGISTERS REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] (byte) idx ← (byte) 0 [ ] ( [ ] ) always clobbers reg byte a
Statement [6] *((const byte*) SCREEN + (byte) main::i#2) ← *((const byte*) idx_p) [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte a Statement [6] *((const byte*) SCREEN + (byte) main::i#2) ← *((const byte*) idx_p) [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::i#2 main::i#1 ] Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::i#2 main::i#1 ]
Statement [7] *((const byte*) idx_p) ← *((const byte*) idx_p) + (byte) main::i#2 [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte a Statement [7] *((const byte*) idx_p) ← *((const byte*) idx_p) + (byte) main::i#2 [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte a
Statement [0] (byte) idx ← (byte) 0 [ ] ( [ ] ) always clobbers reg byte a
Statement [6] *((const byte*) SCREEN + (byte) main::i#2) ← *((const byte*) idx_p) [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte a Statement [6] *((const byte*) SCREEN + (byte) main::i#2) ← *((const byte*) idx_p) [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte a
Statement [7] *((const byte*) idx_p) ← *((const byte*) idx_p) + (byte) main::i#2 [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte a Statement [7] *((const byte*) idx_p) ← *((const byte*) idx_p) + (byte) main::i#2 [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte a
Potential registers zp[1]:2 [ main::i#2 main::i#1 ] : zp[1]:2 , reg byte x , reg byte y , Potential registers zp[1]:2 [ main::i#2 main::i#1 ] : zp[1]:2 , reg byte x , reg byte y ,
@@ -206,12 +202,12 @@ Potential registers mem[1] [ idx ] : mem[1] ,
REGISTER UPLIFT SCOPES REGISTER UPLIFT SCOPES
Uplift Scope [main] 31.17: zp[1]:2 [ main::i#2 main::i#1 ] Uplift Scope [main] 31.17: zp[1]:2 [ main::i#2 main::i#1 ]
Uplift Scope [] 20: mem[1] [ idx ] Uplift Scope [] 0: mem[1] [ idx ]
Uplifting [main] best 409 combination reg byte x [ main::i#2 main::i#1 ] Uplifting [main] best 403 combination reg byte x [ main::i#2 main::i#1 ]
Uplifting [] best 409 combination mem[1] [ idx ] Uplifting [] best 403 combination mem[1] [ idx ]
Attempting to uplift remaining variables inmem[1] [ idx ] Attempting to uplift remaining variables inmem[1] [ idx ]
Uplifting [] best 409 combination mem[1] [ idx ] Uplifting [] best 403 combination mem[1] [ idx ]
ASSEMBLER BEFORE OPTIMIZATION ASSEMBLER BEFORE OPTIMIZATION
// File Comments // File Comments
@@ -226,9 +222,6 @@ ASSEMBLER BEFORE OPTIMIZATION
.label idx_p = idx .label idx_p = idx
// @begin // @begin
__bbegin: __bbegin:
// [0] (byte) idx ← (byte) 0 -- vbum1=vbuc1
lda #0
sta idx
// [1] phi from @begin to @1 [phi:@begin->@1] // [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin: __b1_from___bbegin:
jmp __b1 jmp __b1
@@ -284,28 +277,32 @@ Removing instruction jmp __bend
Removing instruction jmp __b1 Removing instruction jmp __b1
Removing instruction jmp __breturn Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination Succesful ASM optimization Pass5NextJumpElimination
Replacing label __bbegin with __b1
Replacing label __b1_from___b1 with __b1 Replacing label __b1_from___b1 with __b1
Removing instruction __bbegin:
Removing instruction __b1_from___bbegin: Removing instruction __b1_from___bbegin:
Removing instruction main_from___b1: Removing instruction main_from___b1:
Removing instruction __bend_from___b1: Removing instruction __bend_from___b1:
Removing instruction __b1_from___b1: Removing instruction __b1_from___b1:
Succesful ASM optimization Pass5RedundantLabelElimination Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __b1:
Removing instruction __bend: Removing instruction __bend:
Removing instruction __b1_from_main: Removing instruction __b1_from_main:
Removing instruction __breturn: Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination Succesful ASM optimization Pass5UnusedLabelElimination
Adding RTS to root block Updating BasicUpstart to call main directly
Succesful ASM optimization Pass5AddMainRts Removing instruction jsr main
Succesful ASM optimization Pass5SkipBegin
Removing instruction jmp __b1 Removing instruction jmp __b1
Succesful ASM optimization Pass5NextJumpElimination Succesful ASM optimization Pass5NextJumpElimination
Removing instruction __b1:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE FINAL SYMBOL TABLE
(label) @1 (label) @1
(label) @begin (label) @begin
(label) @end (label) @end
(const byte*) SCREEN = (byte*) 1024 (const byte*) SCREEN = (byte*) 1024
(byte) idx loadstore mem[1] 20.0 (byte) idx loadstore mem[1] = (byte) 0
(const byte*) idx_p = &(byte) idx (const byte*) idx_p = &(byte) idx
(void()) main() (void()) main()
(label) main::@1 (label) main::@1
@@ -319,30 +316,23 @@ mem[1] [ idx ]
FINAL ASSEMBLER FINAL ASSEMBLER
Score: 319 Score: 301
// File Comments // File Comments
// Test declaring a variable as "memory", meaning it will be stored in memory and accessed through an implicit pointer (using load/store) // Test declaring a variable as "memory", meaning it will be stored in memory and accessed through an implicit pointer (using load/store)
// Test a pointer to a memory variable // Test a pointer to a memory variable
// Upstart // Upstart
.pc = $801 "Basic" .pc = $801 "Basic"
:BasicUpstart(__bbegin) :BasicUpstart(main)
.pc = $80d "Program" .pc = $80d "Program"
// Global Constants & labels // Global Constants & labels
.label SCREEN = $400 .label SCREEN = $400
.label idx_p = idx .label idx_p = idx
// @begin // @begin
__bbegin:
// idx
// [0] (byte) idx ← (byte) 0 -- vbum1=vbuc1
lda #0
sta idx
// [1] phi from @begin to @1 [phi:@begin->@1] // [1] phi from @begin to @1 [phi:@begin->@1]
// @1 // @1
// [2] call main // [2] call main
// [4] phi from @1 to main [phi:@1->main] // [4] phi from @1 to main [phi:@1->main]
jsr main
rts
// [3] phi from @1 to @end [phi:@1->@end] // [3] phi from @1 to @end [phi:@1->@end]
// @end // @end
// main // main

View File

@@ -2,7 +2,7 @@
(label) @begin (label) @begin
(label) @end (label) @end
(const byte*) SCREEN = (byte*) 1024 (const byte*) SCREEN = (byte*) 1024
(byte) idx loadstore mem[1] 20.0 (byte) idx loadstore mem[1] = (byte) 0
(const byte*) idx_p = &(byte) idx (const byte*) idx_p = &(byte) idx
(void()) main() (void()) main()
(label) main::@1 (label) main::@1

View File

@@ -1,16 +1,9 @@
// Test declaring a variable as "memory", meaning it will be stored in memory and accessed through an implicit pointer (using load/store) // Test declaring a variable as "memory", meaning it will be stored in memory and accessed through an implicit pointer (using load/store)
// Test a memory variable containing a pointer // Test a memory variable containing a pointer
.pc = $801 "Basic" .pc = $801 "Basic"
:BasicUpstart(__bbegin) :BasicUpstart(main)
.pc = $80d "Program" .pc = $80d "Program"
.label SCREEN = $400 .label SCREEN = $400
__bbegin:
lda #<SCREEN
sta cursor
lda #>SCREEN
sta cursor+1
jsr main
rts
main: { main: {
ldx #0 ldx #0
__b1: __b1:
@@ -33,4 +26,4 @@ main: {
bne __b1 bne __b1
rts rts
} }
cursor: .word 0 cursor: .word SCREEN

View File

@@ -1,5 +1,5 @@
@begin: scope:[] from @begin: scope:[] from
[0] (byte*) cursor ← (const byte*) SCREEN [0] phi()
to:@1 to:@1
@1: scope:[] from @begin @1: scope:[] from @begin
[1] phi() [1] phi()

View File

@@ -2,7 +2,6 @@ Culled Empty Block (label) main::@2
CONTROL FLOW GRAPH SSA CONTROL FLOW GRAPH SSA
@begin: scope:[] from @begin: scope:[] from
(byte*) cursor ← (const byte*) SCREEN
to:@1 to:@1
(void()) main() (void()) main()
@@ -33,7 +32,7 @@ SYMBOL TABLE SSA
(label) @begin (label) @begin
(label) @end (label) @end
(const byte*) SCREEN = (byte*)(number) $400 (const byte*) SCREEN = (byte*)(number) $400
(byte*) cursor loadstore (byte*) cursor loadstore = (const byte*) SCREEN
(void()) main() (void()) main()
(bool~) main::$0 (bool~) main::$0
(label) main::@1 (label) main::@1
@@ -50,12 +49,12 @@ Simplifying constant integer cast $29
Successful SSA optimization PassNCastSimplification Successful SSA optimization PassNCastSimplification
Finalized unsigned number type (byte) $29 Finalized unsigned number type (byte) $29
Successful SSA optimization PassNFinalizeNumberTypeConversions Successful SSA optimization PassNFinalizeNumberTypeConversions
Simple Condition (bool~) main::$0 [7] if((byte) main::i#1!=rangelast(0,$18)) goto main::@1 Simple Condition (bool~) main::$0 [6] if((byte) main::i#1!=rangelast(0,$18)) goto main::@1
Successful SSA optimization Pass2ConditionalJumpSimplification Successful SSA optimization Pass2ConditionalJumpSimplification
Constant (const byte) main::i#0 = 0 Constant (const byte) main::i#0 = 0
Successful SSA optimization Pass2ConstantIdentification Successful SSA optimization Pass2ConstantIdentification
Resolved ranged next value [5] main::i#1 ← ++ main::i#2 to ++ Resolved ranged next value [4] main::i#1 ← ++ main::i#2 to ++
Resolved ranged comparison value [7] if(main::i#1!=rangelast(0,$18)) goto main::@1 to (number) $19 Resolved ranged comparison value [6] if(main::i#1!=rangelast(0,$18)) goto main::@1 to (number) $19
Adding number conversion cast (unumber) $19 in if((byte) main::i#1!=(number) $19) goto main::@1 Adding number conversion cast (unumber) $19 in if((byte) main::i#1!=(number) $19) goto main::@1
Successful SSA optimization PassNAddNumberTypeConversions Successful SSA optimization PassNAddNumberTypeConversions
Simplifying constant integer cast $19 Simplifying constant integer cast $19
@@ -66,6 +65,7 @@ Inlining constant with var siblings (const byte) main::i#0
Constant inlined main::i#0 = (byte) 0 Constant inlined main::i#0 = (byte) 0
Successful SSA optimization Pass2ConstantInlining Successful SSA optimization Pass2ConstantInlining
Added new block during phi lifting main::@3(between main::@1 and main::@1) Added new block during phi lifting main::@3(between main::@1 and main::@1)
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1 Adding NOP phi() at start of @1
Adding NOP phi() at start of @2 Adding NOP phi() at start of @2
Adding NOP phi() at start of @end Adding NOP phi() at start of @end
@@ -78,13 +78,14 @@ Coalesced [12] main::i#3 ← main::i#1
Coalesced down to 1 phi equivalence classes Coalesced down to 1 phi equivalence classes
Culled Empty Block (label) @2 Culled Empty Block (label) @2
Culled Empty Block (label) main::@3 Culled Empty Block (label) main::@3
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1 Adding NOP phi() at start of @1
Adding NOP phi() at start of @end Adding NOP phi() at start of @end
Adding NOP phi() at start of main Adding NOP phi() at start of main
FINAL CONTROL FLOW GRAPH FINAL CONTROL FLOW GRAPH
@begin: scope:[] from @begin: scope:[] from
[0] (byte*) cursor ← (const byte*) SCREEN [0] phi()
to:@1 to:@1
@1: scope:[] from @begin @1: scope:[] from @begin
[1] phi() [1] phi()
@@ -110,7 +111,7 @@ main::@return: scope:[main] from main::@1
VARIABLE REGISTER WEIGHTS VARIABLE REGISTER WEIGHTS
(byte*) cursor loadstore 5.0 (byte*) cursor loadstore 4.714285714285714 = (const byte*) SCREEN
(void()) main() (void()) main()
(byte) main::i (byte) main::i
(byte) main::i#1 16.5 (byte) main::i#1 16.5
@@ -138,11 +139,6 @@ Target platform is c64basic / MOS6502X
.label SCREEN = $400 .label SCREEN = $400
// @begin // @begin
__bbegin: __bbegin:
// [0] (byte*) cursor ← (const byte*) SCREEN -- pbum1=pbuc1
lda #<SCREEN
sta cursor
lda #>SCREEN
sta cursor+1
// [1] phi from @begin to @1 [phi:@begin->@1] // [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin: __b1_from___bbegin:
jmp __b1 jmp __b1
@@ -201,26 +197,24 @@ main: {
rts rts
} }
// File Data // File Data
cursor: .word 0 cursor: .word SCREEN
REGISTER UPLIFT POTENTIAL REGISTERS REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] (byte*) cursor ← (const byte*) SCREEN [ cursor ] ( [ cursor ] ) always clobbers reg byte a
Statement [6] *((byte*) cursor) ← (byte) '*' [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte a reg byte y Statement [6] *((byte*) cursor) ← (byte) '*' [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte a reg byte y
Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::i#2 main::i#1 ] Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::i#2 main::i#1 ]
Removing always clobbered register reg byte y as potential for zp[1]:2 [ main::i#2 main::i#1 ] Removing always clobbered register reg byte y as potential for zp[1]:2 [ main::i#2 main::i#1 ]
Statement [7] (byte*) cursor ← (byte*) cursor + (byte) $29 [ cursor main::i#2 ] ( main:2 [ cursor main::i#2 ] ) always clobbers reg byte a Statement [7] (byte*) cursor ← (byte*) cursor + (byte) $29 [ main::i#2 cursor ] ( main:2 [ main::i#2 cursor ] ) always clobbers reg byte a
Statement [0] (byte*) cursor ← (const byte*) SCREEN [ cursor ] ( [ cursor ] ) always clobbers reg byte a
Statement [6] *((byte*) cursor) ← (byte) '*' [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte a reg byte y Statement [6] *((byte*) cursor) ← (byte) '*' [ main::i#2 ] ( main:2 [ main::i#2 ] ) always clobbers reg byte a reg byte y
Statement [7] (byte*) cursor ← (byte*) cursor + (byte) $29 [ cursor main::i#2 ] ( main:2 [ cursor main::i#2 ] ) always clobbers reg byte a Statement [7] (byte*) cursor ← (byte*) cursor + (byte) $29 [ main::i#2 cursor ] ( main:2 [ main::i#2 cursor ] ) always clobbers reg byte a
Potential registers zp[1]:2 [ main::i#2 main::i#1 ] : zp[1]:2 , reg byte x , Potential registers zp[1]:2 [ main::i#2 main::i#1 ] : zp[1]:2 , reg byte x ,
Potential registers mem[2] [ cursor ] : mem[2] , Potential registers mem[2] [ cursor ] : mem[2] ,
REGISTER UPLIFT SCOPES REGISTER UPLIFT SCOPES
Uplift Scope [main] 23.83: zp[1]:2 [ main::i#2 main::i#1 ] Uplift Scope [main] 23.83: zp[1]:2 [ main::i#2 main::i#1 ]
Uplift Scope [] 5: mem[2] [ cursor ] Uplift Scope [] 4.71: mem[2] [ cursor ]
Uplifting [main] best 650 combination reg byte x [ main::i#2 main::i#1 ] Uplifting [main] best 638 combination reg byte x [ main::i#2 main::i#1 ]
Uplifting [] best 650 combination mem[2] [ cursor ] Uplifting [] best 638 combination mem[2] [ cursor ]
ASSEMBLER BEFORE OPTIMIZATION ASSEMBLER BEFORE OPTIMIZATION
// File Comments // File Comments
@@ -234,11 +228,6 @@ ASSEMBLER BEFORE OPTIMIZATION
.label SCREEN = $400 .label SCREEN = $400
// @begin // @begin
__bbegin: __bbegin:
// [0] (byte*) cursor ← (const byte*) SCREEN -- pbum1=pbuc1
lda #<SCREEN
sta cursor
lda #>SCREEN
sta cursor+1
// [1] phi from @begin to @1 [phi:@begin->@1] // [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin: __b1_from___bbegin:
jmp __b1 jmp __b1
@@ -294,7 +283,7 @@ main: {
rts rts
} }
// File Data // File Data
cursor: .word 0 cursor: .word SCREEN
ASSEMBLER OPTIMIZATIONS ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1 Removing instruction jmp __b1
@@ -302,28 +291,32 @@ Removing instruction jmp __bend
Removing instruction jmp __b1 Removing instruction jmp __b1
Removing instruction jmp __breturn Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination Succesful ASM optimization Pass5NextJumpElimination
Replacing label __bbegin with __b1
Replacing label __b1_from___b1 with __b1 Replacing label __b1_from___b1 with __b1
Removing instruction __bbegin:
Removing instruction __b1_from___bbegin: Removing instruction __b1_from___bbegin:
Removing instruction main_from___b1: Removing instruction main_from___b1:
Removing instruction __bend_from___b1: Removing instruction __bend_from___b1:
Removing instruction __b1_from___b1: Removing instruction __b1_from___b1:
Succesful ASM optimization Pass5RedundantLabelElimination Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __b1:
Removing instruction __bend: Removing instruction __bend:
Removing instruction __b1_from_main: Removing instruction __b1_from_main:
Removing instruction __breturn: Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination Succesful ASM optimization Pass5UnusedLabelElimination
Adding RTS to root block Updating BasicUpstart to call main directly
Succesful ASM optimization Pass5AddMainRts Removing instruction jsr main
Succesful ASM optimization Pass5SkipBegin
Removing instruction jmp __b1 Removing instruction jmp __b1
Succesful ASM optimization Pass5NextJumpElimination Succesful ASM optimization Pass5NextJumpElimination
Removing instruction __b1:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE FINAL SYMBOL TABLE
(label) @1 (label) @1
(label) @begin (label) @begin
(label) @end (label) @end
(const byte*) SCREEN = (byte*) 1024 (const byte*) SCREEN = (byte*) 1024
(byte*) cursor loadstore mem[2] 5.0 (byte*) cursor loadstore mem[2] 4.714285714285714 = (const byte*) SCREEN
(void()) main() (void()) main()
(label) main::@1 (label) main::@1
(label) main::@return (label) main::@return
@@ -336,31 +329,22 @@ mem[2] [ cursor ]
FINAL ASSEMBLER FINAL ASSEMBLER
Score: 560 Score: 536
// File Comments // File Comments
// Test declaring a variable as "memory", meaning it will be stored in memory and accessed through an implicit pointer (using load/store) // Test declaring a variable as "memory", meaning it will be stored in memory and accessed through an implicit pointer (using load/store)
// Test a memory variable containing a pointer // Test a memory variable containing a pointer
// Upstart // Upstart
.pc = $801 "Basic" .pc = $801 "Basic"
:BasicUpstart(__bbegin) :BasicUpstart(main)
.pc = $80d "Program" .pc = $80d "Program"
// Global Constants & labels // Global Constants & labels
.label SCREEN = $400 .label SCREEN = $400
// @begin // @begin
__bbegin:
// cursor = SCREEN
// [0] (byte*) cursor ← (const byte*) SCREEN -- pbum1=pbuc1
lda #<SCREEN
sta cursor
lda #>SCREEN
sta cursor+1
// [1] phi from @begin to @1 [phi:@begin->@1] // [1] phi from @begin to @1 [phi:@begin->@1]
// @1 // @1
// [2] call main // [2] call main
// [4] phi from @1 to main [phi:@1->main] // [4] phi from @1 to main [phi:@1->main]
jsr main
rts
// [3] phi from @1 to @end [phi:@1->@end] // [3] phi from @1 to @end [phi:@1->@end]
// @end // @end
// main // main
@@ -402,5 +386,5 @@ main: {
rts rts
} }
// File Data // File Data
cursor: .word 0 cursor: .word SCREEN

View File

@@ -2,7 +2,7 @@
(label) @begin (label) @begin
(label) @end (label) @end
(const byte*) SCREEN = (byte*) 1024 (const byte*) SCREEN = (byte*) 1024
(byte*) cursor loadstore mem[2] 5.0 (byte*) cursor loadstore mem[2] 4.714285714285714 = (const byte*) SCREEN
(void()) main() (void()) main()
(label) main::@1 (label) main::@1
(label) main::@return (label) main::@return

View File

@@ -1,19 +1,9 @@
// Minimal struct with C-Standard behavior - global main-mem struct should be initialized in data, not code // Minimal struct with C-Standard behavior - global main-mem struct should be initialized in data, not code
.pc = $801 "Basic" .pc = $801 "Basic"
:BasicUpstart(__bbegin) :BasicUpstart(main)
.pc = $80d "Program" .pc = $80d "Program"
.label SCREEN = $400 .label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 3
.const OFFSET_STRUCT_POINT_INITIALS = 1 .const OFFSET_STRUCT_POINT_INITIALS = 1
__bbegin:
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta point1-1,y
dey
bne !-
jsr main
rts
main: { main: {
lda point1 lda point1
sta SCREEN sta SCREEN
@@ -23,5 +13,4 @@ main: {
sta SCREEN+2 sta SCREEN+2
rts rts
} }
__0: .byte 2, 'j', 'g' point1: .byte 2, 'j', 'g'
point1: .fill SIZEOF_STRUCT_POINT, 0

View File

@@ -1,5 +1,5 @@
@begin: scope:[] from @begin: scope:[] from
[0] *(&(struct Point) point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) [0] phi()
to:@1 to:@1
@1: scope:[] from @begin @1: scope:[] from @begin
[1] phi() [1] phi()

View File

@@ -1,14 +1,12 @@
Fixing struct type size struct Point to 3 Fixing struct type size struct Point to 3
Fixing struct type SIZE_OF struct Point to 3 Fixing struct type SIZE_OF struct Point to 3
Fixing struct type SIZE_OF struct Point to 3 Fixing struct type SIZE_OF struct Point to 3
Adding struct value member variable copy *(&(struct Point) point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
Replacing struct member reference (struct Point) point1.x with member unwinding reference *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_X) Replacing struct member reference (struct Point) point1.x with member unwinding reference *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_X)
Replacing struct member reference (struct Point) point1.initials with member unwinding reference (byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS Replacing struct member reference (struct Point) point1.initials with member unwinding reference (byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS
Replacing struct member reference (struct Point) point1.initials with member unwinding reference (byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS Replacing struct member reference (struct Point) point1.initials with member unwinding reference (byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS
CONTROL FLOW GRAPH SSA CONTROL FLOW GRAPH SSA
@begin: scope:[] from @begin: scope:[] from
*(&(struct Point) point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT)
to:@1 to:@1
(void()) main() (void()) main()
@@ -28,7 +26,6 @@ main::@return: scope:[main] from main
@end: scope:[] from @2 @end: scope:[] from @2
SYMBOL TABLE SSA SYMBOL TABLE SSA
(const struct Point) $0 = { x: (byte) 2, initials: { (byte) 'j', (byte) 'g' } }
(label) @1 (label) @1
(label) @2 (label) @2
(label) @begin (label) @begin
@@ -38,10 +35,9 @@ SYMBOL TABLE SSA
(const byte*) Point::initials[(number) 2] = { fill( 2, 0) } (const byte*) Point::initials[(number) 2] = { fill( 2, 0) }
(byte) Point::x (byte) Point::x
(const byte*) SCREEN = (byte*)(number) $400 (const byte*) SCREEN = (byte*)(number) $400
(const byte) SIZEOF_STRUCT_POINT = (byte) 3
(void()) main() (void()) main()
(label) main::@return (label) main::@return
(struct Point) point1 loadstore (struct Point) point1 loadstore = { x: (byte) 2, initials: { (byte) 'j', (byte) 'g' } }
Adding number conversion cast (unumber) 0 in *((const byte*) SCREEN + (number) 0) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_X) Adding number conversion cast (unumber) 0 in *((const byte*) SCREEN + (number) 0) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_X)
Adding number conversion cast (unumber) 0 in *((const byte*) SCREEN + (number) 1) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (number) 0) Adding number conversion cast (unumber) 0 in *((const byte*) SCREEN + (number) 1) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (number) 0)
@@ -62,9 +58,9 @@ Finalized unsigned number type (byte) 1
Finalized unsigned number type (byte) 1 Finalized unsigned number type (byte) 1
Finalized unsigned number type (byte) 2 Finalized unsigned number type (byte) 2
Successful SSA optimization PassNFinalizeNumberTypeConversions Successful SSA optimization PassNFinalizeNumberTypeConversions
Simplifying expression containing zero (byte*)&point1 in [1] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_X) Simplifying expression containing zero (byte*)&point1 in [0] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_X)
Simplifying expression containing zero SCREEN in [1] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) point1) Simplifying expression containing zero SCREEN in [0] *((const byte*) SCREEN + (byte) 0) ← *((byte*)&(struct Point) point1)
Simplifying expression containing zero (byte*)&point1+OFFSET_STRUCT_POINT_INITIALS in [2] *((const byte*) SCREEN + (byte) 1) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (byte) 0) Simplifying expression containing zero (byte*)&point1+OFFSET_STRUCT_POINT_INITIALS in [1] *((const byte*) SCREEN + (byte) 1) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS + (byte) 0)
Successful SSA optimization PassNSimplifyExpressionWithZero Successful SSA optimization PassNSimplifyExpressionWithZero
Eliminating unused constant (const byte) OFFSET_STRUCT_POINT_X Eliminating unused constant (const byte) OFFSET_STRUCT_POINT_X
Successful SSA optimization PassNEliminateUnusedVars Successful SSA optimization PassNEliminateUnusedVars
@@ -72,6 +68,7 @@ Consolidated array index constant in *(SCREEN+1)
Consolidated array index constant in *((byte*)&point1+OFFSET_STRUCT_POINT_INITIALS+1) Consolidated array index constant in *((byte*)&point1+OFFSET_STRUCT_POINT_INITIALS+1)
Consolidated array index constant in *(SCREEN+2) Consolidated array index constant in *(SCREEN+2)
Successful SSA optimization Pass2ConstantAdditionElimination Successful SSA optimization Pass2ConstantAdditionElimination
Adding NOP phi() at start of @begin
Adding NOP phi() at start of @1 Adding NOP phi() at start of @1
Adding NOP phi() at start of @2 Adding NOP phi() at start of @2
Adding NOP phi() at start of @end Adding NOP phi() at start of @end
@@ -81,12 +78,13 @@ Calls in [] to main:2
Created 0 initial phi equivalence classes Created 0 initial phi equivalence classes
Coalesced down to 0 phi equivalence classes Coalesced down to 0 phi equivalence classes
Culled Empty Block (label) @2 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 @1
Adding NOP phi() at start of @end Adding NOP phi() at start of @end
FINAL CONTROL FLOW GRAPH FINAL CONTROL FLOW GRAPH
@begin: scope:[] from @begin: scope:[] from
[0] *(&(struct Point) point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) [0] phi()
to:@1 to:@1
@1: scope:[] from @begin @1: scope:[] from @begin
[1] phi() [1] phi()
@@ -109,7 +107,7 @@ main::@return: scope:[main] from main
VARIABLE REGISTER WEIGHTS VARIABLE REGISTER WEIGHTS
(byte) Point::x (byte) Point::x
(void()) main() (void()) main()
(struct Point) point1 loadstore (struct Point) point1 loadstore = { x: (byte) 2, initials: { (byte) 'j', (byte) 'g' } }
Initial phi equivalence classes Initial phi equivalence classes
Added variable point1 to live range equivalence class [ point1 ] Added variable point1 to live range equivalence class [ point1 ]
@@ -127,17 +125,9 @@ Target platform is c64basic / MOS6502X
.pc = $80d "Program" .pc = $80d "Program"
// Global Constants & labels // Global Constants & labels
.label SCREEN = $400 .label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 3
.const OFFSET_STRUCT_POINT_INITIALS = 1 .const OFFSET_STRUCT_POINT_INITIALS = 1
// @begin // @begin
__bbegin: __bbegin:
// [0] *(&(struct Point) point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta point1-1,y
dey
bne !-
// [1] phi from @begin to @1 [phi:@begin->@1] // [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin: __b1_from___bbegin:
jmp __b1 jmp __b1
@@ -168,11 +158,9 @@ main: {
rts rts
} }
// File Data // File Data
__0: .byte 2, 'j', 'g' point1: .byte 2, 'j', 'g'
point1: .fill SIZEOF_STRUCT_POINT, 0
REGISTER UPLIFT POTENTIAL REGISTERS REGISTER UPLIFT POTENTIAL REGISTERS
Statement [0] *(&(struct Point) point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) [ point1 ] ( [ point1 ] ) always clobbers reg byte a reg byte y
Statement [4] *((const byte*) SCREEN) ← *((byte*)&(struct Point) point1) [ point1 ] ( main:2 [ point1 ] ) always clobbers reg byte a Statement [4] *((const byte*) SCREEN) ← *((byte*)&(struct Point) point1) [ point1 ] ( main:2 [ point1 ] ) always clobbers reg byte a
Statement [5] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) [ point1 ] ( main:2 [ point1 ] ) always clobbers reg byte a Statement [5] *((const byte*) SCREEN+(byte) 1) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS) [ point1 ] ( main:2 [ point1 ] ) always clobbers reg byte a
Statement [6] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) [ ] ( main:2 [ ] ) always clobbers reg byte a Statement [6] *((const byte*) SCREEN+(byte) 2) ← *((byte*)&(struct Point) point1+(const byte) OFFSET_STRUCT_POINT_INITIALS+(byte) 1) [ ] ( main:2 [ ] ) always clobbers reg byte a
@@ -183,9 +171,9 @@ Uplift Scope [Point]
Uplift Scope [main] Uplift Scope [main]
Uplift Scope [] 0: mem[3] [ point1 ] Uplift Scope [] 0: mem[3] [ point1 ]
Uplifting [Point] best 61 combination Uplifting [Point] best 45 combination
Uplifting [main] best 61 combination Uplifting [main] best 45 combination
Uplifting [] best 61 combination mem[3] [ point1 ] Uplifting [] best 45 combination mem[3] [ point1 ]
ASSEMBLER BEFORE OPTIMIZATION ASSEMBLER BEFORE OPTIMIZATION
// File Comments // File Comments
@@ -196,17 +184,9 @@ ASSEMBLER BEFORE OPTIMIZATION
.pc = $80d "Program" .pc = $80d "Program"
// Global Constants & labels // Global Constants & labels
.label SCREEN = $400 .label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 3
.const OFFSET_STRUCT_POINT_INITIALS = 1 .const OFFSET_STRUCT_POINT_INITIALS = 1
// @begin // @begin
__bbegin: __bbegin:
// [0] *(&(struct Point) point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta point1-1,y
dey
bne !-
// [1] phi from @begin to @1 [phi:@begin->@1] // [1] phi from @begin to @1 [phi:@begin->@1]
__b1_from___bbegin: __b1_from___bbegin:
jmp __b1 jmp __b1
@@ -237,26 +217,28 @@ main: {
rts rts
} }
// File Data // File Data
__0: .byte 2, 'j', 'g' point1: .byte 2, 'j', 'g'
point1: .fill SIZEOF_STRUCT_POINT, 0
ASSEMBLER OPTIMIZATIONS ASSEMBLER OPTIMIZATIONS
Removing instruction jmp __b1 Removing instruction jmp __b1
Removing instruction jmp __bend Removing instruction jmp __bend
Removing instruction jmp __breturn Removing instruction jmp __breturn
Succesful ASM optimization Pass5NextJumpElimination Succesful ASM optimization Pass5NextJumpElimination
Replacing label __bbegin with __b1
Removing instruction __bbegin:
Removing instruction __b1_from___bbegin: Removing instruction __b1_from___bbegin:
Removing instruction __bend_from___b1: Removing instruction __bend_from___b1:
Succesful ASM optimization Pass5RedundantLabelElimination Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction __b1:
Removing instruction __bend: Removing instruction __bend:
Removing instruction __breturn: Removing instruction __breturn:
Succesful ASM optimization Pass5UnusedLabelElimination Succesful ASM optimization Pass5UnusedLabelElimination
Adding RTS to root block Updating BasicUpstart to call main directly
Succesful ASM optimization Pass5AddMainRts Removing instruction jsr main
Succesful ASM optimization Pass5SkipBegin
Removing instruction __b1:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE FINAL SYMBOL TABLE
(const struct Point) $0 = { x: (byte) 2, initials: { (byte) 'j', (byte) 'g' } }
(label) @1 (label) @1
(label) @begin (label) @begin
(label) @end (label) @end
@@ -264,42 +246,29 @@ FINAL SYMBOL TABLE
(const byte*) Point::initials[(number) 2] = { fill( 2, 0) } (const byte*) Point::initials[(number) 2] = { fill( 2, 0) }
(byte) Point::x (byte) Point::x
(const byte*) SCREEN = (byte*) 1024 (const byte*) SCREEN = (byte*) 1024
(const byte) SIZEOF_STRUCT_POINT = (byte) 3
(void()) main() (void()) main()
(label) main::@return (label) main::@return
(struct Point) point1 loadstore mem[3] (struct Point) point1 loadstore mem[3] = { x: (byte) 2, initials: { (byte) 'j', (byte) 'g' } }
mem[3] [ point1 ] mem[3] [ point1 ]
FINAL ASSEMBLER FINAL ASSEMBLER
Score: 58 Score: 30
// File Comments // File Comments
// Minimal struct with C-Standard behavior - global main-mem struct should be initialized in data, not code // Minimal struct with C-Standard behavior - global main-mem struct should be initialized in data, not code
// Upstart // Upstart
.pc = $801 "Basic" .pc = $801 "Basic"
:BasicUpstart(__bbegin) :BasicUpstart(main)
.pc = $80d "Program" .pc = $80d "Program"
// Global Constants & labels // Global Constants & labels
.label SCREEN = $400 .label SCREEN = $400
.const SIZEOF_STRUCT_POINT = 3
.const OFFSET_STRUCT_POINT_INITIALS = 1 .const OFFSET_STRUCT_POINT_INITIALS = 1
// @begin // @begin
__bbegin:
// point1 = { 2, { 'j', 'g' } }
// [0] *(&(struct Point) point1) ← memcpy(*(&(const struct Point) $0), struct Point, (const byte) SIZEOF_STRUCT_POINT) -- _deref_pssc1=_deref_pssc2_memcpy_vbuc3
ldy #SIZEOF_STRUCT_POINT
!:
lda __0-1,y
sta point1-1,y
dey
bne !-
// [1] phi from @begin to @1 [phi:@begin->@1] // [1] phi from @begin to @1 [phi:@begin->@1]
// @1 // @1
// [2] call main // [2] call main
jsr main
rts
// [3] phi from @1 to @end [phi:@1->@end] // [3] phi from @1 to @end [phi:@1->@end]
// @end // @end
// main // main
@@ -322,6 +291,5 @@ main: {
rts rts
} }
// File Data // File Data
__0: .byte 2, 'j', 'g' point1: .byte 2, 'j', 'g'
point1: .fill SIZEOF_STRUCT_POINT, 0

View File

@@ -1,4 +1,3 @@
(const struct Point) $0 = { x: (byte) 2, initials: { (byte) 'j', (byte) 'g' } }
(label) @1 (label) @1
(label) @begin (label) @begin
(label) @end (label) @end
@@ -6,9 +5,8 @@
(const byte*) Point::initials[(number) 2] = { fill( 2, 0) } (const byte*) Point::initials[(number) 2] = { fill( 2, 0) }
(byte) Point::x (byte) Point::x
(const byte*) SCREEN = (byte*) 1024 (const byte*) SCREEN = (byte*) 1024
(const byte) SIZEOF_STRUCT_POINT = (byte) 3
(void()) main() (void()) main()
(label) main::@return (label) main::@return
(struct Point) point1 loadstore mem[3] (struct Point) point1 loadstore mem[3] = { x: (byte) 2, initials: { (byte) 'j', (byte) 'g' } }
mem[3] [ point1 ] mem[3] [ point1 ]