1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-08-02 09:29:35 +00:00

Started work on phi transition optimization

This commit is contained in:
jespergravgaard 2017-08-23 09:37:16 +02:00
parent f72585e3c0
commit 23d9af8420
6 changed files with 1999 additions and 1 deletions

View File

@ -10,7 +10,6 @@ import java.util.*;
*/
public class Pass4CodeGeneration {
private 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) {
Statement toFirstStatement = toBlock.getStatements().get(0);
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) {
asm.startSegment(statement.getIndex(), "[" + statement.getIndex() + "] phi " + lValue.toString(program) + " = " + rValue.toString(program));
if (isRegisterCopy(lValue, rValue)) {

View File

@ -44,6 +44,10 @@ public class TestCompilationOutput extends TestCase {
compileAndCompare("bresenham");
}
public void testBresenhamArr() throws IOException, URISyntaxException {
compileAndCompare("bresenhamarr");
}
public void testMinus() throws IOException, URISyntaxException {
compileAndCompare("minus");
}

View 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

View 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

File diff suppressed because it is too large Load Diff

View 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 ]