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

Implemented boolean && /

This commit is contained in:
jespergravgaard 2018-04-21 23:00:05 +02:00
parent 8a7f5bde39
commit b2f1e1abe3
19 changed files with 2350 additions and 518 deletions

View File

@ -179,6 +179,7 @@ public class Compiler {
optimizations.add(new Pass2SelfPhiElimination(program));
optimizations.add(new Pass2RedundantPhiElimination(program));
optimizations.add(new Pass2ConditionalJumpSimplification(program));
optimizations.add(new Pass2ConditionalAndOrRewriting(program));
optimizations.add(new Pass2ConstantIdentification(program));
optimizations.add(new Pass2ConstantAdditionElimination(program));
optimizations.add(new Pass2ConstantIfs(program));
@ -186,7 +187,6 @@ public class Compiler {
optimizations.add(new Pass2TypeInference(program));
optimizations.add(new PassNEliminateUnusedVars(program));
optimizations.add(new Pass2NopCastElimination(program));
//optimizations.add(new Pass2ConstantIfs(program));
optimizations.add(new Pass2EliminateUnusedBlocks(program));
pass2OptimizeSSA(optimizations);

View File

@ -297,8 +297,6 @@ public class AsmFragmentInstanceSpec {
return "vds";
} else if(SymbolType.STRING.equals(type)) {
return "pbu";
} else if(SymbolType.BOOLEAN.equals(type)) {
return "vbo";
} else if(type instanceof SymbolTypePointer) {
SymbolType elementType = ((SymbolTypePointer) type).getElementType();
if(SymbolType.isByte(elementType)) {
@ -328,8 +326,7 @@ public class AsmFragmentInstanceSpec {
if(
Registers.RegisterType.ZP_BYTE.equals(register.getType()) ||
Registers.RegisterType.ZP_WORD.equals(register.getType()) ||
Registers.RegisterType.ZP_DWORD.equals(register.getType()) ||
Registers.RegisterType.ZP_BOOL.equals(register.getType())
Registers.RegisterType.ZP_DWORD.equals(register.getType())
) {
// Examine if the ZP register is already bound
Registers.RegisterZp registerZp = (Registers.RegisterZp) register;

View File

@ -0,0 +1,144 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.ControlFlowBlock;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.operators.Operators;
import dk.camelot64.kickc.model.statements.Statement;
import dk.camelot64.kickc.model.statements.StatementAssignment;
import dk.camelot64.kickc.model.statements.StatementConditionalJump;
import dk.camelot64.kickc.model.symbols.Label;
import dk.camelot64.kickc.model.symbols.Scope;
import dk.camelot64.kickc.model.values.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* Compiler Pass rewriting conditional jumps that use && or || operators
*/
public class Pass2ConditionalAndOrRewriting extends Pass2SsaOptimization {
public Pass2ConditionalAndOrRewriting(Program program) {
super(program);
}
@Override
public boolean step() {
VariableRef obsoleteConditionVar = findAndRewriteBooleanCondition();
if(obsoleteConditionVar!=null) {
Collection<VariableRef> obsoleteVars = new ArrayList<>();
obsoleteVars.add(obsoleteConditionVar);
removeAssignments(obsoleteVars);
deleteSymbols(obsoleteVars);
return true;
} else {
return false;
}
}
/**
* Look through the entire program looking for an if() condition that uses &&, || or !.
* When found rewrite it (adding blocks)
* @return Null if no condition was found to rewrite. The now obsolete variable containing the && / || / ! to be removed.
*/
private VariableRef findAndRewriteBooleanCondition() {
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
final Map<LValue, StatementAssignment> assignments = getAllAssignments();
final Map<RValue, List<Statement>> usages = getAllUsages();
for(Statement statement : block.getStatements()) {
if(statement instanceof StatementConditionalJump) {
StatementConditionalJump conditional = (StatementConditionalJump) statement;
if(conditional.getrValue1()==null && conditional.getOperator()==null) {
RValue conditionRValue = conditional.getrValue2();
if(conditionRValue instanceof VariableRef && usages.get(conditionRValue).size() == 1) {
VariableRef conditionVar = (VariableRef) conditionRValue;
StatementAssignment conditionAssignment = assignments.get(conditionVar);
if(Operators.LOGIC_AND.equals(conditionAssignment.getOperator())) {
// Found if() with logical && condition - rewrite to if(c1) if(c2) { xx }
rewriteLogicAnd(block, conditional, conditionAssignment);
return conditionVar;
} else if(Operators.LOGIC_OR.equals(conditionAssignment.getOperator())) {
// Found if() with logical || condition - rewrite to if(c1) goto x else if(c2) goto x else goto end, x:{ xx } end:
rewriteLogicOr(block, conditional, conditionAssignment);
return conditionVar;
} else if(Operators.LOGIC_NOT.equals(conditionAssignment.getOperator())) {
// Found if() with logical ! condition - rewrite to if(!c1) goto x else goto end, x:{ xx } end:
rewriteLogicNot(block, conditional, conditionAssignment);
return conditionVar;
}
}
}
}
}
}
return null;
}
/**
* Rewrite logical && condition if(c1&&c2) { xx } to if(c1) if(c2) { xx }
* @param block The block containing the current if()
* @param conditional The if()-statement
* @param conditionAssignment The assignment defining the condition variable.
*/
private void rewriteLogicAnd(ControlFlowBlock block, StatementConditionalJump conditional, StatementAssignment conditionAssignment) {
// Found an if with a logical && condition - rewrite to if(c1) if(c2) { xx }
getLog().append("Rewriting && if()-condition to two if()s "+conditionAssignment.toString(getProgram(), false));
ScopeRef currentScopeRef = block.getScope();
Scope currentScope = getScope().getScope(currentScopeRef);
// Add a new block containing the second part of the && condition expression
Label newBlockLabel = currentScope.addLabelIntermediate();
ControlFlowBlock newBlock = new ControlFlowBlock(newBlockLabel.getRef(), currentScopeRef);
getGraph().addBlock(newBlock);
newBlock.getStatements().add(new StatementConditionalJump(conditionAssignment.getrValue2(), conditional.getDestination()));
newBlock.setDefaultSuccessor(block.getDefaultSuccessor());
newBlock.setConditionalSuccessor(conditional.getDestination());
// Rewrite the conditional to use only the first part of the && condition expression
conditional.setDestination(newBlockLabel.getRef());
block.setConditionalSuccessor(newBlockLabel.getRef());
conditional.setrValue2(conditionAssignment.getrValue1());
}
/**
* Rewrite logical || condition if(c1&&c2) { xx } to if(c1) goto x else if(c2) goto x else goto end, x:{ xx } end:
* @param block The block containing the current if()
* @param conditional The if()-statement
* @param conditionAssignment The assignment defining the condition variable.
*/
private void rewriteLogicOr(ControlFlowBlock block, StatementConditionalJump conditional, StatementAssignment conditionAssignment) {
getLog().append("Rewriting || if()-condition to two if()s "+conditionAssignment.toString(getProgram(), false));
ScopeRef currentScopeRef = block.getScope();
Scope currentScope = getScope().getScope(currentScopeRef);
// Add a new block containing the second part of the && condition expression
Label newBlockLabel = currentScope.addLabelIntermediate();
ControlFlowBlock newBlock = new ControlFlowBlock(newBlockLabel.getRef(), currentScopeRef);
getGraph().addBlock(newBlock);
newBlock.getStatements().add(new StatementConditionalJump(conditionAssignment.getrValue2(), conditional.getDestination()));
newBlock.setConditionalSuccessor(conditional.getDestination());
newBlock.setDefaultSuccessor(block.getDefaultSuccessor());
// Rewrite the conditional to use only the first part of the && condition expression
block.setDefaultSuccessor(newBlockLabel.getRef());
conditional.setrValue2(conditionAssignment.getrValue1());
}
/**
* Rewrite logical ! condition if(!c1) { xx } to if(c1) goto end else goto x, x:{ xx } end:
* @param block The block containing the current if()
* @param conditional The if()-statement
* @param conditionAssignment The assignment defining the condition variable.
*/
private void rewriteLogicNot(ControlFlowBlock block, StatementConditionalJump conditional, StatementAssignment conditionAssignment) {
getLog().append("Rewriting ! if()-condition to reversed if() "+conditionAssignment.toString(getProgram(), false));
// Rewrite the conditional to use only the first part of the && condition expression
LabelRef defaultSuccessor = block.getDefaultSuccessor();
LabelRef conditionalSuccessor = block.getConditionalSuccessor();
// Change condition (to the non-negated condition)
conditional.setrValue2(conditionAssignment.getrValue2());
// Swap successors
conditional.setDestination(defaultSuccessor);
block.setConditionalSuccessor(defaultSuccessor);
block.setDefaultSuccessor(conditionalSuccessor);
}
}

View File

@ -21,9 +21,6 @@ public class Pass2ConditionalJumpSimplification extends Pass2SsaOptimization {
super(program);
}
/**
* Eliminate alias assignments replacing them with the aliased variable.
*/
@Override
public boolean step() {
final Map<LValue, StatementAssignment> assignments = getAllAssignments();

View File

@ -53,9 +53,6 @@ public class Pass4RegisterUpliftPotentialInitialize extends Pass2Base {
potentials.add(Registers.getRegisterX());
potentials.add(Registers.getRegisterY());
}
if(registerType.equals(Registers.RegisterType.ZP_BOOL) && !varRefExtracted(equivalenceClass)) {
potentials.add(Registers.getRegisterA());
}
registerPotentials.setPotentialRegisters(equivalenceClass, potentials);
}
}

View File

@ -1,14 +1,16 @@
// A Minimal test of boolean variables.
// Boolean variables are bytes under the hood
// 0: false, !=0 : true
const byte* screen = $400;
// A test of boolean conditions using && || and !
void main() {
bool_and();
bool_or();
bool_not();
bool_complex();
}
void bool_and() {
const byte* screen = $400;
for( byte i : 0..20) {
boolean o1 = i<10;
boolean o2 = (i&1)==0;
if( o1 && o2 ) {
if( (i<10) && ((i&1)==0) ) {
screen[i] = '*';
} else {
screen[i] = ' ';
@ -16,3 +18,37 @@ void main() {
}
}
void bool_or() {
const byte* screen = $428;
for( byte i : 0..20) {
if( (i<10) || ((i&1)==0) ) {
screen[i] = '*';
} else {
screen[i] = ' ';
}
}
}
void bool_not() {
const byte* screen = $450;
for( byte i : 0..20) {
boolean o1 = (i&1)==0;
if( !((i<10) || ((i&1)==0)) ) {
screen[i] = '*';
} else {
screen[i] = ' ';
}
}
}
void bool_complex() {
const byte* screen = $478;
for( byte i : 0..20) {
boolean o1 = (i&1)==0;
if( ((i<10) && ((i&1)==0)) || !((i<10) || ((i&1)==0)) ) {
screen[i] = '*';
} else {
screen[i] = ' ';
}
}
}

View File

@ -424,6 +424,22 @@ Alias (boolean) bool_const_vars::b1#0 = (boolean~) bool_const_vars::$3
Alias (boolean) bool_const_vars::b2#0 = (boolean~) bool_const_vars::$7
Alias (boolean) bool_const_vars::b#0 = (boolean~) bool_const_vars::$10
Succesful SSA optimization Pass2AliasElimination
Rewriting || if()-condition to two if()s (boolean) bool_const_vars::b#0 ← (boolean~) bool_const_vars::$9 || false
Succesful SSA optimization Pass2ConditionalAndOrRewriting
Rewriting && if()-condition to two if()s (boolean~) bool_const_vars::$9 ← (boolean) bool_const_vars::b1#0 && (boolean~) bool_const_vars::$8
Succesful SSA optimization Pass2ConditionalAndOrRewriting
Rewriting || if()-condition to two if()s (boolean) bool_const_vars::b1#0 ← (boolean~) bool_const_vars::$0 || (boolean~) bool_const_vars::$2
Succesful SSA optimization Pass2ConditionalAndOrRewriting
Rewriting || if()-condition to two if()s (boolean~) bool_const_inline::$8 ← (boolean~) bool_const_inline::$5 || (boolean~) bool_const_inline::$7
Succesful SSA optimization Pass2ConditionalAndOrRewriting
Rewriting || if()-condition to two if()s (boolean~) bool_const_inline::$5 ← (boolean~) bool_const_inline::$0 || (boolean~) bool_const_inline::$4
Succesful SSA optimization Pass2ConditionalAndOrRewriting
Rewriting ! if()-condition to reversed if() (boolean~) bool_const_vars::$8 ← ! (boolean) bool_const_vars::b2#0
Succesful SSA optimization Pass2ConditionalAndOrRewriting
Rewriting || if()-condition to two if()s (boolean) bool_const_vars::b2#0 ← (boolean~) bool_const_vars::$4 || (boolean~) bool_const_vars::$6
Succesful SSA optimization Pass2ConditionalAndOrRewriting
Rewriting && if()-condition to two if()s (boolean~) bool_const_inline::$4 ← (boolean~) bool_const_inline::$2 && (boolean~) bool_const_inline::$3
Succesful SSA optimization Pass2ConditionalAndOrRewriting
Constant (const byte*) SCREEN#0 = ((byte*))1024
Constant (const boolean) bool_const_if::b#0 = true
Constant (const byte) bool_const_vars::a#0 = 14
@ -440,18 +456,6 @@ Constant (const boolean) bool_const_inline::$2 = bool_const_inline::a#0>=bool_co
Constant (const boolean) bool_const_inline::$3 = bool_const_inline::a#0==15
Constant (const boolean) bool_const_inline::$7 = 21>=bool_const_inline::a#0
Succesful SSA optimization Pass2ConstantIdentification
Constant (const boolean) bool_const_vars::b1#0 = bool_const_vars::$0||bool_const_vars::$2
Constant (const boolean) bool_const_vars::b2#0 = bool_const_vars::$4||bool_const_vars::$6
Constant (const boolean) bool_const_inline::$4 = bool_const_inline::$2&&bool_const_inline::$3
Succesful SSA optimization Pass2ConstantIdentification
Constant (const boolean) bool_const_vars::$8 = !bool_const_vars::b2#0
Constant (const boolean) bool_const_inline::$5 = bool_const_inline::$0||bool_const_inline::$4
Succesful SSA optimization Pass2ConstantIdentification
Constant (const boolean) bool_const_vars::$9 = bool_const_vars::b1#0&&bool_const_vars::$8
Constant (const boolean) bool_const_inline::$8 = bool_const_inline::$5||bool_const_inline::$7
Succesful SSA optimization Pass2ConstantIdentification
Constant (const boolean) bool_const_vars::b#0 = bool_const_vars::$9||false
Succesful SSA optimization Pass2ConstantIdentification
Consolidated array index constant in *(SCREEN#0+0)
Consolidated array index constant in *(SCREEN#0+0)
Consolidated array index constant in *(SCREEN#0+1)
@ -460,40 +464,43 @@ Consolidated array index constant in *(SCREEN#0+2)
Consolidated array index constant in *(SCREEN#0+2)
Succesful SSA optimization Pass2ConstantAdditionElimination
if() condition always true - replacing block destination if((const boolean) bool_const_if::b#0) goto bool_const_if::@1
if() condition always false - eliminating if((const boolean) bool_const_vars::b#0) goto bool_const_vars::@1
if() condition always true - replacing block destination if((const boolean) bool_const_inline::$8) goto bool_const_inline::@1
if() condition always false - eliminating if((const boolean) bool_const_vars::$0) goto bool_const_vars::@6
if() condition always true - replacing block destination if((const boolean) bool_const_inline::$0) goto bool_const_inline::@1
if() condition always false - eliminating if(false) goto bool_const_vars::@1
if() condition always true - replacing block destination if((const boolean) bool_const_vars::$4) goto bool_const_vars::@5
if() condition always true - replacing block destination if((const boolean) bool_const_vars::$2) goto bool_const_vars::@6
if() condition always false - eliminating if((const boolean) bool_const_inline::$7) goto bool_const_inline::@1
if() condition always true - replacing block destination if((const boolean) bool_const_inline::$2) goto bool_const_inline::@7
if() condition always true - replacing block destination if((const boolean) bool_const_vars::$6) goto bool_const_vars::@5
if() condition always false - eliminating if((const boolean) bool_const_inline::$3) goto bool_const_inline::@1
Succesful SSA optimization Pass2ConstantIfs
Eliminating unused constant (const boolean) bool_const_if::b#0
Eliminating unused constant (const boolean) bool_const_vars::b#0
Eliminating unused constant (const boolean) bool_const_inline::$8
Succesful SSA optimization PassNEliminateUnusedVars
Eliminating unused constant (const boolean) bool_const_vars::$9
Eliminating unused constant (const boolean) bool_const_inline::$7
Eliminating unused constant (const boolean) bool_const_inline::$5
Succesful SSA optimization PassNEliminateUnusedVars
Eliminating unused constant (const boolean) bool_const_vars::b1#0
Eliminating unused constant (const boolean) bool_const_vars::$8
Eliminating unused constant (const boolean) bool_const_inline::$0
Eliminating unused constant (const boolean) bool_const_inline::$4
Succesful SSA optimization PassNEliminateUnusedVars
Eliminating unused constant (const boolean) bool_const_vars::$0
Eliminating unused constant (const boolean) bool_const_vars::$2
Eliminating unused constant (const boolean) bool_const_vars::b2#0
Eliminating unused constant (const boolean) bool_const_inline::$2
Eliminating unused constant (const boolean) bool_const_inline::$3
Succesful SSA optimization PassNEliminateUnusedVars
Eliminating unused constant (const boolean) bool_const_vars::$4
Eliminating unused constant (const boolean) bool_const_vars::$6
Eliminating unused constant (const byte) bool_const_inline::a#0
Eliminating unused constant (const signed byte/signed word/signed dword) bool_const_inline::$1
Eliminating unused constant (const boolean) bool_const_inline::$0
Eliminating unused constant (const boolean) bool_const_inline::$2
Eliminating unused constant (const boolean) bool_const_inline::$3
Eliminating unused constant (const boolean) bool_const_inline::$7
Succesful SSA optimization PassNEliminateUnusedVars
Eliminating unused constant (const byte) bool_const_vars::a#0
Eliminating unused constant (const signed byte/signed word/signed dword) bool_const_vars::$5
Eliminating unused constant (const byte) bool_const_inline::a#0
Eliminating unused constant (const signed byte/signed word/signed dword) bool_const_inline::$1
Succesful SSA optimization PassNEliminateUnusedVars
Removing unused block bool_const_if::@3
Removing unused block bool_const_vars::@1
Removing unused block bool_const_inline::@3
Removing unused block bool_const_inline::@5
Removing unused block bool_const_inline::@6
Removing unused block bool_const_vars::@8
Removing unused block bool_const_inline::@7
Succesful SSA optimization Pass2EliminateUnusedBlocks
Culled Empty Block (label) bool_const_vars::@5
Culled Empty Block (label) bool_const_vars::@6
Culled Empty Block (label) bool_const_vars::@7
Succesful SSA optimization Pass2CullEmptyBlocks
OPTIMIZING CONTROL FLOW GRAPH
Block Sequence Planned @begin @4 @end main main::@1 main::@2 main::@return bool_const_inline bool_const_inline::@1 bool_const_inline::@return bool_const_vars bool_const_vars::@3 bool_const_vars::@return bool_const_if bool_const_if::@1 bool_const_if::@return
Block Sequence Planned @begin @4 @end main main::@1 main::@2 main::@return bool_const_inline bool_const_inline::@1 bool_const_inline::@return bool_const_vars bool_const_vars::@3 bool_const_vars::@return bool_const_if bool_const_if::@1 bool_const_if::@return

View File

@ -1,32 +1,79 @@
.pc = $801 "Basic"
:BasicUpstart(main)
.pc = $80d "Program"
.label screen = $400
jsr main
main: {
.label o1 = 2
jsr bool_and
jsr bool_or
jsr bool_not
jsr bool_complex
rts
}
bool_complex: {
.label screen = $478
ldy #0
b1:
tya
and #1
tax
tya
and #1
cpy #$a
bcc b8
b7:
cpy #$a
bcc b4
cmp #0
beq b4
b2:
lda #'*'
sta screen,y
b3:
iny
cpy #$15
bne b1
rts
b4:
lda #' '
sta screen,y
jmp b3
b8:
cpx #0
beq b2
jmp b7
}
bool_not: {
.label screen = $450
ldx #0
b1:
cpx #$a
lda #0
rol
eor #1
sta o1
txa
and #1
sec
sbc #0
beq !+
lda #$ff
!:
eor #$ff
cpx #$a
bcc b4
cmp #0
beq !+
lda #$ff
!:
and o1
beq b4
lda #'*'
sta screen,x
b3:
inx
cpx #$15
bne b1
rts
b4:
lda #' '
sta screen,x
jmp b3
}
bool_or: {
.label screen = $428
ldx #0
b1:
txa
and #1
cpx #$a
bcc b2
cmp #0
bne b2
beq b2
lda #' '
sta screen,x
b3:
@ -39,3 +86,28 @@ main: {
sta screen,x
jmp b3
}
bool_and: {
.label screen = $400
ldx #0
b1:
txa
and #1
cpx #$a
bcc b7
b4:
lda #' '
sta screen,x
b3:
inx
cpx #$15
bne b1
rts
b7:
cmp #0
beq b2
jmp b4
b2:
lda #'*'
sta screen,x
jmp b3
}

View File

@ -1,33 +1,131 @@
@begin: scope:[] from
[0] phi() [ ] ( )
to:@1
@1: scope:[] from @begin
to:@5
@5: scope:[] from @begin
[1] phi() [ ] ( )
[2] call main param-assignment [ ] ( )
to:@end
@end: scope:[] from @1
@end: scope:[] from @5
[3] phi() [ ] ( )
main: scope:[main] from @1
main: scope:[main] from @5
[4] phi() [ ] ( main:2 [ ] )
[5] call bool_and param-assignment [ ] ( main:2 [ ] )
to:main::@1
main::@1: scope:[main] from main main::@3
[5] (byte) main::i#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@3/(byte) main::i#1 ) [ main::i#2 ] ( main:2 [ main::i#2 ] )
[6] (boolean) main::o1#0 ← (byte) main::i#2 < (byte/signed byte/word/signed word/dword/signed dword) 10 [ main::i#2 main::o1#0 ] ( main:2 [ main::i#2 main::o1#0 ] )
[7] (byte~) main::$1 ← (byte) main::i#2 & (byte/signed byte/word/signed word/dword/signed dword) 1 [ main::i#2 main::o1#0 main::$1 ] ( main:2 [ main::i#2 main::o1#0 main::$1 ] )
[8] (boolean) main::o2#0 ← (byte~) main::$1 == (byte/signed byte/word/signed word/dword/signed dword) 0 [ main::i#2 main::o1#0 main::o2#0 ] ( main:2 [ main::i#2 main::o1#0 main::o2#0 ] )
[9] (boolean~) main::$3 ← (boolean) main::o1#0 && (boolean) main::o2#0 [ main::i#2 main::$3 ] ( main:2 [ main::i#2 main::$3 ] )
[10] if((boolean~) main::$3) goto main::@2 [ main::i#2 ] ( main:2 [ main::i#2 ] )
to:main::@4
main::@4: scope:[main] from main::@1
[11] *((const byte*) screen#0 + (byte) main::i#2) ← (byte) ' ' [ main::i#2 ] ( main:2 [ main::i#2 ] )
main::@1: scope:[main] from main
[6] phi() [ ] ( main:2 [ ] )
[7] call bool_or param-assignment [ ] ( main:2 [ ] )
to:main::@2
main::@2: scope:[main] from main::@1
[8] phi() [ ] ( main:2 [ ] )
[9] call bool_not param-assignment [ ] ( main:2 [ ] )
to:main::@3
main::@3: scope:[main] from main::@2 main::@4
[12] (byte) main::i#1 ← ++ (byte) main::i#2 [ main::i#1 ] ( main:2 [ main::i#1 ] )
[13] if((byte) main::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 21) goto main::@1 [ main::i#1 ] ( main:2 [ main::i#1 ] )
main::@3: scope:[main] from main::@2
[10] phi() [ ] ( main:2 [ ] )
[11] call bool_complex param-assignment [ ] ( main:2 [ ] )
to:main::@return
main::@return: scope:[main] from main::@3
[14] return [ ] ( main:2 [ ] )
[12] return [ ] ( main:2 [ ] )
to:@return
main::@2: scope:[main] from main::@1
[15] *((const byte*) screen#0 + (byte) main::i#2) ← (byte) '*' [ main::i#2 ] ( main:2 [ main::i#2 ] )
to:main::@3
bool_complex: scope:[bool_complex] from main::@3
[13] phi() [ ] ( main:2::bool_complex:11 [ ] )
to:bool_complex::@1
bool_complex::@1: scope:[bool_complex] from bool_complex bool_complex::@3
[14] (byte) bool_complex::i#2 ← phi( bool_complex/(byte/signed byte/word/signed word/dword/signed dword) 0 bool_complex::@3/(byte) bool_complex::i#1 ) [ bool_complex::i#2 ] ( main:2::bool_complex:11 [ bool_complex::i#2 ] )
[15] (byte~) bool_complex::$3 ← (byte) bool_complex::i#2 & (byte/signed byte/word/signed word/dword/signed dword) 1 [ bool_complex::i#2 bool_complex::$3 ] ( main:2::bool_complex:11 [ bool_complex::i#2 bool_complex::$3 ] )
[16] (byte~) bool_complex::$7 ← (byte) bool_complex::i#2 & (byte/signed byte/word/signed word/dword/signed dword) 1 [ bool_complex::i#2 bool_complex::$3 bool_complex::$7 ] ( main:2::bool_complex:11 [ bool_complex::i#2 bool_complex::$3 bool_complex::$7 ] )
[17] if((byte) bool_complex::i#2<(byte/signed byte/word/signed word/dword/signed dword) 10) goto bool_complex::@8 [ bool_complex::i#2 bool_complex::$3 bool_complex::$7 ] ( main:2::bool_complex:11 [ bool_complex::i#2 bool_complex::$3 bool_complex::$7 ] )
to:bool_complex::@7
bool_complex::@7: scope:[bool_complex] from bool_complex::@1 bool_complex::@8
[18] if((byte) bool_complex::i#2<(byte/signed byte/word/signed word/dword/signed dword) 10) goto bool_complex::@4 [ bool_complex::i#2 bool_complex::$7 ] ( main:2::bool_complex:11 [ bool_complex::i#2 bool_complex::$7 ] )
to:bool_complex::@9
bool_complex::@9: scope:[bool_complex] from bool_complex::@7
[19] if((byte~) bool_complex::$7==(byte/signed byte/word/signed word/dword/signed dword) 0) goto bool_complex::@4 [ bool_complex::i#2 ] ( main:2::bool_complex:11 [ bool_complex::i#2 ] )
to:bool_complex::@2
bool_complex::@2: scope:[bool_complex] from bool_complex::@8 bool_complex::@9
[20] *((const byte*) bool_complex::screen#0 + (byte) bool_complex::i#2) ← (byte) '*' [ bool_complex::i#2 ] ( main:2::bool_complex:11 [ bool_complex::i#2 ] )
to:bool_complex::@3
bool_complex::@3: scope:[bool_complex] from bool_complex::@2 bool_complex::@4
[21] (byte) bool_complex::i#1 ← ++ (byte) bool_complex::i#2 [ bool_complex::i#1 ] ( main:2::bool_complex:11 [ bool_complex::i#1 ] )
[22] if((byte) bool_complex::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 21) goto bool_complex::@1 [ bool_complex::i#1 ] ( main:2::bool_complex:11 [ bool_complex::i#1 ] )
to:bool_complex::@return
bool_complex::@return: scope:[bool_complex] from bool_complex::@3
[23] return [ ] ( main:2::bool_complex:11 [ ] )
to:@return
bool_complex::@4: scope:[bool_complex] from bool_complex::@7 bool_complex::@9
[24] *((const byte*) bool_complex::screen#0 + (byte) bool_complex::i#2) ← (byte) ' ' [ bool_complex::i#2 ] ( main:2::bool_complex:11 [ bool_complex::i#2 ] )
to:bool_complex::@3
bool_complex::@8: scope:[bool_complex] from bool_complex::@1
[25] if((byte~) bool_complex::$3==(byte/signed byte/word/signed word/dword/signed dword) 0) goto bool_complex::@2 [ bool_complex::i#2 bool_complex::$7 ] ( main:2::bool_complex:11 [ bool_complex::i#2 bool_complex::$7 ] )
to:bool_complex::@7
bool_not: scope:[bool_not] from main::@2
[26] phi() [ ] ( main:2::bool_not:9 [ ] )
to:bool_not::@1
bool_not::@1: scope:[bool_not] from bool_not bool_not::@3
[27] (byte) bool_not::i#2 ← phi( bool_not/(byte/signed byte/word/signed word/dword/signed dword) 0 bool_not::@3/(byte) bool_not::i#1 ) [ bool_not::i#2 ] ( main:2::bool_not:9 [ bool_not::i#2 ] )
[28] (byte~) bool_not::$3 ← (byte) bool_not::i#2 & (byte/signed byte/word/signed word/dword/signed dword) 1 [ bool_not::i#2 bool_not::$3 ] ( main:2::bool_not:9 [ bool_not::i#2 bool_not::$3 ] )
[29] if((byte) bool_not::i#2<(byte/signed byte/word/signed word/dword/signed dword) 10) goto bool_not::@4 [ bool_not::i#2 bool_not::$3 ] ( main:2::bool_not:9 [ bool_not::i#2 bool_not::$3 ] )
to:bool_not::@7
bool_not::@7: scope:[bool_not] from bool_not::@1
[30] if((byte~) bool_not::$3==(byte/signed byte/word/signed word/dword/signed dword) 0) goto bool_not::@4 [ bool_not::i#2 ] ( main:2::bool_not:9 [ bool_not::i#2 ] )
to:bool_not::@2
bool_not::@2: scope:[bool_not] from bool_not::@7
[31] *((const byte*) bool_not::screen#0 + (byte) bool_not::i#2) ← (byte) '*' [ bool_not::i#2 ] ( main:2::bool_not:9 [ bool_not::i#2 ] )
to:bool_not::@3
bool_not::@3: scope:[bool_not] from bool_not::@2 bool_not::@4
[32] (byte) bool_not::i#1 ← ++ (byte) bool_not::i#2 [ bool_not::i#1 ] ( main:2::bool_not:9 [ bool_not::i#1 ] )
[33] if((byte) bool_not::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 21) goto bool_not::@1 [ bool_not::i#1 ] ( main:2::bool_not:9 [ bool_not::i#1 ] )
to:bool_not::@return
bool_not::@return: scope:[bool_not] from bool_not::@3
[34] return [ ] ( main:2::bool_not:9 [ ] )
to:@return
bool_not::@4: scope:[bool_not] from bool_not::@1 bool_not::@7
[35] *((const byte*) bool_not::screen#0 + (byte) bool_not::i#2) ← (byte) ' ' [ bool_not::i#2 ] ( main:2::bool_not:9 [ bool_not::i#2 ] )
to:bool_not::@3
bool_or: scope:[bool_or] from main::@1
[36] phi() [ ] ( main:2::bool_or:7 [ ] )
to:bool_or::@1
bool_or::@1: scope:[bool_or] from bool_or bool_or::@3
[37] (byte) bool_or::i#2 ← phi( bool_or/(byte/signed byte/word/signed word/dword/signed dword) 0 bool_or::@3/(byte) bool_or::i#1 ) [ bool_or::i#2 ] ( main:2::bool_or:7 [ bool_or::i#2 ] )
[38] (byte~) bool_or::$1 ← (byte) bool_or::i#2 & (byte/signed byte/word/signed word/dword/signed dword) 1 [ bool_or::i#2 bool_or::$1 ] ( main:2::bool_or:7 [ bool_or::i#2 bool_or::$1 ] )
[39] if((byte) bool_or::i#2<(byte/signed byte/word/signed word/dword/signed dword) 10) goto bool_or::@2 [ bool_or::i#2 bool_or::$1 ] ( main:2::bool_or:7 [ bool_or::i#2 bool_or::$1 ] )
to:bool_or::@7
bool_or::@7: scope:[bool_or] from bool_or::@1
[40] if((byte~) bool_or::$1==(byte/signed byte/word/signed word/dword/signed dword) 0) goto bool_or::@2 [ bool_or::i#2 ] ( main:2::bool_or:7 [ bool_or::i#2 ] )
to:bool_or::@4
bool_or::@4: scope:[bool_or] from bool_or::@7
[41] *((const byte*) bool_or::screen#0 + (byte) bool_or::i#2) ← (byte) ' ' [ bool_or::i#2 ] ( main:2::bool_or:7 [ bool_or::i#2 ] )
to:bool_or::@3
bool_or::@3: scope:[bool_or] from bool_or::@2 bool_or::@4
[42] (byte) bool_or::i#1 ← ++ (byte) bool_or::i#2 [ bool_or::i#1 ] ( main:2::bool_or:7 [ bool_or::i#1 ] )
[43] if((byte) bool_or::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 21) goto bool_or::@1 [ bool_or::i#1 ] ( main:2::bool_or:7 [ bool_or::i#1 ] )
to:bool_or::@return
bool_or::@return: scope:[bool_or] from bool_or::@3
[44] return [ ] ( main:2::bool_or:7 [ ] )
to:@return
bool_or::@2: scope:[bool_or] from bool_or::@1 bool_or::@7
[45] *((const byte*) bool_or::screen#0 + (byte) bool_or::i#2) ← (byte) '*' [ bool_or::i#2 ] ( main:2::bool_or:7 [ bool_or::i#2 ] )
to:bool_or::@3
bool_and: scope:[bool_and] from main
[46] phi() [ ] ( main:2::bool_and:5 [ ] )
to:bool_and::@1
bool_and::@1: scope:[bool_and] from bool_and bool_and::@3
[47] (byte) bool_and::i#2 ← phi( bool_and/(byte/signed byte/word/signed word/dword/signed dword) 0 bool_and::@3/(byte) bool_and::i#1 ) [ bool_and::i#2 ] ( main:2::bool_and:5 [ bool_and::i#2 ] )
[48] (byte~) bool_and::$1 ← (byte) bool_and::i#2 & (byte/signed byte/word/signed word/dword/signed dword) 1 [ bool_and::i#2 bool_and::$1 ] ( main:2::bool_and:5 [ bool_and::i#2 bool_and::$1 ] )
[49] if((byte) bool_and::i#2<(byte/signed byte/word/signed word/dword/signed dword) 10) goto bool_and::@7 [ bool_and::i#2 bool_and::$1 ] ( main:2::bool_and:5 [ bool_and::i#2 bool_and::$1 ] )
to:bool_and::@4
bool_and::@4: scope:[bool_and] from bool_and::@1 bool_and::@7
[50] *((const byte*) bool_and::screen#0 + (byte) bool_and::i#2) ← (byte) ' ' [ bool_and::i#2 ] ( main:2::bool_and:5 [ bool_and::i#2 ] )
to:bool_and::@3
bool_and::@3: scope:[bool_and] from bool_and::@2 bool_and::@4
[51] (byte) bool_and::i#1 ← ++ (byte) bool_and::i#2 [ bool_and::i#1 ] ( main:2::bool_and:5 [ bool_and::i#1 ] )
[52] if((byte) bool_and::i#1!=(byte/signed byte/word/signed word/dword/signed dword) 21) goto bool_and::@1 [ bool_and::i#1 ] ( main:2::bool_and:5 [ bool_and::i#1 ] )
to:bool_and::@return
bool_and::@return: scope:[bool_and] from bool_and::@3
[53] return [ ] ( main:2::bool_and:5 [ ] )
to:@return
bool_and::@7: scope:[bool_and] from bool_and::@1
[54] if((byte~) bool_and::$1==(byte/signed byte/word/signed word/dword/signed dword) 0) goto bool_and::@2 [ bool_and::i#2 ] ( main:2::bool_and:5 [ bool_and::i#2 ] )
to:bool_and::@4
bool_and::@2: scope:[bool_and] from bool_and::@7
[55] *((const byte*) bool_and::screen#0 + (byte) bool_and::i#2) ← (byte) '*' [ bool_and::i#2 ] ( main:2::bool_and:5 [ bool_and::i#2 ] )
to:bool_and::@3

File diff suppressed because it is too large Load Diff

View File

@ -1,26 +1,73 @@
(label) @1
(label) @5
(label) @begin
(label) @end
(void()) bool_and()
(byte~) bool_and::$1 reg byte a 11.0
(label) bool_and::@1
(label) bool_and::@2
(label) bool_and::@3
(label) bool_and::@4
(label) bool_and::@7
(label) bool_and::@return
(byte) bool_and::i
(byte) bool_and::i#1 reg byte x 16.5
(byte) bool_and::i#2 reg byte x 11.0
(byte*) bool_and::screen
(const byte*) bool_and::screen#0 screen = ((byte*))(word/signed word/dword/signed dword) 1024
(void()) bool_complex()
(byte~) bool_complex::$3 reg byte x 7.333333333333333
(byte~) bool_complex::$7 reg byte a 5.5
(label) bool_complex::@1
(label) bool_complex::@2
(label) bool_complex::@3
(label) bool_complex::@4
(label) bool_complex::@7
(label) bool_complex::@8
(label) bool_complex::@9
(label) bool_complex::@return
(byte) bool_complex::i
(byte) bool_complex::i#1 reg byte y 16.5
(byte) bool_complex::i#2 reg byte y 9.777777777777779
(byte*) bool_complex::screen
(const byte*) bool_complex::screen#0 screen = ((byte*))(word/signed word/dword/signed dword) 1144
(void()) bool_not()
(byte~) bool_not::$3 reg byte a 11.0
(label) bool_not::@1
(label) bool_not::@2
(label) bool_not::@3
(label) bool_not::@4
(label) bool_not::@7
(label) bool_not::@return
(byte) bool_not::i
(byte) bool_not::i#1 reg byte x 16.5
(byte) bool_not::i#2 reg byte x 11.0
(byte*) bool_not::screen
(const byte*) bool_not::screen#0 screen = ((byte*))(word/signed word/dword/signed dword) 1104
(void()) bool_or()
(byte~) bool_or::$1 reg byte a 11.0
(label) bool_or::@1
(label) bool_or::@2
(label) bool_or::@3
(label) bool_or::@4
(label) bool_or::@7
(label) bool_or::@return
(byte) bool_or::i
(byte) bool_or::i#1 reg byte x 16.5
(byte) bool_or::i#2 reg byte x 11.0
(byte*) bool_or::screen
(const byte*) bool_or::screen#0 screen = ((byte*))(word/signed word/dword/signed dword) 1064
(void()) main()
(byte~) main::$1 reg byte a 22.0
(boolean~) main::$3 reg byte a 22.0
(label) main::@1
(label) main::@2
(label) main::@3
(label) main::@4
(label) main::@return
(byte) main::i
(byte) main::i#1 reg byte x 16.5
(byte) main::i#2 reg byte x 8.25
(boolean) main::o1
(boolean) main::o1#0 o1 zp ZP_BOOL:2 7.333333333333333
(boolean) main::o2
(boolean) main::o2#0 reg byte a 22.0
(byte*) screen
(const byte*) screen#0 screen = ((byte*))(word/signed word/dword/signed dword) 1024
reg byte x [ main::i#2 main::i#1 ]
zp ZP_BOOL:2 [ main::o1#0 ]
reg byte a [ main::$1 ]
reg byte a [ main::o2#0 ]
reg byte a [ main::$3 ]
reg byte y [ bool_complex::i#2 bool_complex::i#1 ]
reg byte x [ bool_not::i#2 bool_not::i#1 ]
reg byte x [ bool_or::i#2 bool_or::i#1 ]
reg byte x [ bool_and::i#2 bool_and::i#1 ]
reg byte x [ bool_complex::$3 ]
reg byte a [ bool_complex::$7 ]
reg byte a [ bool_not::$3 ]
reg byte a [ bool_or::$1 ]
reg byte a [ bool_and::$1 ]