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:
@@ -0,0 +1,6 @@
|
|||||||
|
ldy {m1}
|
||||||
|
sty $fe
|
||||||
|
ldy {m1}+1
|
||||||
|
sty $ff
|
||||||
|
ldy #{c1}
|
||||||
|
sta ($fe),y
|
@@ -0,0 +1,7 @@
|
|||||||
|
sty $fd
|
||||||
|
ldy {m1}
|
||||||
|
sty $fe
|
||||||
|
ldy {m1}+1
|
||||||
|
sty $ff
|
||||||
|
ldy $fd
|
||||||
|
sta ($fe),y
|
@@ -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);
|
||||||
|
@@ -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;
|
||||||
|
@@ -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;
|
||||||
|
@@ -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);
|
||||||
|
@@ -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()) {
|
||||||
|
@@ -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:
|
||||||
|
@@ -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()
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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:
|
||||||
|
@@ -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()
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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()
|
||||||
|
@@ -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
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
|
||||||
|
@@ -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()
|
||||||
|
@@ -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
|
|
||||||
|
|
||||||
|
@@ -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 ]
|
||||||
|
Reference in New Issue
Block a user