mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-02-22 13:29:18 +00:00
Started work on phi transition optimization
This commit is contained in:
parent
f72585e3c0
commit
23d9af8420
@ -10,7 +10,6 @@ import java.util.*;
|
|||||||
*/
|
*/
|
||||||
public class Pass4CodeGeneration {
|
public class Pass4CodeGeneration {
|
||||||
|
|
||||||
|
|
||||||
private Program program;
|
private Program program;
|
||||||
|
|
||||||
public Pass4CodeGeneration(Program program) {
|
public Pass4CodeGeneration(Program program) {
|
||||||
@ -215,6 +214,81 @@ public class Pass4CodeGeneration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Keeps track of the phi transitions into blocks during code generation.
|
||||||
|
* Used to ensure that duplicate transitions are only code generated once.
|
||||||
|
* Maps to-block label to the transition information*/
|
||||||
|
private Map<LabelRef, PhiTransitions> transitions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keeps track of the phi transitions into a single block during code generation.
|
||||||
|
* Used to ensure that duplicate transitions are only code generated once.
|
||||||
|
*/
|
||||||
|
public static class PhiTransitions {
|
||||||
|
|
||||||
|
/** Label of the to-block. */
|
||||||
|
private ControlFlowBlock toBlock;
|
||||||
|
|
||||||
|
/** The phi-block of the to-block. */
|
||||||
|
private StatementPhiBlock phiBlock;
|
||||||
|
|
||||||
|
public PhiTransition getTransition(LabelRef fromBlock) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A single transition into a to-block.
|
||||||
|
* The transition contains the assignments necessary to enter the to-block from specific from-block(s).
|
||||||
|
* The transition may be shared between multiple from-blocks, if the assignments are identical.
|
||||||
|
*/
|
||||||
|
public class PhiTransition {
|
||||||
|
|
||||||
|
private List<ControlFlowBlock> fromBlocks;
|
||||||
|
|
||||||
|
private boolean generated;
|
||||||
|
|
||||||
|
public List<PhiAssignment> getAssignments() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isGenerated() {
|
||||||
|
return generated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGenerated(boolean generated) {
|
||||||
|
this.generated = generated;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assignment of a single value during a phi transition
|
||||||
|
*/
|
||||||
|
public class PhiAssignment {
|
||||||
|
|
||||||
|
private StatementPhiBlock.PhiVariable phiVariable;
|
||||||
|
|
||||||
|
private StatementPhiBlock.PhiRValue phiRValue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a phi block transition. The transition performs all necessary assignment operations when moving from one block to another.
|
||||||
|
* The transition can be inserted either at the start of the to-block (used for conditional jumps)
|
||||||
|
* or at the end of the from-block ( used at default block transitions and before JMP/JSR)
|
||||||
|
* @param asm The ASP program to generate the transition into.
|
||||||
|
* @param fromBlock The from-block
|
||||||
|
* @param toBlock The to-block
|
||||||
|
* @param scope The scope where the ASM code is being inserted. Used to ensure that labels inserted in the code reference the right variables.
|
||||||
|
* If the transition code is inserted in the to-block, this is the scope of the to-block.
|
||||||
|
* If the transition code is inserted in the from-block this is the scope of the from-block.
|
||||||
|
*/
|
||||||
private void genBlockPhiTransition(AsmProgram asm, ControlFlowBlock fromBlock, ControlFlowBlock toBlock, ScopeRef scope) {
|
private void genBlockPhiTransition(AsmProgram asm, ControlFlowBlock fromBlock, ControlFlowBlock toBlock, ScopeRef scope) {
|
||||||
Statement toFirstStatement = toBlock.getStatements().get(0);
|
Statement toFirstStatement = toBlock.getStatements().get(0);
|
||||||
asm.startSegment(toFirstStatement.getIndex(), "[" + toFirstStatement.getIndex() + "]" + " phi from " + fromBlock.getLabel().getFullName() + " to " + toBlock.getLabel().getFullName());
|
asm.startSegment(toFirstStatement.getIndex(), "[" + toFirstStatement.getIndex() + "]" + " phi from " + fromBlock.getLabel().getFullName() + " to " + toBlock.getLabel().getFullName());
|
||||||
@ -250,6 +324,14 @@ public class Pass4CodeGeneration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate ASM assigning a value (rValue) to a variable (lValue).
|
||||||
|
* @param asm The ASM program to generate into
|
||||||
|
* @param lValue The lValue that should be assigned the value
|
||||||
|
* @param rValue The rValue to assign to the lValue.
|
||||||
|
* @param statement The ICL statement that is the cause of the assignment.
|
||||||
|
* @param scope The scope where the ASM code is being inserted. Used to ensure that labels inserted in the code reference the right variables.
|
||||||
|
*/
|
||||||
private void genAsmMove(AsmProgram asm, LValue lValue, RValue rValue, Statement statement, ScopeRef scope) {
|
private void genAsmMove(AsmProgram asm, LValue lValue, RValue rValue, Statement statement, ScopeRef scope) {
|
||||||
asm.startSegment(statement.getIndex(), "[" + statement.getIndex() + "] phi " + lValue.toString(program) + " = " + rValue.toString(program));
|
asm.startSegment(statement.getIndex(), "[" + statement.getIndex() + "] phi " + lValue.toString(program) + " = " + rValue.toString(program));
|
||||||
if (isRegisterCopy(lValue, rValue)) {
|
if (isRegisterCopy(lValue, rValue)) {
|
||||||
|
@ -44,6 +44,10 @@ public class TestCompilationOutput extends TestCase {
|
|||||||
compileAndCompare("bresenham");
|
compileAndCompare("bresenham");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testBresenhamArr() throws IOException, URISyntaxException {
|
||||||
|
compileAndCompare("bresenhamarr");
|
||||||
|
}
|
||||||
|
|
||||||
public void testMinus() throws IOException, URISyntaxException {
|
public void testMinus() throws IOException, URISyntaxException {
|
||||||
compileAndCompare("minus");
|
compileAndCompare("minus");
|
||||||
}
|
}
|
||||||
|
47
src/main/java/dk/camelot64/kickc/test/ref/bresenhamarr.asm
Normal file
47
src/main/java/dk/camelot64/kickc/test/ref/bresenhamarr.asm
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
.label idx = 2
|
||||||
|
.label y = 4
|
||||||
|
lda #$0
|
||||||
|
sta y
|
||||||
|
ldy #$c
|
||||||
|
ldx #$0
|
||||||
|
lda #$0
|
||||||
|
sta idx
|
||||||
|
lda #$0
|
||||||
|
sta idx+$1
|
||||||
|
b1:
|
||||||
|
lda #<$400
|
||||||
|
clc
|
||||||
|
adc idx
|
||||||
|
sta !s++$1
|
||||||
|
lda #>$400
|
||||||
|
adc idx+$1
|
||||||
|
sta !s++$2
|
||||||
|
lda #$51
|
||||||
|
!s:
|
||||||
|
sta $400
|
||||||
|
inx
|
||||||
|
inc idx
|
||||||
|
bne !+
|
||||||
|
inc idx+$1
|
||||||
|
!:
|
||||||
|
tya
|
||||||
|
clc
|
||||||
|
adc #$18
|
||||||
|
tay
|
||||||
|
cpy #$27
|
||||||
|
bcc b2
|
||||||
|
inc y
|
||||||
|
lda idx
|
||||||
|
clc
|
||||||
|
adc #<$28
|
||||||
|
sta idx
|
||||||
|
bcc !+
|
||||||
|
inc idx+$1
|
||||||
|
!:
|
||||||
|
tya
|
||||||
|
sec
|
||||||
|
sbc #$27
|
||||||
|
tay
|
||||||
|
b2:
|
||||||
|
cpx #$28
|
||||||
|
bcc b1
|
25
src/main/java/dk/camelot64/kickc/test/ref/bresenhamarr.cfg
Normal file
25
src/main/java/dk/camelot64/kickc/test/ref/bresenhamarr.cfg
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
@begin: scope:[] from
|
||||||
|
to:@1
|
||||||
|
@1: scope:[] from @2 @begin
|
||||||
|
[0] (byte) y#2 ← phi( @2/(byte) y#4 @begin/(byte) 0 ) [ idx#3 x#2 e#3 y#2 ]
|
||||||
|
[0] (byte) e#3 ← phi( @2/(byte) e#5 @begin/(byte) 12 ) [ idx#3 x#2 e#3 y#2 ]
|
||||||
|
[0] (byte) x#2 ← phi( @2/(byte) x#1 @begin/(byte) 0 ) [ idx#3 x#2 e#3 y#2 ]
|
||||||
|
[0] (word) idx#3 ← phi( @2/(word) idx#5 @begin/(byte) 0 ) [ idx#3 x#2 e#3 y#2 ]
|
||||||
|
[1] *((word) 1024 + (word) idx#3) ← (byte) 81 [ idx#3 x#2 e#3 y#2 ]
|
||||||
|
[2] (byte) x#1 ← (byte) x#2 + (byte) 1 [ x#1 idx#3 e#3 y#2 ]
|
||||||
|
[3] (word) idx#1 ← (word) idx#3 + (byte) 1 [ x#1 e#3 y#2 idx#1 ]
|
||||||
|
[4] (byte) e#1 ← (byte) e#3 + (byte) 24 [ x#1 e#1 y#2 idx#1 ]
|
||||||
|
[5] if((byte) 39>=(byte) e#1) goto @2 [ x#1 e#1 y#2 idx#1 ]
|
||||||
|
to:@3
|
||||||
|
@3: scope:[] from @1
|
||||||
|
[6] (byte) y#1 ← (byte) y#2 + (byte) 1 [ x#1 e#1 idx#1 y#1 ]
|
||||||
|
[7] (word) idx#2 ← (word) idx#1 + (byte) 40 [ x#1 e#1 idx#2 y#1 ]
|
||||||
|
[8] (byte) e#2 ← (byte) e#1 - (byte) 39 [ x#1 idx#2 e#2 y#1 ]
|
||||||
|
to:@2
|
||||||
|
@2: scope:[] from @1 @3
|
||||||
|
[9] (byte) y#4 ← phi( @1/(byte) y#2 @3/(byte) y#1 ) [ idx#5 x#1 e#5 y#4 ]
|
||||||
|
[9] (byte) e#5 ← phi( @1/(byte) e#1 @3/(byte) e#2 ) [ idx#5 x#1 e#5 y#4 ]
|
||||||
|
[9] (word) idx#5 ← phi( @1/(word) idx#1 @3/(word) idx#2 ) [ idx#5 x#1 e#5 y#4 ]
|
||||||
|
[10] if((byte) x#1<(byte) 40) goto @1 [ idx#5 x#1 e#5 y#4 ]
|
||||||
|
to:@end
|
||||||
|
@end: scope:[] from @2
|
1805
src/main/java/dk/camelot64/kickc/test/ref/bresenhamarr.log
Normal file
1805
src/main/java/dk/camelot64/kickc/test/ref/bresenhamarr.log
Normal file
File diff suppressed because it is too large
Load Diff
35
src/main/java/dk/camelot64/kickc/test/ref/bresenhamarr.sym
Normal file
35
src/main/java/dk/camelot64/kickc/test/ref/bresenhamarr.sym
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
(label) @1
|
||||||
|
(label) @2
|
||||||
|
(label) @3
|
||||||
|
(label) @begin
|
||||||
|
(label) @end
|
||||||
|
(byte) STAR
|
||||||
|
(byte) e
|
||||||
|
(byte) e#1 reg byte y 11.0
|
||||||
|
(byte) e#2 reg byte y 22.0
|
||||||
|
(byte) e#3 reg byte y 5.5
|
||||||
|
(byte) e#5 reg byte y 16.5
|
||||||
|
(word) idx
|
||||||
|
(word) idx#1 idx zp ZP_WORD:2 8.25
|
||||||
|
(word) idx#2 idx zp ZP_WORD:2 11.0
|
||||||
|
(word) idx#3 idx zp ZP_WORD:2 11.0
|
||||||
|
(word) idx#5 idx zp ZP_WORD:2 16.5
|
||||||
|
(byte[1000]) screen
|
||||||
|
(byte) x
|
||||||
|
(byte) x#1 reg byte x 3.666666666666667
|
||||||
|
(byte) x#2 reg byte x 11.0
|
||||||
|
(byte) x0
|
||||||
|
(byte) x1
|
||||||
|
(byte) xd
|
||||||
|
(byte) y
|
||||||
|
(byte) y#1 y zp ZP_BYTE:4 7.333333333333333
|
||||||
|
(byte) y#2 y zp ZP_BYTE:4 5.5
|
||||||
|
(byte) y#4 y zp ZP_BYTE:4 16.5
|
||||||
|
(byte) y0
|
||||||
|
(byte) y1
|
||||||
|
(byte) yd
|
||||||
|
|
||||||
|
zp ZP_WORD:2 [ idx#3 idx#5 idx#1 idx#2 ]
|
||||||
|
reg byte x [ x#2 x#1 ]
|
||||||
|
reg byte y [ e#3 e#5 e#1 e#2 ]
|
||||||
|
zp ZP_BYTE:4 [ y#2 y#4 y#1 ]
|
Loading…
x
Reference in New Issue
Block a user