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

Refactored recursive value replacement into ValueReplacer. Moved VariableReplacer to a simple ValueReplacer. Added test for true inline word constructors.

This commit is contained in:
jespergravgaard 2017-12-27 13:40:55 +01:00
parent a3a7d02cd7
commit 8a1dbc36d7
27 changed files with 2775 additions and 1564 deletions

View File

@ -125,7 +125,6 @@ public class Compiler {
new Pass1EliminateUncalledProcedures(program).execute(); new Pass1EliminateUncalledProcedures(program).execute();
new Pass1EliminateUnusedVars(program).execute(); new Pass1EliminateUnusedVars(program).execute();
new Pass1ExtractInlineStrings(program).execute(); new Pass1ExtractInlineStrings(program).execute();
new Pass1FixWordConstructors(program).execute();
new Pass1EliminateEmptyBlocks(program).execute(); new Pass1EliminateEmptyBlocks(program).execute();
getLog().append("CONTROL FLOW GRAPH"); getLog().append("CONTROL FLOW GRAPH");
@ -181,6 +180,7 @@ public class Compiler {
optimizations.add(new Pass2ConditionalJumpSimplification(program)); optimizations.add(new Pass2ConditionalJumpSimplification(program));
optimizations.add(new Pass2ConstantIdentification(program)); optimizations.add(new Pass2ConstantIdentification(program));
optimizations.add(new Pass2ConstantAdditionElimination(program)); optimizations.add(new Pass2ConstantAdditionElimination(program));
optimizations.add(new Pass2FixWordConstructors(program));
pass2OptimizeSSA(optimizations); pass2OptimizeSSA(optimizations);
// Constant inlining optimizations - as the last step to ensure that constant identification has been completed // Constant inlining optimizations - as the last step to ensure that constant identification has been completed

View File

@ -20,7 +20,7 @@ import java.util.regex.Pattern;
*/ */
public class AsmFragmentManager { public class AsmFragmentManager {
static boolean verboseFragmentLog = true; static boolean verboseFragmentLog = false;
/** /**
* Cache for fragment files. Maps signature to the parsed file. * Cache for fragment files. Maps signature to the parsed file.
@ -155,33 +155,33 @@ public class AsmFragmentManager {
synths.add(new FragmentSynthesis("(.*)=_deref_vwuc1(.*)", ".*=.*aa.*", "lda {c1}\n", "$1=vbuaa$2", null, mapC)); synths.add(new FragmentSynthesis("(.*)=_deref_vwuc1(.*)", ".*=.*aa.*", "lda {c1}\n", "$1=vbuaa$2", null, mapC));
synths.add(new FragmentSynthesis("(.*)=_deref_pb(.)z1(.*)", ".*z1.*z1.*|.*=.*aa.*|.*=.*yy.*", "ldy #0\n" + "lda ({z1}),y\n", "$1=vb$2aa$3", null, mapZ)); synths.add(new FragmentSynthesis("(.*)=_deref_pb(.)z1(.*)", ".*z1.*z1.*|.*=.*aa.*|.*=.*yy.*", "ldy #0\n" + "lda ({z1}),y\n", "$1=vb$2aa$3", null, mapZ));
synths.add(new FragmentSynthesis("(.*)=(.*)pb(.)c1_derefidx_vbuxx(.*)", ".*=.*aa.*|.*c1.*c1.*", "lda {c1},x\n", "$1=$2vb$3aa$4", null, mapC)); // Convert array indexing with A register to X/Y register by prefixing tax/tay (..._derefidx_vbuaa... -> ..._derefidx_vbuxx... /... _derefidx_vbuyy... )
synths.add(new FragmentSynthesis("(.*)=(.*c1.*)pb(.)c1_derefidx_vbuxx(.*)", ".*=.*aa.*", "lda {c1},x\n", "$1=$2vb$3aa$4", null, null));
synths.add(new FragmentSynthesis("(.*)=(.*)pb(.)c1_derefidx_vbuxx(.*c1.*)", ".*=.*aa.*", "lda {c1},x\n", "$1=$2vb$3aa$4", null, null));
synths.add(new FragmentSynthesis("(.*)=(.*)pb(.)c1_derefidx_vbuyy(.*)", ".*=.*aa.*|.*c1.*c1.*", "lda {c1},y\n", "$1=$2vb$3aa$4", null, mapC));
synths.add(new FragmentSynthesis("(.*)=(.*c1.*)pb(.)c1_derefidx_vbuyy(.*)", ".*=.*aa.*", "lda {c1},y\n", "$1=$2vb$3aa$4", null, null));
synths.add(new FragmentSynthesis("(.*)=(.*)pb(.)c1_derefidx_vbuyy(.*c1.*)", ".*=.*aa.*", "lda {c1},y\n", "$1=$2vb$3aa$4", null, null));
synths.add(new FragmentSynthesis("(.*)=(.*)pb(.)c2_derefidx_vbuxx(.*)", ".*=.*aa.*|.*c2.*c2.*", "lda {c2},x\n", "$1=$2vb$3aa$4", null, mapC3));
synths.add(new FragmentSynthesis("(.*)=(.*c2.*)pb(.)c2_derefidx_vbuxx(.*)", ".*=.*aa.*", "lda {c2},x\n", "$1=$2vb$3aa$4", null, null));
synths.add(new FragmentSynthesis("(.*)=(.*)pb(.)c2_derefidx_vbuxx(.*c2.*)", ".*=.*aa.*", "lda {c2},x\n", "$1=$2vb$3aa$4", null, null));
synths.add(new FragmentSynthesis("(.*)=(.*)pb(.)c2_derefidx_vbuyy(.*)", ".*=.*aa.*|.*c2.*c2.*", "lda {c2},y\n", "$1=$2vb$3aa$4", null, mapC3));
synths.add(new FragmentSynthesis("(.*)=(.*c2.*)pb(.)c2_derefidx_vbuyy(.*)", ".*=.*aa.*", "lda {c2},y\n", "$1=$2vb$3aa$4", null, null));
synths.add(new FragmentSynthesis("(.*)=(.*)pb(.)c2_derefidx_vbuyy(.*c2.*)", ".*=.*aa.*", "lda {c2},y\n", "$1=$2vb$3aa$4", null, null));
synths.add(new FragmentSynthesis("(.*)=(.*)_derefidx_vbuaa(.*)", ".*=.*xx.*", "tax\n", "$1=$2_derefidx_vbuxx$3", null, null)); synths.add(new FragmentSynthesis("(.*)=(.*)_derefidx_vbuaa(.*)", ".*=.*xx.*", "tax\n", "$1=$2_derefidx_vbuxx$3", null, null));
synths.add(new FragmentSynthesis("(.*)=(.*)_derefidx_vbuaa(.*)", ".*=.*yy.*", "tay\n", "$1=$2_derefidx_vbuyy$3", null, null)); synths.add(new FragmentSynthesis("(.*)=(.*)_derefidx_vbuaa(.*)", ".*=.*yy.*", "tay\n", "$1=$2_derefidx_vbuyy$3", null, null));
// Convert array indexing with zero page to x/y register by prefixing ldx z1 / ldy z1 ( ..._derefidx_vbuzn... -> ..._derefidx_vbuxx... / ..._derefidx_vbuyy... )
synths.add(new FragmentSynthesis("(.*)=(.*)_derefidx_vbuz1(.*)", ".*=.*xx.*|.*z1.*z1.*", "ldx {z1}\n", "$1=$2_derefidx_vbuxx$3", null, mapZ)); synths.add(new FragmentSynthesis("(.*)=(.*)_derefidx_vbuz1(.*)", ".*=.*xx.*|.*z1.*z1.*", "ldx {z1}\n", "$1=$2_derefidx_vbuxx$3", null, mapZ));
synths.add(new FragmentSynthesis("(.*)=(.*)_derefidx_vbuz1(.*)", ".*=.*yy.*|.*z1.*z1.*", "ldy {z1}\n", "$1=$2_derefidx_vbuyy$3", null, mapZ)); synths.add(new FragmentSynthesis("(.*)=(.*)_derefidx_vbuz1(.*)", ".*=.*yy.*|.*z1.*z1.*", "ldy {z1}\n", "$1=$2_derefidx_vbuyy$3", null, mapZ));
synths.add(new FragmentSynthesis("(.*)=(.*)_derefidx_vbuz2(.*)", ".*=.*xx.*|.*z2.*z2.*", "ldx {z2}\n", "$1=$2_derefidx_vbuxx$3", null, mapZ3)); synths.add(new FragmentSynthesis("(.*)=(.*)_derefidx_vbuz2(.*)", ".*=.*xx.*|.*z2.*z2.*", "ldx {z2}\n", "$1=$2_derefidx_vbuxx$3", null, mapZ3));
synths.add(new FragmentSynthesis("(.*)=(.*)_derefidx_vbuz2(.*)", ".*=.*yy.*|.*z2.*z2.*", "ldy {z2}\n", "$1=$2_derefidx_vbuyy$3", null, mapZ3)); synths.add(new FragmentSynthesis("(.*)=(.*)_derefidx_vbuz2(.*)", ".*=.*yy.*|.*z2.*z2.*", "ldy {z2}\n", "$1=$2_derefidx_vbuyy$3", null, mapZ3));
synths.add(new FragmentSynthesis("(.*)=(.*)_derefidx_vbuz3(.*)", ".*=.*yy.*", "ldy {z3}\n", "$1=$2_derefidx_vbuyy$3", null, null)); synths.add(new FragmentSynthesis("(.*)=(.*)_derefidx_vbuz3(.*)", ".*=.*yy.*", "ldy {z3}\n", "$1=$2_derefidx_vbuyy$3", null, null));
synths.add(new FragmentSynthesis("(.*)=(.*)_derefidx_vbuz3(.*)", ".*=.*xx.*", "ldx {z3}\n", "$1=$2_derefidx_vbuxx$3", null, null)); synths.add(new FragmentSynthesis("(.*)=(.*)_derefidx_vbuz3(.*)", ".*=.*xx.*", "ldx {z3}\n", "$1=$2_derefidx_vbuxx$3", null, null));
synths.add(new FragmentSynthesis("(.*)_derefidx_vbuz1(.*)_derefidx_vbuz1(.*)", ".*z1.*z1.*z1.*|.*xx.*", null, "$1_derefidx_vbuxx$2_derefidx_vbuxx$3", "ldx {z1}\n", mapZ)); synths.add(new FragmentSynthesis("(.*)_derefidx_vbuz1(.*)_derefidx_vbuz1(.*)", ".*z1.*z1.*z1.*|.*xx.*", null, "$1_derefidx_vbuxx$2_derefidx_vbuxx$3", "ldx {z1}\n", mapZ));
synths.add(new FragmentSynthesis("(.*)_derefidx_vbuz1(.*)_derefidx_vbuz1(.*)", ".*z1.*z1.*z1.*|.*yy.*", null, "$1_derefidx_vbuyy$2_derefidx_vbuyy$3", "ldy {z1}\n", mapZ)); synths.add(new FragmentSynthesis("(.*)_derefidx_vbuz1(.*)_derefidx_vbuz1(.*)", ".*z1.*z1.*z1.*|.*yy.*", null, "$1_derefidx_vbuyy$2_derefidx_vbuyy$3", "ldy {z1}\n", mapZ));
synths.add(new FragmentSynthesis("(.*)_derefidx_vbuz2(.*)_derefidx_vbuz2(.*)", ".*z2.*z2.*z2.*|.*xx.*", null, "$1_derefidx_vbuxx$2_derefidx_vbuxx$3", "ldx {z2}\n", mapZ)); synths.add(new FragmentSynthesis("(.*)_derefidx_vbuz2(.*)_derefidx_vbuz2(.*)", ".*z2.*z2.*z2.*|.*xx.*", null, "$1_derefidx_vbuxx$2_derefidx_vbuxx$3", "ldx {z2}\n", mapZ));
synths.add(new FragmentSynthesis("(.*)_derefidx_vbuz2(.*)_derefidx_vbuz2(.*)", ".*z2.*z2.*z2.*|.*yy.*", null, "$1_derefidx_vbuyy$2_derefidx_vbuyy$3", "ldy {z2}\n", mapZ)); synths.add(new FragmentSynthesis("(.*)_derefidx_vbuz2(.*)_derefidx_vbuz2(.*)", ".*z2.*z2.*z2.*|.*yy.*", null, "$1_derefidx_vbuyy$2_derefidx_vbuyy$3", "ldy {z2}\n", mapZ));
// Convert X/Y-based array indexing of a constant pointer into A-register by prefixing lda cn,x / lda cn,y ( ...pb.c1_derefidx_vbuxx... / ...pb.c1_derefidx_vbuyy... -> ...vb.aa... )
synths.add(new FragmentSynthesis("(.*)=(.*)pb(.)c1_derefidx_vbuxx(.*)", ".*=.*aa.*|.*c1.*c1.*", "lda {c1},x\n", "$1=$2vb$3aa$4", null, mapC));
synths.add(new FragmentSynthesis("(.*)=(.*c1.*)pb(.)c1_derefidx_vbuxx(.*)", ".*=.*aa.*", "lda {c1},x\n", "$1=$2vb$3aa$4", null, null));
synths.add(new FragmentSynthesis("(.*)=(.*)pb(.)c1_derefidx_vbuxx(.*c1.*)", ".*=.*aa.*", "lda {c1},x\n", "$1=$2vb$3aa$4", null, null));
synths.add(new FragmentSynthesis("(.*)=(.*)pb(.)c1_derefidx_vbuyy(.*)", ".*=.*aa.*|.*c1.*c1.*", "lda {c1},y\n", "$1=$2vb$3aa$4", null, mapC));
synths.add(new FragmentSynthesis("(.*)=(.*c1.*)pb(.)c1_derefidx_vbuyy(.*)", ".*=.*aa.*", "lda {c1},y\n", "$1=$2vb$3aa$4", null, null));
synths.add(new FragmentSynthesis("(.*)=(.*)pb(.)c1_derefidx_vbuyy(.*c1.*)", ".*=.*aa.*", "lda {c1},y\n", "$1=$2vb$3aa$4", null, null));
synths.add(new FragmentSynthesis("(.*)=(.*)pb(.)c2_derefidx_vbuxx(.*)", ".*=.*aa.*|.*c2.*c2.*", "lda {c2},x\n", "$1=$2vb$3aa$4", null, mapC3));
synths.add(new FragmentSynthesis("(.*)=(.*c2.*)pb(.)c2_derefidx_vbuxx(.*)", ".*=.*aa.*", "lda {c2},x\n", "$1=$2vb$3aa$4", null, null));
synths.add(new FragmentSynthesis("(.*)=(.*)pb(.)c2_derefidx_vbuxx(.*c2.*)", ".*=.*aa.*", "lda {c2},x\n", "$1=$2vb$3aa$4", null, null));
synths.add(new FragmentSynthesis("(.*)=(.*)pb(.)c2_derefidx_vbuyy(.*)", ".*=.*aa.*|.*c2.*c2.*", "lda {c2},y\n", "$1=$2vb$3aa$4", null, mapC3));
synths.add(new FragmentSynthesis("(.*)=(.*c2.*)pb(.)c2_derefidx_vbuyy(.*)", ".*=.*aa.*", "lda {c2},y\n", "$1=$2vb$3aa$4", null, null));
synths.add(new FragmentSynthesis("(.*)=(.*)pb(.)c2_derefidx_vbuyy(.*c2.*)", ".*=.*aa.*", "lda {c2},y\n", "$1=$2vb$3aa$4", null, null));
synths.add(new FragmentSynthesis("(.*)=(.*)_vbuxx", ".*=.*[ax][ax].*xx|.*derefidx_vb.xx", "txa\n", "$1=$2_vbuaa", null, null)); synths.add(new FragmentSynthesis("(.*)=(.*)_vbuxx", ".*=.*[ax][ax].*xx|.*derefidx_vb.xx", "txa\n", "$1=$2_vbuaa", null, null));
synths.add(new FragmentSynthesis("(.*)=(.*)_vbsxx", ".*=.*[ax][ax].*xx|.*derefidx_vb.xx", "txa\n", "$1=$2_vbsaa", null, null)); synths.add(new FragmentSynthesis("(.*)=(.*)_vbsxx", ".*=.*[ax][ax].*xx|.*derefidx_vb.xx", "txa\n", "$1=$2_vbsaa", null, null));
@ -229,30 +229,31 @@ public class AsmFragmentManager {
synths.add(new FragmentSynthesis("p..z1=(.*)_(sethi|setlo|plus|minus)_(.*)", null, null, "vwuz1=$1_$2_$3", null, null)); synths.add(new FragmentSynthesis("p..z1=(.*)_(sethi|setlo|plus|minus)_(.*)", null, null, "vwuz1=$1_$2_$3", null, null));
synths.add(new FragmentSynthesis("(.*)=p..z(.)_(sethi|setlo|plus|minus)_(.*)", null, null, "$1=vwuz$2_$3_$4", null, null)); synths.add(new FragmentSynthesis("(.*)=p..z(.)_(sethi|setlo|plus|minus)_(.*)", null, null, "$1=vwuz$2_$3_$4", null, null));
// Use unsigned ASM to synthesize signed ASM ( ...vbs... -> ...vbu... )
synths.add(new FragmentSynthesis("(vbsz.|vbsaa|vbsxx|vbsyy)_(eq|neq)_(vbsz.|vbsc.|vbsaa|vbsxx|vbsyy)_then_(.*)", null, null, "$1_$2_$3_then_$4", null, mapSToU)); synths.add(new FragmentSynthesis("(vbsz.|vbsaa|vbsxx|vbsyy)_(eq|neq)_(vbsz.|vbsc.|vbsaa|vbsxx|vbsyy)_then_(.*)", null, null, "$1_$2_$3_then_$4", null, mapSToU));
synths.add(new FragmentSynthesis("(vbsz.|vbsaa|vbsxx|vbsyy)=(vbsz.|vbsc.|vbsaa|vbsxx|vbsyy)", null, null, "$1=$2", null, mapSToU)); synths.add(new FragmentSynthesis("(vbsz.|vbsaa|vbsxx|vbsyy)=(vbsz.|vbsc.|vbsaa|vbsxx|vbsyy)", null, null, "$1=$2", null, mapSToU));
synths.add(new FragmentSynthesis("(vbsz.|vbsaa|vbsxx|vbsyy)=(vbsz.|vbsc.|vbsaa|vbsxx|vbsyy)_(plus|band|bxor|bor)_(vbsz.|csoby.|vbsaa|vbsxx|vbsyy)", null, null, "$1=$2_$3_$4", null, mapSToU)); synths.add(new FragmentSynthesis("(vbsz.|vbsaa|vbsxx|vbsyy)=(vbsz.|vbsc.|vbsaa|vbsxx|vbsyy)_(plus|band|bxor|bor)_(vbsz.|csoby.|vbsaa|vbsxx|vbsyy)", null, null, "$1=$2_$3_$4", null, mapSToU));
synths.add(new FragmentSynthesis("(vbsz.|vbsaa|vbsxx|vbsyy)=_(inc|dec)_(vbsz.|vbsc.|vbsaa|vbsxx|vbsyy)", null, null, "$1=_$2_$3", null, mapSToU)); synths.add(new FragmentSynthesis("(vbsz.|vbsaa|vbsxx|vbsyy)=_(inc|dec)_(vbsz.|vbsc.|vbsaa|vbsxx|vbsyy)", null, null, "$1=_$2_$3", null, mapSToU));
synths.add(new FragmentSynthesis("(vwsz.)=(vwsz.|vwsc.)", null, null, "$1=$2", null, mapSToU)); synths.add(new FragmentSynthesis("(vwsz.)=(vwsz.|vwsc.)", null, null, "$1=$2", null, mapSToU));
synths.add(new FragmentSynthesis("(vwsz.)=(vwsz.|vwsc.)_(plus|band|bxor|bor)_(vwsz.|vwsc.)", null, null, "$1=$2_$3_$4", null, mapSToU)); synths.add(new FragmentSynthesis("(vwsz.)=(vwsz.|vwsc.)_(plus|band|bxor|bor)_(vwsz.|vwsc.)", null, null, "$1=$2_$3_$4", null, mapSToU));
synths.add(new FragmentSynthesis("(vbuz.|vbuaa|vbuxx|vbuyy)=_(lo|hi)_vws(z.|c.)", null, null, "$1=_$2_vwu$3", null, mapSToU));
// Use constant word ASM to synthesize unsigned constant byte ASM ( ...vb.c... -> vw.c... )
synths.add(new FragmentSynthesis("(vwuz.)=(vwuz.)_(plus|minus|band|bxor|bor)_vb.c(.)", null, null, "$1=$2_$3_vwuc$4", null, null)); synths.add(new FragmentSynthesis("(vwuz.)=(vwuz.)_(plus|minus|band|bxor|bor)_vb.c(.)", null, null, "$1=$2_$3_vwuc$4", null, null));
synths.add(new FragmentSynthesis("(vwuz.)=vb.c(.)_(plus|minus|band|bxor|bor)_(vwuz.)", null, null, "$1=vwuc$2_$3_$4", null, null)); synths.add(new FragmentSynthesis("(vwuz.)=vb.c(.)_(plus|minus|band|bxor|bor)_(vwuz.)", null, null, "$1=vwuc$2_$3_$4", null, null));
synths.add(new FragmentSynthesis("(vwsz.)=(vwsz.)_(plus|minus|band|bxor|bor)_vb.c(.)", null, null, "$1=$2_$3_vwsc$4", null, null)); synths.add(new FragmentSynthesis("(vwsz.)=(vwsz.)_(plus|minus|band|bxor|bor)_vb.c(.)", null, null, "$1=$2_$3_vwsc$4", null, null));
synths.add(new FragmentSynthesis("(vwsz.)=vb.c(.)_(plus|minus|band|bxor|bor)_(vwsz.)", null, null, "$1=vwsc$2_$3_$4", null, null)); synths.add(new FragmentSynthesis("(vwsz.)=vb.c(.)_(plus|minus|band|bxor|bor)_(vwsz.)", null, null, "$1=vwsc$2_$3_$4", null, null));
// Move constant words to the end of the ASM signature for symmetric operators ( ...vw.c...vw.z... -> ...vw.z...vw.c... )
synths.add(new FragmentSynthesis("(vwuz.)=(vwuc.)_(plus|band|bxor|bor)_(vwuz.)", null, null, "$1=$4_$3_$2", null, null)); synths.add(new FragmentSynthesis("(vwuz.)=(vwuc.)_(plus|band|bxor|bor)_(vwuz.)", null, null, "$1=$4_$3_$2", null, null));
synths.add(new FragmentSynthesis("(vwsz.)=(vwsc.)_(plus|band|bxor|bor)_(vwsz.)", null, null, "$1=$4_$3_$2", null, null)); synths.add(new FragmentSynthesis("(vwsz.)=(vwsc.)_(plus|band|bxor|bor)_(vwsz.)", null, null, "$1=$4_$3_$2", null, null));
synths.add(new FragmentSynthesis("(vbuz.|vbuaa|vbuxx|vbuyy)=_(lo|hi)_vws(z.|c.)", null, null, "$1=_$2_vwu$3", null, mapSToU)); // Use Z1/Z2 ASM to synthesize Z1-only code ( ...z1...z1... -> ...z1...z2... )
synths.add(new FragmentSynthesis("(v..)z1=(v..)z1_(plus|minus|band|bxor|bor)_(.*)", ".*z2.*", null, "$1z1=$2z2_$3_$4", null, mapZ, false));
synths.add(new FragmentSynthesis("(v..)z1=(.*)_(plus|minus|band|bxor|bor)_(v..)z1", ".*z2.*", null, "$1z1=$2_$3_$4z2", null, mapZ, false));
synths.add(new FragmentSynthesis("(v..)z1=_(neg|lo|hi)_(v..)z1", ".*z2.*", null, "$1z1=_$2_$3z2", null, mapZ, false));
// Use Z1/Z2 ASM to synthesize Z1-only code // Convert INC/DEC to +1/-1 ( ..._inc_xxx... -> ...xxx_plus_1_... / ..._dec_xxx... -> ...xxx_minus_1_... )
synths.add(new FragmentSynthesis("(v..)z1=(v..)z1_(plus|minus|band|bxor|bor)_(.*)", null, null, "$1z1=$2z2_$3_$4", null, mapZ, false));
synths.add(new FragmentSynthesis("(v..)z1=(.*)_(plus|minus|band|bxor|bor)_(v..)z1", null, null, "$1z1=$2_$3_$4z2", null, mapZ, false));
synths.add(new FragmentSynthesis("(v..)z1=_(neg|lo|hi)_(v..)z1", null, null, "$1z1=_$2_$3z2", null, mapZ, false));
// INC/DEC from +1 / -1
synths.add(new FragmentSynthesis("vb(.)aa=_inc_(.*)", null, null, "vb$1aa=$2_plus_1", null, null)); synths.add(new FragmentSynthesis("vb(.)aa=_inc_(.*)", null, null, "vb$1aa=$2_plus_1", null, null));
synths.add(new FragmentSynthesis("vb(.)aa=_dec_(.*)", null, null, "vb$1aa=$2_minus_1", null, null)); synths.add(new FragmentSynthesis("vb(.)aa=_dec_(.*)", null, null, "vb$1aa=$2_minus_1", null, null));

View File

@ -0,0 +1,95 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.*;
import java.util.ArrayList;
import java.util.Map;
/** A {@link ValueReplacer} that replaces symbols with their alias. */
public class AliasReplacer implements ValueReplacer.Replacer {
private Map<? extends SymbolRef, ? extends RValue> aliases;
public AliasReplacer(Map<? extends SymbolRef, ? extends RValue> aliases) {
this.aliases = aliases;
}
/**
* Get the alias to use for an RValue.
* Also looks inside any constant values for replacements.
* If a replacement is found the replacement is performed and the new value is returned. If no replacement is found null is returned.
*
* @param rValue The RValue to find an alias for
* @return The alias to use. Null if no alias exists.
*/
public static RValue getReplacement(RValue rValue, Map<? extends SymbolRef, ? extends RValue> aliases) {
if (rValue instanceof SymbolRef) {
RValue alias = aliases.get(rValue);
if (alias != null) {
if (alias.equals(rValue)) {
return alias;
}
RValue replacement = getReplacement(alias, aliases);
if (replacement != null) {
return replacement;
} else {
return alias;
}
}
} else if (rValue instanceof ConstantUnary) {
ConstantUnary constantUnary = (ConstantUnary) rValue;
ConstantValue alias = (ConstantValue) getReplacement(constantUnary.getOperand(), aliases);
if (alias != null) {
return new ConstantUnary(constantUnary.getOperator(), alias);
}
} else if (rValue instanceof ConstantBinary) {
ConstantBinary constantBinary = (ConstantBinary) rValue;
ConstantValue aliasLeft = (ConstantValue) getReplacement(constantBinary.getLeft(), aliases);
ConstantValue aliasRight = (ConstantValue) getReplacement(constantBinary.getRight(), aliases);
if (aliasLeft != null || aliasRight != null) {
if (aliasLeft == null) {
aliasLeft = constantBinary.getLeft();
}
if (aliasRight == null) {
aliasRight = constantBinary.getRight();
}
return new ConstantBinary(aliasLeft, constantBinary.getOperator(), aliasRight);
}
} else if (rValue instanceof ConstantArray) {
ConstantArray constantArray = (ConstantArray) rValue;
ArrayList<ConstantValue> replacementList = new ArrayList<>();
boolean any = false;
for (ConstantValue elemValue : constantArray.getElements()) {
RValue elemReplacement = getReplacement(elemValue, aliases);
if (elemReplacement != null) {
replacementList.add((ConstantValue) elemReplacement);
any = true;
} else {
replacementList.add(elemValue);
}
}
if (any) {
return new ConstantArray(replacementList, constantArray.getElementType());
}
}
// No replacement found - return null
return null;
}
@Override
/**
* Execute alias replacement on a replaceable value
* @param replaceable The replaceable value
*/
public void execute(ValueReplacer.ReplaceableValue replaceable) {
if (replaceable.get() != null) {
RValue replacement = getReplacement(replaceable.get(), aliases);
if (replacement != null) {
replaceable.set(replacement);
}
}
}
}

View File

@ -27,7 +27,7 @@ public class Pass1ExtractInlineStrings extends Pass1Base {
int size = parameters.size(); int size = parameters.size();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
String parameterName = procedure.getParameterNames().get(i); String parameterName = procedure.getParameterNames().get(i);
execute(new VariableReplacer.ReplacableCallParameter(call, i), blockScope, parameterName); execute(new ValueReplacer.ReplaceableCallParameter(call, i), blockScope, parameterName);
} }
} else if (statement instanceof StatementAssignment) { } else if (statement instanceof StatementAssignment) {
StatementAssignment assignment = (StatementAssignment) statement; StatementAssignment assignment = (StatementAssignment) statement;
@ -39,23 +39,23 @@ public class Pass1ExtractInlineStrings extends Pass1Base {
// This will be picked up later as a constant - the temporary constant variable is not needed // This will be picked up later as a constant - the temporary constant variable is not needed
continue; continue;
} }
execute(new VariableReplacer.ReplacableRValue1(assignment), blockScope, null); execute(new ValueReplacer.ReplaceableRValue1(assignment), blockScope, null);
execute(new VariableReplacer.ReplacableRValue2(assignment), blockScope, null); execute(new ValueReplacer.ReplaceableRValue2(assignment), blockScope, null);
} else if (statement instanceof StatementReturn) { } else if (statement instanceof StatementReturn) {
execute(new VariableReplacer.ReplacableReturn((StatementReturn) statement), blockScope, null); execute(new ValueReplacer.ReplaceableReturn((StatementReturn) statement), blockScope, null);
} }
} }
} }
return false; return false;
} }
private void execute(VariableReplacer.ReplacableValue replacable, Scope blockScope, String nameHint) { private void execute(ValueReplacer.ReplaceableValue replaceable, Scope blockScope, String nameHint) {
RValue value = replacable.get(); RValue value = replaceable.get();
if(value instanceof ConstantString) { if(value instanceof ConstantString) {
ConstantVar strConst = createStringConstantVar(blockScope, (ConstantString) replacable.get(), nameHint); ConstantVar strConst = createStringConstantVar(blockScope, (ConstantString) replaceable.get(), nameHint);
replacable.set(strConst.getRef()); replaceable.set(strConst.getRef());
} }
for (VariableReplacer.ReplacableValue subValue : replacable.getSubValues()) { for (ValueReplacer.ReplaceableValue subValue : replaceable.getSubValues()) {
execute(subValue, blockScope, nameHint); execute(subValue, blockScope, nameHint);
} }
} }

View File

@ -65,22 +65,22 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base {
} }
/** /**
* Version all variable uses in the replacable value * Version all variable uses in the replaceable value
* *
* @param replacableValue The value to version variable usages in * @param replaceableValue The value to version variable usages in
* @param blockVersions Newest version of variables in the block. * @param blockVersions Newest version of variables in the block.
* @param blockNewPhis New phi functions introduced in the block to create versions of variables. * @param blockNewPhis New phi functions introduced in the block to create versions of variables.
*/ */
private void execute( private void execute(
VariableReplacer.ReplacableValue replacableValue, ValueReplacer.ReplaceableValue replaceableValue,
Map<VariableUnversioned, VariableVersion> blockVersions, Map<VariableUnversioned, VariableVersion> blockVersions,
Map<VariableUnversioned, VariableVersion> blockNewPhis) { Map<VariableUnversioned, VariableVersion> blockNewPhis) {
RValue value = replacableValue.get(); RValue value = replaceableValue.get();
VariableVersion version = findOrCreateVersion(value, blockVersions, blockNewPhis); VariableVersion version = findOrCreateVersion(value, blockVersions, blockNewPhis);
if (version != null) { if (version != null) {
replacableValue.set(version.getRef()); replaceableValue.set(version.getRef());
} }
for (VariableReplacer.ReplacableValue subValue : replacableValue.getSubValues()) { for (ValueReplacer.ReplaceableValue subValue : replaceableValue.getSubValues()) {
execute(subValue, blockVersions, blockNewPhis); execute(subValue, blockVersions, blockNewPhis);
} }
} }
@ -96,12 +96,12 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base {
Map<VariableUnversioned, VariableVersion> blockNewPhis = new LinkedHashMap<>(); Map<VariableUnversioned, VariableVersion> blockNewPhis = new LinkedHashMap<>();
for (Statement statement : block.getStatements()) { for (Statement statement : block.getStatements()) {
if (statement instanceof StatementReturn) { if (statement instanceof StatementReturn) {
execute(new VariableReplacer.ReplacableReturn((StatementReturn) statement), blockVersions, blockNewPhis); execute(new ValueReplacer.ReplaceableReturn((StatementReturn) statement), blockVersions, blockNewPhis);
} else if (statement instanceof StatementAssignment) { } else if (statement instanceof StatementAssignment) {
StatementAssignment assignment = (StatementAssignment) statement; StatementAssignment assignment = (StatementAssignment) statement;
execute(new VariableReplacer.ReplacableRValue1(assignment), blockVersions, blockNewPhis); execute(new ValueReplacer.ReplaceableRValue1(assignment), blockVersions, blockNewPhis);
execute(new VariableReplacer.ReplacableRValue2(assignment), blockVersions, blockNewPhis); execute(new ValueReplacer.ReplaceableRValue2(assignment), blockVersions, blockNewPhis);
execute(new VariableReplacer.ReplacableLValue(assignment), blockVersions, blockNewPhis); execute(new ValueReplacer.ReplaceableLValue(assignment), blockVersions, blockNewPhis);
// Update map of versions encountered in the block // Update map of versions encountered in the block
LValue lValue = assignment.getlValue(); LValue lValue = assignment.getlValue();

View File

@ -39,13 +39,13 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
if (statement instanceof StatementAssignment) { if (statement instanceof StatementAssignment) {
StatementAssignment assignment = (StatementAssignment) statement; StatementAssignment assignment = (StatementAssignment) statement;
if(assignment.getlValue() instanceof PointerDereferenceIndexed) { if(assignment.getlValue() instanceof PointerDereferenceIndexed) {
optimized |= optimizePointerDereferenceIndexed(new VariableReplacer.ReplacableLValue(assignment)); optimized |= optimizePointerDereferenceIndexed(new ValueReplacer.ReplaceableLValue(assignment));
} }
if(assignment.getrValue1() instanceof PointerDereferenceIndexed) { if(assignment.getrValue1() instanceof PointerDereferenceIndexed) {
optimized |= optimizePointerDereferenceIndexed(new VariableReplacer.ReplacableRValue1(assignment)); optimized |= optimizePointerDereferenceIndexed(new ValueReplacer.ReplaceableRValue1(assignment));
} }
if(assignment.getrValue2() instanceof PointerDereferenceIndexed) { if(assignment.getrValue2() instanceof PointerDereferenceIndexed) {
optimized |= optimizePointerDereferenceIndexed(new VariableReplacer.ReplacableRValue2(assignment)); optimized |= optimizePointerDereferenceIndexed(new ValueReplacer.ReplaceableRValue2(assignment));
} }
Operator operator = assignment.getOperator(); Operator operator = assignment.getOperator();
@ -62,10 +62,10 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
} else if(statement instanceof StatementConditionalJump) { } else if(statement instanceof StatementConditionalJump) {
StatementConditionalJump jump = (StatementConditionalJump) statement; StatementConditionalJump jump = (StatementConditionalJump) statement;
if(jump.getrValue1() instanceof PointerDereferenceIndexed) { if(jump.getrValue1() instanceof PointerDereferenceIndexed) {
optimized |= optimizePointerDereferenceIndexed(new VariableReplacer.ReplacableCondRValue1(jump)); optimized |= optimizePointerDereferenceIndexed(new ValueReplacer.ReplaceableCondRValue1(jump));
} }
if(jump.getrValue2() instanceof PointerDereferenceIndexed) { if(jump.getrValue2() instanceof PointerDereferenceIndexed) {
optimized |= optimizePointerDereferenceIndexed(new VariableReplacer.ReplacableCondRValue2(jump)); optimized |= optimizePointerDereferenceIndexed(new ValueReplacer.ReplaceableCondRValue2(jump));
} }
} }
} }
@ -73,7 +73,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
return optimized; return optimized;
} }
private boolean optimizePointerDereferenceIndexed(VariableReplacer.ReplacableValue value) { private boolean optimizePointerDereferenceIndexed(ValueReplacer.ReplaceableValue value) {
PointerDereferenceIndexed pointerDereferenceIndexed = (PointerDereferenceIndexed) value.get(); PointerDereferenceIndexed pointerDereferenceIndexed = (PointerDereferenceIndexed) value.get();
if(pointerDereferenceIndexed.getPointer() instanceof ConstantValue && pointerDereferenceIndexed.getIndex() instanceof ConstantValue) { if(pointerDereferenceIndexed.getPointer() instanceof ConstantValue && pointerDereferenceIndexed.getIndex() instanceof ConstantValue) {
ConstantValue ptrConstant = (ConstantValue) pointerDereferenceIndexed.getPointer(); ConstantValue ptrConstant = (ConstantValue) pointerDereferenceIndexed.getPointer();

View File

@ -57,8 +57,9 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
ControlFlowGraphBaseVisitor<Void> visitor = new ControlFlowGraphBaseVisitor<Void>() { ControlFlowGraphBaseVisitor<Void> visitor = new ControlFlowGraphBaseVisitor<Void>() {
@Override @Override
public Void visitAssignment(StatementAssignment assignment) { public Void visitAssignment(StatementAssignment assignment) {
if (assignment.getlValue() instanceof VariableRef) { LValue lValue = assignment.getlValue();
VariableRef variable = (VariableRef) assignment.getlValue(); if (lValue instanceof VariableRef) {
VariableRef variable = (VariableRef) lValue;
if (assignment.getrValue1() == null && getConstant(assignment.getrValue2()) != null) { if (assignment.getrValue1() == null && getConstant(assignment.getrValue2()) != null) {
if (assignment.getOperator() == null) { if (assignment.getOperator() == null) {
// Constant assignment // Constant assignment
@ -81,35 +82,39 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
constants.put(variable, constant); constants.put(variable, constant);
} }
} else if (assignment.getrValue2() instanceof ValueList && assignment.getOperator() == null && assignment.getrValue1() == null) { } else if (assignment.getrValue2() instanceof ValueList && assignment.getOperator() == null && assignment.getrValue1() == null) {
ValueList valueList = (ValueList) assignment.getrValue2(); if (lValue instanceof VariableRef) {
List<RValue> values = valueList.getList(); Variable lVariable = getSymbols().getVariable((VariableRef) lValue);
boolean allConstant = true; if (lVariable.getType() instanceof SymbolTypeArray) {
SymbolType elementType = null; ValueList valueList = (ValueList) assignment.getrValue2();
List<ConstantValue> elements = new ArrayList<>(); List<RValue> values = valueList.getList();
for (RValue value : values) { boolean allConstant = true;
if (value instanceof ConstantValue) { SymbolType elementType = null;
ConstantValue constantValue = (ConstantValue) value; List<ConstantValue> elements = new ArrayList<>();
SymbolType type = constantValue.getType(getSymbols()); for (RValue value : values) {
if (elementType == null) { if (value instanceof ConstantValue) {
elementType = type; ConstantValue constantValue = (ConstantValue) value;
} else { SymbolType type = constantValue.getType(getSymbols());
if (!SymbolTypeInference.typeMatch(type, elementType)) { if (elementType == null) {
throw new RuntimeException("Array type mismatch " + elementType + " does not match " + type + " " + valueList.toString(getProgram())); elementType = type;
} else {
if (!SymbolTypeInference.typeMatch(type, elementType)) {
throw new RuntimeException("Array type mismatch " + elementType + " does not match " + type + " " + valueList.toString(getProgram()));
}
}
elements.add(constantValue);
} else {
allConstant = false;
elementType = null;
break;
} }
} }
elements.add(constantValue); if (allConstant && elementType != null) {
} else { ConstantValue constant = new ConstantArray(elements, elementType);
allConstant = false; constants.put(variable, constant);
elementType = null; }
break;
} }
} }
if (allConstant && elementType != null) {
ConstantValue constant = new ConstantArray(elements, elementType);
constants.put(variable, constant);
}
} }
} }
return null; return null;
} }
@ -164,6 +169,8 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
case "<<": case "<<":
case ">>": case ">>":
return new ConstantBinary(c1, operator, c2); return new ConstantBinary(c1, operator, c2);
case "w=":
return new ConstantBinary(new ConstantBinary(c1, Operator.MULTIPLY, new ConstantInteger(256)), Operator.PLUS, c2);
case "*idx": case "*idx":
// Pointer dereference - not constant // Pointer dereference - not constant
return null; return null;

View File

@ -52,11 +52,10 @@ public class Pass2ConstantInlining extends Pass2SsaOptimization {
* @param inline The replacements to make * @param inline The replacements to make
*/ */
private void replaceInSymbolTable(Map<ConstantRef, ConstantValue> inline) { private void replaceInSymbolTable(Map<ConstantRef, ConstantValue> inline) {
VariableReplacer replacer = new VariableReplacer(inline);
Collection<ConstantVar> allConstants = getProgram().getScope().getAllConstants(true); Collection<ConstantVar> allConstants = getProgram().getScope().getAllConstants(true);
for (ConstantVar constantVar : allConstants) { for (ConstantVar constantVar : allConstants) {
ConstantValue constantValue = constantVar.getValue(); ConstantValue constantValue = constantVar.getValue();
RValue replacement = replacer.getReplacement(constantValue); RValue replacement = AliasReplacer.getReplacement(constantValue, inline);
if(replacement!=null) { if(replacement!=null) {
constantVar.setValue((ConstantValue) replacement); constantVar.setValue((ConstantValue) replacement);
} }
@ -68,13 +67,12 @@ public class Pass2ConstantInlining extends Pass2SsaOptimization {
* @param inline The replacements * @param inline The replacements
*/ */
private void replaceInValues(Map<ConstantRef, ConstantValue> inline) { private void replaceInValues(Map<ConstantRef, ConstantValue> inline) {
VariableReplacer replacer = new VariableReplacer(inline);
boolean replaced = true; boolean replaced = true;
while(replaced) { while(replaced) {
replaced = false; replaced = false;
for (ConstantRef constantRef : inline.keySet()) { for (ConstantRef constantRef : inline.keySet()) {
ConstantValue constantValue = inline.get(constantRef); ConstantValue constantValue = inline.get(constantRef);
ConstantValue replacement = (ConstantValue) replacer.getReplacement(constantValue); ConstantValue replacement = (ConstantValue) AliasReplacer.getReplacement(constantValue, inline);
if (replacement != null) { if (replacement != null) {
replaced = true; replaced = true;
inline.put(constantRef, replacement); inline.put(constantRef, replacement);
@ -112,7 +110,7 @@ public class Pass2ConstantInlining extends Pass2SsaOptimization {
ConstantValue constantValue = constant.getValue(); ConstantValue constantValue = constant.getValue();
if(constantValue instanceof ConstantRef) { if(constantValue instanceof ConstantRef) {
if(((ConstantRef) constantValue).isIntermediate()) { if(((ConstantRef) constantValue).isIntermediate()) {
// The value is an intermediate constant - replace all uses of the intermediate with uses of the referer instead. // The value is an intermediate constant - replace all uses of the intermediate with uses of the referrer instead.
aliases.put((ConstantRef) constant.getValue(), constant.getRef()); aliases.put((ConstantRef) constant.getValue(), constant.getRef());
constant.setValue(programScope.getConstant((ConstantRef) constantValue).getValue()); constant.setValue(programScope.getConstant((ConstantRef) constantValue).getValue());
} else { } else {

View File

@ -3,17 +3,18 @@ package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.*; import dk.camelot64.kickc.model.*;
/** /**
* The syntax for word constructors <code>word w = { b1, b2 };</code> * Identifies word constructors <code>{ b1, b2 }</code> and replaces
* is turned into a binary operator <code>word w = b1 _toword_ b2 ;</code> * them with a binary operator <code>word w = b1 w= b2 ;</code>
*/ */
public class Pass1FixWordConstructors extends Pass1Base { public class Pass2FixWordConstructors extends Pass2SsaOptimization{
public Pass1FixWordConstructors(Program program) { public Pass2FixWordConstructors(Program program) {
super(program); super(program);
} }
@Override @Override
boolean executeStep() { public boolean optimize() {
boolean optimized = false;
ProgramScope programScope = getProgram().getScope(); ProgramScope programScope = getProgram().getScope();
for (ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) { for (ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) {
for (Statement statement : block.getStatements()) { for (Statement statement : block.getStatements()) {
@ -33,6 +34,7 @@ public class Pass1FixWordConstructors extends Pass1Base {
assignment.setOperator(Operator.WORD); assignment.setOperator(Operator.WORD);
assignment.setrValue2(list.getList().get(1)); assignment.setrValue2(list.getList().get(1));
getLog().append("Fixing word constructor with " + assignment.toString()); getLog().append("Fixing word constructor with " + assignment.toString());
optimized = true;
} }
} }
} }
@ -40,7 +42,7 @@ public class Pass1FixWordConstructors extends Pass1Base {
} }
} }
} }
return false; return optimized;
} }
} }

View File

@ -47,8 +47,8 @@ public abstract class Pass2SsaOptimization {
* @param aliases Variables that have alias values. * @param aliases Variables that have alias values.
*/ */
public void replaceVariables(final Map<? extends SymbolRef, ? extends RValue> aliases) { public void replaceVariables(final Map<? extends SymbolRef, ? extends RValue> aliases) {
VariableReplacer replacer = new VariableReplacer(aliases); AliasReplacer replacer = new AliasReplacer(aliases);
replacer.execute(getGraph()); ValueReplacer.executeAll(getGraph(), replacer);
} }
/** /**

View File

@ -0,0 +1,337 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.*;
import java.util.*;
/**
* A replacer capable to alias all usages of a variable (or constant var) with a suitable replacement
*/
public class ValueReplacer {
/** A replacer that receives a replaceable value and has the potential to replace the value or recurse into sub-values. */
public interface Replacer {
void execute(ReplaceableValue replaceable);
}
/**
* Execute a replacer on all replaceable values in the program control flow graph
*
* @param graph The program control flow graph
* @param replacer The replacer to execute
*/
public static void executeAll(ControlFlowGraph graph, Replacer replacer) {
for (ControlFlowBlock block : graph.getAllBlocks()) {
for (Statement statement : block.getStatements()) {
if (statement instanceof StatementAssignment) {
executeAll(new ReplaceableLValue((StatementLValue) statement), replacer);
executeAll(new ReplaceableRValue1((StatementAssignment) statement), replacer);
executeAll(new ReplaceableRValue2((StatementAssignment) statement), replacer);
} else if (statement instanceof StatementCall) {
replacer.execute(new ReplaceableLValue((StatementLValue) statement));
StatementCall call = (StatementCall) statement;
if (call.getParameters() != null) {
int size = call.getParameters().size();
for (int i = 0; i < size; i++) {
executeAll(new ReplaceableCallParameter(call, i), replacer);
}
}
} else if (statement instanceof StatementConditionalJump) {
executeAll(new ReplaceableCondRValue1((StatementConditionalJump) statement), replacer);
executeAll(new ReplaceableCondRValue2((StatementConditionalJump) statement), replacer);
} else if (statement instanceof StatementReturn) {
executeAll(new ReplaceableReturn((StatementReturn) statement), replacer);
} else if (statement instanceof StatementPhiBlock) {
for (StatementPhiBlock.PhiVariable phiVariable : ((StatementPhiBlock) statement).getPhiVariables()) {
executeAll(new ReplaceablePhiVariable(phiVariable), replacer);
int size = phiVariable.getValues().size();
for (int i = 0; i < size; i++) {
executeAll(new ReplaceablePhiValue(phiVariable, i), replacer);
}
}
}
}
}
}
/**
* Execute the a replacer on a replaceable value and all sub-values of the value.
* @param replaceable The replaceable value
* @param replacer The value replacer
*/
public static void executeAll(ReplaceableValue replaceable, Replacer replacer) {
replacer.execute(replaceable);
for (ReplaceableValue subValue : replaceable.getSubValues()) {
executeAll(subValue, replacer);
}
}
/**
* Interface representing an RValue that can be replaced.
* The value may have sub-values that can also be replaced.
*/
public static abstract class ReplaceableValue {
public abstract RValue get();
public abstract void set(RValue value);
public Collection<ReplaceableValue> getSubValues() {
RValue value = get();
ArrayList<ReplaceableValue> subValues = new ArrayList<>();
if (value instanceof PointerDereferenceIndexed) {
subValues.add(new ReplaceablePointer((PointerDereference) value));
subValues.add(new ReplaceablePointerIndex((PointerDereferenceIndexed) value));
} else if (value instanceof PointerDereferenceSimple) {
subValues.add(new ReplaceablePointer((PointerDereference) value));
} else if (value instanceof ValueList) {
ValueList valueList = (ValueList) value;
int size = valueList.getList().size();
for (int i = 0; i < size; i++) {
subValues.add(new ReplaceableListElement(valueList, i));
}
}
return subValues;
}
}
/**
* Replaceable LValue as part of an assignment statement (or a call).
*/
public static class ReplaceableLValue extends ReplaceableValue {
private final StatementLValue statement;
public ReplaceableLValue(StatementLValue statement) {
this.statement = statement;
}
@Override
public RValue get() {
return statement.getlValue();
}
@Override
public void set(RValue value) {
statement.setlValue((LValue) value);
}
}
/**
* Replaceable pointer inside a pointer dererence value.
*/
public static class ReplaceablePointer extends ReplaceableValue {
private final PointerDereference pointer;
ReplaceablePointer(PointerDereference pointer) {
this.pointer = pointer;
}
@Override
public RValue get() {
return pointer.getPointer();
}
@Override
public void set(RValue val) {
pointer.setPointer(val);
}
}
public static class ReplaceableListElement extends ReplaceableValue {
private ValueList list;
private int idx;
public ReplaceableListElement(ValueList list, int idx) {
this.list = list;
this.idx = idx;
}
@Override
public RValue get() {
return list.getList().get(idx);
}
@Override
public void set(RValue value) {
list.getList().set(idx, value);
}
}
/**
* Replaceable pointer index inside a indexed pointer dererence value.
*/
public static class ReplaceablePointerIndex extends ReplaceableValue {
private final PointerDereferenceIndexed pointer;
ReplaceablePointerIndex(PointerDereferenceIndexed pointer) {
this.pointer = pointer;
}
@Override
public RValue get() {
return pointer.getIndex();
}
@Override
public void set(RValue val) {
pointer.setIndex(val);
}
}
public static class ReplaceableRValue1 extends ReplaceableValue {
private final StatementAssignment statement;
public ReplaceableRValue1(StatementAssignment statement) {
this.statement = statement;
}
@Override
public RValue get() {
return statement.getrValue1();
}
@Override
public void set(RValue value) {
statement.setrValue1(value);
}
}
public static class ReplaceableRValue2 extends ReplaceableValue {
private final StatementAssignment statement;
public ReplaceableRValue2(StatementAssignment statement) {
this.statement = statement;
}
@Override
public RValue get() {
return statement.getrValue2();
}
@Override
public void set(RValue value) {
statement.setrValue2(value);
}
}
public static class ReplaceableCallParameter extends ReplaceableValue {
private final StatementCall call;
private final int i;
public ReplaceableCallParameter(StatementCall call, int i) {
this.call = call;
this.i = i;
}
@Override
public RValue get() {
return call.getParameters().get(i);
}
@Override
public void set(RValue value) {
call.getParameters().set(i, value);
}
}
public static class ReplaceableCondRValue1 extends ReplaceableValue {
private final StatementConditionalJump statement;
public ReplaceableCondRValue1(StatementConditionalJump statement) {
this.statement = statement;
}
@Override
public RValue get() {
return statement.getrValue1();
}
@Override
public void set(RValue value) {
statement.setrValue1(value);
}
}
public static class ReplaceableCondRValue2 extends ReplaceableValue {
private final StatementConditionalJump statement;
public ReplaceableCondRValue2(StatementConditionalJump statement) {
this.statement = statement;
}
@Override
public RValue get() {
return statement.getrValue2();
}
@Override
public void set(RValue value) {
statement.setrValue2(value);
}
}
public static class ReplaceableReturn extends ReplaceableValue {
private final StatementReturn statement;
public ReplaceableReturn(StatementReturn statement) {
this.statement = statement;
}
@Override
public RValue get() {
return statement.getValue();
}
@Override
public void set(RValue value) {
statement.setValue(value);
}
}
public static class ReplaceablePhiValue extends ReplaceableValue {
private final StatementPhiBlock.PhiVariable phiVariable;
private final int i;
public ReplaceablePhiValue(StatementPhiBlock.PhiVariable phiVariable, int i) {
this.phiVariable = phiVariable;
this.i = i;
}
@Override
public RValue get() {
return phiVariable.getValues().get(i).getrValue();
}
@Override
public void set(RValue value) {
phiVariable.getValues().get(i).setrValue(value);
}
}
/**
* Replaceable LValue as part of an assignment statement (or a call).
*/
public static class ReplaceablePhiVariable extends ReplaceableValue {
private final StatementPhiBlock.PhiVariable phiVariable;
public ReplaceablePhiVariable(StatementPhiBlock.PhiVariable phiVariable) {
this.phiVariable = phiVariable;
}
@Override
public RValue get() {
return phiVariable.getVariable();
}
@Override
public void set(RValue value) {
phiVariable.setVariable((VariableRef) value);
}
}
}

View File

@ -1,394 +0,0 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.*;
import java.util.*;
/**
* A replacer capable to alias all usages of a variable (or constant var) with a suitable replacement
*/
public class VariableReplacer {
private Map<? extends SymbolRef, ? extends RValue> aliases;
public VariableReplacer(Map<? extends SymbolRef, ? extends RValue> aliases) {
this.aliases = aliases;
}
public void execute(ControlFlowGraph graph) {
//new GraphReplacer().visitGraph(graph);
for (ControlFlowBlock block : graph.getAllBlocks()) {
for (Statement statement : block.getStatements()) {
if (statement instanceof StatementAssignment) {
execute(new ReplacableLValue((StatementLValue) statement));
execute(new ReplacableRValue1((StatementAssignment) statement));
execute(new ReplacableRValue2((StatementAssignment) statement));
} else if (statement instanceof StatementCall) {
execute(new ReplacableLValue((StatementLValue) statement));
StatementCall call = (StatementCall) statement;
if(call.getParameters()!=null) {
int size = call.getParameters().size();
for (int i = 0; i < size; i++) {
execute(new ReplacableCallParameter(call, i));
}
}
} else if (statement instanceof StatementConditionalJump) {
execute(new ReplacableCondRValue1((StatementConditionalJump) statement));
execute(new ReplacableCondRValue2((StatementConditionalJump) statement));
} else if (statement instanceof StatementReturn) {
execute(new ReplacableReturn((StatementReturn) statement));
} else if (statement instanceof StatementPhiBlock) {
for (StatementPhiBlock.PhiVariable phiVariable : ((StatementPhiBlock) statement).getPhiVariables()) {
execute(new ReplacablePhiVariable(phiVariable));
int size = phiVariable.getValues().size();
for (int i = 0; i < size; i++) {
execute(new ReplacablePhiValue(phiVariable, i));
}
}
}
}
}
}
/**
* Execute replacements inside a replacable value - and its sub-values.
* @param replacable The replacable value
*/
void execute(ReplacableValue replacable) {
if(replacable.get()!=null) {
RValue replacement = getReplacement(replacable.get());
if(replacement!=null) {
replacable.set(replacement);
}
for (ReplacableValue subReplacable : replacable.getSubValues()) {
execute(subReplacable);
}
}
}
/**
* Get the alias to use for an RValue.
* Also looks inside any constant values for replacements.
* If a replacement is found the replacement is performed and the new value is returned. If no replacement is found null is returned.
*
* @param rValue The RValue to find an alias for
* @return The alias to use. Null if no alias exists.
*/
public RValue getReplacement(RValue rValue) {
if (rValue instanceof SymbolRef) {
RValue alias = aliases.get(rValue);
if (alias != null) {
if (alias.equals(rValue)) {
return alias;
}
RValue replacement = getReplacement(alias);
if (replacement != null) {
return replacement;
} else {
return alias;
}
}
} else if (rValue instanceof ConstantUnary) {
ConstantUnary constantUnary = (ConstantUnary) rValue;
ConstantValue alias = (ConstantValue) getReplacement(constantUnary.getOperand());
if (alias != null) {
return new ConstantUnary(constantUnary.getOperator(), alias);
}
} else if (rValue instanceof ConstantBinary) {
ConstantBinary constantBinary = (ConstantBinary) rValue;
ConstantValue aliasLeft = (ConstantValue) getReplacement(constantBinary.getLeft());
ConstantValue aliasRight = (ConstantValue) getReplacement(constantBinary.getRight());
if (aliasLeft != null || aliasRight != null) {
if (aliasLeft == null) {
aliasLeft = constantBinary.getLeft();
}
if (aliasRight == null) {
aliasRight = constantBinary.getRight();
}
return new ConstantBinary(aliasLeft, constantBinary.getOperator(), aliasRight);
}
} else if(rValue instanceof ConstantArray) {
ConstantArray constantArray = (ConstantArray) rValue;
ArrayList<ConstantValue> replacementList = new ArrayList<>();
boolean any = false;
for (ConstantValue elemValue : constantArray.getElements()) {
RValue elemReplacement = getReplacement(elemValue);
if(elemReplacement!=null) {
replacementList.add((ConstantValue) elemReplacement);
any = true;
} else{
replacementList.add(elemValue);
}
}
if(any) {
return new ConstantArray(replacementList, constantArray.getElementType());
}
}
// No replacement found - return null
return null;
}
/**
* Interface representing an RValue that can be replaced.
* The value may have sub-values that can also be replaced.
*/
public static abstract class ReplacableValue {
public abstract RValue get();
public abstract void set(RValue value);
public Collection<ReplacableValue> getSubValues() {
RValue value = get();
ArrayList<ReplacableValue> subValues = new ArrayList<>();
if (value instanceof PointerDereferenceIndexed) {
subValues.add(new ReplacablePointer((PointerDereference) value));
subValues.add(new ReplacablePointerIndex((PointerDereferenceIndexed) value));
} else if (value instanceof PointerDereferenceSimple) {
subValues.add(new ReplacablePointer((PointerDereference) value));
} else if (value instanceof ValueList) {
ValueList valueList = (ValueList) value;
int size = valueList.getList().size();
for (int i = 0; i < size; i++) {
subValues.add(new ReplacableListElement(valueList, i));
}
}
return subValues;
}
}
/** Replacable LValue as part of an assignment statement (or a call). */
public static class ReplacableLValue extends ReplacableValue {
private final StatementLValue statement;
public ReplacableLValue(StatementLValue statement) {
this.statement = statement;
}
@Override
public RValue get() {
return statement.getlValue();
}
@Override
public void set(RValue value) {
statement.setlValue((LValue) value);
}
}
/** Replacable pointer inside a pointer dererence value. */
public static class ReplacablePointer extends ReplacableValue {
private final PointerDereference pointer;
ReplacablePointer(PointerDereference pointer) {
this.pointer = pointer;
}
@Override
public RValue get() {
return pointer.getPointer();
}
@Override
public void set(RValue val) {
pointer.setPointer(val);
}
}
public static class ReplacableListElement extends ReplacableValue {
private ValueList list;
private int idx;
public ReplacableListElement(ValueList list, int idx) {
this.list = list;
this.idx = idx;
}
@Override
public RValue get() {
return list.getList().get(idx);
}
@Override
public void set(RValue value) {
list.getList().set(idx, value);
}
}
/** Replacable pointer index inside a indexed pointer dererence value. */
public static class ReplacablePointerIndex extends ReplacableValue {
private final PointerDereferenceIndexed pointer;
ReplacablePointerIndex(PointerDereferenceIndexed pointer) {
this.pointer = pointer;
}
@Override
public RValue get() {
return pointer.getIndex();
}
@Override
public void set(RValue val) {
pointer.setIndex(val);
}
}
public static class ReplacableRValue1 extends ReplacableValue {
private final StatementAssignment statement;
public ReplacableRValue1(StatementAssignment statement) {
this.statement = statement;
}
@Override
public RValue get() {
return statement.getrValue1();
}
@Override
public void set(RValue value) {
statement.setrValue1(value);
}
}
public static class ReplacableRValue2 extends ReplacableValue {
private final StatementAssignment statement;
public ReplacableRValue2(StatementAssignment statement) {
this.statement = statement;
}
@Override
public RValue get() {
return statement.getrValue2();
}
@Override
public void set(RValue value) {
statement.setrValue2(value);
}
}
public static class ReplacableCallParameter extends ReplacableValue {
private final StatementCall call;
private final int i;
public ReplacableCallParameter(StatementCall call, int i) {
this.call = call;
this.i = i;
}
@Override
public RValue get() {
return call.getParameters().get(i);
}
@Override
public void set(RValue value) {
call.getParameters().set(i, value);
}
}
public static class ReplacableCondRValue1 extends ReplacableValue {
private final StatementConditionalJump statement;
public ReplacableCondRValue1(StatementConditionalJump statement) {
this.statement = statement;
}
@Override
public RValue get() {
return statement.getrValue1();
}
@Override
public void set(RValue value) {
statement.setrValue1(value);
}
}
public static class ReplacableCondRValue2 extends ReplacableValue {
private final StatementConditionalJump statement;
public ReplacableCondRValue2(StatementConditionalJump statement) {
this.statement = statement;
}
@Override
public RValue get() {
return statement.getrValue2();
}
@Override
public void set(RValue value) {
statement.setrValue2(value);
}
}
public static class ReplacableReturn extends ReplacableValue {
private final StatementReturn statement;
public ReplacableReturn(StatementReturn statement) {
this.statement = statement;
}
@Override
public RValue get() {
return statement.getValue();
}
@Override
public void set(RValue value) {
statement.setValue(value);
}
}
public static class ReplacablePhiValue extends ReplacableValue {
private final StatementPhiBlock.PhiVariable phiVariable;
private final int i;
public ReplacablePhiValue(StatementPhiBlock.PhiVariable phiVariable, int i) {
this.phiVariable = phiVariable;
this.i = i;
}
@Override
public RValue get() {
return phiVariable.getValues().get(i).getrValue();
}
@Override
public void set(RValue value) {
phiVariable.getValues().get(i).setrValue(value);
}
}
/** Replacable LValue as part of an assignment statement (or a call). */
public static class ReplacablePhiVariable extends ReplacableValue {
private final StatementPhiBlock.PhiVariable phiVariable;
public ReplacablePhiVariable(StatementPhiBlock.PhiVariable phiVariable) {
this.phiVariable = phiVariable;
}
@Override
public RValue get() {
return phiVariable.getVariable();
}
@Override
public void set(RValue value) {
phiVariable.setVariable((VariableRef) value);
}
}
}

View File

@ -22,6 +22,10 @@ public class TestPrograms extends TestCase {
helper = new ReferenceHelper("dk/camelot64/kickc/test/ref/"); helper = new ReferenceHelper("dk/camelot64/kickc/test/ref/");
} }
public void testTrueInlineWords() throws IOException, URISyntaxException {
compileAndCompare("true-inline-words");
}
public void testIncrementInArray() throws IOException, URISyntaxException { public void testIncrementInArray() throws IOException, URISyntaxException {
compileAndCompare("incrementinarray"); compileAndCompare("incrementinarray");
} }

View File

@ -1,10 +1,10 @@
const byte* SCREEN = $400; const byte* SCREEN = $400;
void main() { void main() {
byte[] his = { >SCREEN, >SCREEN+$100, >SCREEN+$200 }; byte[] his = { >SCREEN, >SCREEN+$100, >SCREEN+$200 }; // constant array
for( byte h: 0..2) { for( byte h: 0..2) {
for (byte l: 4..7) { for (byte l: 4..7) {
word w = { his[h], l }; word w = { his[h], l }; // inline word
byte* sc = (byte*)w; byte* sc = (byte*)w;
*sc = '*'; *sc = '*';
} }

View File

@ -1135,8 +1135,6 @@ Eliminating unused variable - keeping the call (void~) line_xdyi::$1
Eliminating unused variable - keeping the call (void~) line_xdyd::$1 Eliminating unused variable - keeping the call (void~) line_xdyd::$1
Eliminating unused variable - keeping the call (void~) line_ydxi::$1 Eliminating unused variable - keeping the call (void~) line_ydxi::$1
Eliminating unused variable - keeping the call (void~) line_ydxd::$1 Eliminating unused variable - keeping the call (void~) line_ydxd::$1
Fixing word constructor with plot::plotter_x ← *(plot_xhi + plot::x) w= *(plot_xlo + plot::x)
Fixing word constructor with plot::plotter_y ← *(plot_yhi + plot::y) w= *(plot_ylo + plot::y)
Removing empty block main::@2 Removing empty block main::@2
Removing empty block @1 Removing empty block @1
Removing empty block lines::@2 Removing empty block lines::@2
@ -1413,8 +1411,8 @@ line_ydxd::@return: scope:[line_ydxd] from line_ydxd::@2
return return
to:@return to:@return
plot: scope:[plot] from plot: scope:[plot] from
(word) plot::plotter_x ← *((byte[]) plot_xhi + (byte) plot::x) w= *((byte[]) plot_xlo + (byte) plot::x) (word) plot::plotter_x ← { *((byte[]) plot_xhi + (byte) plot::x), *((byte[]) plot_xlo + (byte) plot::x) }
(word) plot::plotter_y ← *((byte[]) plot_yhi + (byte) plot::y) w= *((byte[]) plot_ylo + (byte) plot::y) (word) plot::plotter_y ← { *((byte[]) plot_yhi + (byte) plot::y), *((byte[]) plot_ylo + (byte) plot::y) }
(word~) plot::$0 ← (word) plot::plotter_x + (word) plot::plotter_y (word~) plot::$0 ← (word) plot::plotter_x + (word) plot::plotter_y
(byte*) plot::plotter ← ((byte*)) (word~) plot::$0 (byte*) plot::plotter ← ((byte*)) (word~) plot::$0
(byte~) plot::$1 ← *((byte*) plot::plotter) | *((byte[]) plot_bit + (byte) plot::x) (byte~) plot::$1 ← *((byte*) plot::plotter) | *((byte[]) plot_bit + (byte) plot::x)
@ -1835,8 +1833,8 @@ line_ydxd::@return: scope:[line_ydxd] from line_ydxd::@2
return return
to:@return to:@return
plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1 plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1
(word) plot::plotter_x ← *((byte[]) plot_xhi + (byte) plot::x) w= *((byte[]) plot_xlo + (byte) plot::x) (word) plot::plotter_x ← { *((byte[]) plot_xhi + (byte) plot::x), *((byte[]) plot_xlo + (byte) plot::x) }
(word) plot::plotter_y ← *((byte[]) plot_yhi + (byte) plot::y) w= *((byte[]) plot_ylo + (byte) plot::y) (word) plot::plotter_y ← { *((byte[]) plot_yhi + (byte) plot::y), *((byte[]) plot_ylo + (byte) plot::y) }
(word~) plot::$0 ← (word) plot::plotter_x + (word) plot::plotter_y (word~) plot::$0 ← (word) plot::plotter_x + (word) plot::plotter_y
(byte*) plot::plotter ← ((byte*)) (word~) plot::$0 (byte*) plot::plotter ← ((byte*)) (word~) plot::$0
(byte~) plot::$1 ← *((byte*) plot::plotter) | *((byte[]) plot_bit + (byte) plot::x) (byte~) plot::$1 ← *((byte*) plot::plotter) | *((byte[]) plot_bit + (byte) plot::x)
@ -2489,8 +2487,8 @@ line_ydxd::@return: scope:[line_ydxd] from line_ydxd::@2
plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1 plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1
(byte) plot::y#4 ← phi( line_xdyd::@1/(byte) plot::y#1 line_xdyi::@1/(byte) plot::y#0 line_ydxd::@1/(byte) plot::y#3 line_ydxi::@1/(byte) plot::y#2 ) (byte) plot::y#4 ← phi( line_xdyd::@1/(byte) plot::y#1 line_xdyi::@1/(byte) plot::y#0 line_ydxd::@1/(byte) plot::y#3 line_ydxi::@1/(byte) plot::y#2 )
(byte) plot::x#4 ← phi( line_xdyd::@1/(byte) plot::x#1 line_xdyi::@1/(byte) plot::x#0 line_ydxd::@1/(byte) plot::x#3 line_ydxi::@1/(byte) plot::x#2 ) (byte) plot::x#4 ← phi( line_xdyd::@1/(byte) plot::x#1 line_xdyi::@1/(byte) plot::x#0 line_ydxd::@1/(byte) plot::x#3 line_ydxi::@1/(byte) plot::x#2 )
(word) plot::plotter_x#0 ← *((byte[]) plot_xhi#0 + (byte) plot::x#4) w= *((byte[]) plot_xlo#0 + (byte) plot::x#4) (word) plot::plotter_x#0 ← { *((byte[]) plot_xhi#0 + (byte) plot::x#4), *((byte[]) plot_xlo#0 + (byte) plot::x#4) }
(word) plot::plotter_y#0 ← *((byte[]) plot_yhi#0 + (byte) plot::y#4) w= *((byte[]) plot_ylo#0 + (byte) plot::y#4) (word) plot::plotter_y#0 ← { *((byte[]) plot_yhi#0 + (byte) plot::y#4), *((byte[]) plot_ylo#0 + (byte) plot::y#4) }
(word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0 (word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0
(byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0 (byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0
(byte~) plot::$1 ← *((byte*) plot::plotter#0) | *((byte[]) plot_bit#0 + (byte) plot::x#4) (byte~) plot::$1 ← *((byte*) plot::plotter#0) | *((byte[]) plot_bit#0 + (byte) plot::x#4)
@ -3163,8 +3161,8 @@ line_ydxd::@return: scope:[line_ydxd] from line_ydxd::@2
plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1 plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1
(byte) plot::y#4 ← phi( line_xdyd::@1/(byte) plot::y#1 line_xdyi::@1/(byte) plot::y#0 line_ydxd::@1/(byte) plot::y#3 line_ydxi::@1/(byte) plot::y#2 ) (byte) plot::y#4 ← phi( line_xdyd::@1/(byte) plot::y#1 line_xdyi::@1/(byte) plot::y#0 line_ydxd::@1/(byte) plot::y#3 line_ydxi::@1/(byte) plot::y#2 )
(byte) plot::x#4 ← phi( line_xdyd::@1/(byte) plot::x#1 line_xdyi::@1/(byte) plot::x#0 line_ydxd::@1/(byte) plot::x#3 line_ydxi::@1/(byte) plot::x#2 ) (byte) plot::x#4 ← phi( line_xdyd::@1/(byte) plot::x#1 line_xdyi::@1/(byte) plot::x#0 line_ydxd::@1/(byte) plot::x#3 line_ydxi::@1/(byte) plot::x#2 )
(word) plot::plotter_x#0 ← *((byte[]) plot_xhi#0 + (byte) plot::x#4) w= *((byte[]) plot_xlo#0 + (byte) plot::x#4) (word) plot::plotter_x#0 ← { *((byte[]) plot_xhi#0 + (byte) plot::x#4), *((byte[]) plot_xlo#0 + (byte) plot::x#4) }
(word) plot::plotter_y#0 ← *((byte[]) plot_yhi#0 + (byte) plot::y#4) w= *((byte[]) plot_ylo#0 + (byte) plot::y#4) (word) plot::plotter_y#0 ← { *((byte[]) plot_yhi#0 + (byte) plot::y#4), *((byte[]) plot_ylo#0 + (byte) plot::y#4) }
(word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0 (word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0
(byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0 (byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0
(byte~) plot::$1 ← *((byte*) plot::plotter#0) | *((byte[]) plot_bit#0 + (byte) plot::x#4) (byte~) plot::$1 ← *((byte*) plot::plotter#0) | *((byte[]) plot_bit#0 + (byte) plot::x#4)
@ -4425,8 +4423,8 @@ line_ydxd::@return: scope:[line_ydxd] from line_ydxd::@2
plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1 plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1
(byte) plot::y#4 ← phi( line_xdyd::@1/(byte) plot::y#1 line_xdyi::@1/(byte) plot::y#0 line_ydxd::@1/(byte) plot::y#3 line_ydxi::@1/(byte) plot::y#2 ) (byte) plot::y#4 ← phi( line_xdyd::@1/(byte) plot::y#1 line_xdyi::@1/(byte) plot::y#0 line_ydxd::@1/(byte) plot::y#3 line_ydxi::@1/(byte) plot::y#2 )
(byte) plot::x#4 ← phi( line_xdyd::@1/(byte) plot::x#1 line_xdyi::@1/(byte) plot::x#0 line_ydxd::@1/(byte) plot::x#3 line_ydxi::@1/(byte) plot::x#2 ) (byte) plot::x#4 ← phi( line_xdyd::@1/(byte) plot::x#1 line_xdyi::@1/(byte) plot::x#0 line_ydxd::@1/(byte) plot::x#3 line_ydxi::@1/(byte) plot::x#2 )
(word) plot::plotter_x#0 ← *((byte[]) plot_xhi#0 + (byte) plot::x#4) w= *((byte[]) plot_xlo#0 + (byte) plot::x#4) (word) plot::plotter_x#0 ← { *((byte[]) plot_xhi#0 + (byte) plot::x#4), *((byte[]) plot_xlo#0 + (byte) plot::x#4) }
(word) plot::plotter_y#0 ← *((byte[]) plot_yhi#0 + (byte) plot::y#4) w= *((byte[]) plot_ylo#0 + (byte) plot::y#4) (word) plot::plotter_y#0 ← { *((byte[]) plot_yhi#0 + (byte) plot::y#4), *((byte[]) plot_ylo#0 + (byte) plot::y#4) }
(word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0 (word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0
(byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0 (byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0
(byte~) plot::$1 ← *((byte*) plot::plotter#0) | *((byte[]) plot_bit#0 + (byte) plot::x#4) (byte~) plot::$1 ← *((byte*) plot::plotter#0) | *((byte[]) plot_bit#0 + (byte) plot::x#4)
@ -5084,8 +5082,8 @@ line_ydxd::@return: scope:[line_ydxd] from line_ydxd::@2
plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1 plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1
(byte) plot::y#4 ← phi( line_xdyd::@1/(byte) plot::y#1 line_xdyi::@1/(byte) plot::y#0 line_ydxd::@1/(byte) plot::y#3 line_ydxi::@1/(byte) plot::y#2 ) (byte) plot::y#4 ← phi( line_xdyd::@1/(byte) plot::y#1 line_xdyi::@1/(byte) plot::y#0 line_ydxd::@1/(byte) plot::y#3 line_ydxi::@1/(byte) plot::y#2 )
(byte) plot::x#4 ← phi( line_xdyd::@1/(byte) plot::x#1 line_xdyi::@1/(byte) plot::x#0 line_ydxd::@1/(byte) plot::x#3 line_ydxi::@1/(byte) plot::x#2 ) (byte) plot::x#4 ← phi( line_xdyd::@1/(byte) plot::x#1 line_xdyi::@1/(byte) plot::x#0 line_ydxd::@1/(byte) plot::x#3 line_ydxi::@1/(byte) plot::x#2 )
(word) plot::plotter_x#0 ← *((byte[]) plot_xhi#0 + (byte) plot::x#4) w= *((byte[]) plot_xlo#0 + (byte) plot::x#4) (word) plot::plotter_x#0 ← { *((byte[]) plot_xhi#0 + (byte) plot::x#4), *((byte[]) plot_xlo#0 + (byte) plot::x#4) }
(word) plot::plotter_y#0 ← *((byte[]) plot_yhi#0 + (byte) plot::y#4) w= *((byte[]) plot_ylo#0 + (byte) plot::y#4) (word) plot::plotter_y#0 ← { *((byte[]) plot_yhi#0 + (byte) plot::y#4), *((byte[]) plot_ylo#0 + (byte) plot::y#4) }
(word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0 (word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0
(byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0 (byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0
(byte~) plot::$1 ← *((byte*) plot::plotter#0) | *((byte[]) plot_bit#0 + (byte) plot::x#4) (byte~) plot::$1 ← *((byte*) plot::plotter#0) | *((byte[]) plot_bit#0 + (byte) plot::x#4)
@ -5746,8 +5744,8 @@ line_ydxd::@return: scope:[line_ydxd] from line_ydxd::@2
plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1 plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1
(byte) plot::y#4 ← phi( line_xdyd::@1/(byte) plot::y#1 line_xdyi::@1/(byte) plot::y#0 line_ydxd::@1/(byte) plot::y#3 line_ydxi::@1/(byte) plot::y#2 ) (byte) plot::y#4 ← phi( line_xdyd::@1/(byte) plot::y#1 line_xdyi::@1/(byte) plot::y#0 line_ydxd::@1/(byte) plot::y#3 line_ydxi::@1/(byte) plot::y#2 )
(byte) plot::x#4 ← phi( line_xdyd::@1/(byte) plot::x#1 line_xdyi::@1/(byte) plot::x#0 line_ydxd::@1/(byte) plot::x#3 line_ydxi::@1/(byte) plot::x#2 ) (byte) plot::x#4 ← phi( line_xdyd::@1/(byte) plot::x#1 line_xdyi::@1/(byte) plot::x#0 line_ydxd::@1/(byte) plot::x#3 line_ydxi::@1/(byte) plot::x#2 )
(word) plot::plotter_x#0 ← *((byte[]) plot_xhi#0 + (byte) plot::x#4) w= *((byte[]) plot_xlo#0 + (byte) plot::x#4) (word) plot::plotter_x#0 ← { *((byte[]) plot_xhi#0 + (byte) plot::x#4), *((byte[]) plot_xlo#0 + (byte) plot::x#4) }
(word) plot::plotter_y#0 ← *((byte[]) plot_yhi#0 + (byte) plot::y#4) w= *((byte[]) plot_ylo#0 + (byte) plot::y#4) (word) plot::plotter_y#0 ← { *((byte[]) plot_yhi#0 + (byte) plot::y#4), *((byte[]) plot_ylo#0 + (byte) plot::y#4) }
(word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0 (word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0
(byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0 (byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0
(byte~) plot::$1 ← *((byte*) plot::plotter#0) | *((byte[]) plot_bit#0 + (byte) plot::x#4) (byte~) plot::$1 ← *((byte*) plot::plotter#0) | *((byte[]) plot_bit#0 + (byte) plot::x#4)
@ -6312,8 +6310,8 @@ line_ydxd::@return: scope:[line_ydxd] from line_ydxd::@2
plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1 plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1
(byte) plot::y#4 ← phi( line_xdyd::@1/(byte) plot::y#1 line_xdyi::@1/(byte) plot::y#0 line_ydxd::@1/(byte) plot::y#3 line_ydxi::@1/(byte) plot::y#2 ) (byte) plot::y#4 ← phi( line_xdyd::@1/(byte) plot::y#1 line_xdyi::@1/(byte) plot::y#0 line_ydxd::@1/(byte) plot::y#3 line_ydxi::@1/(byte) plot::y#2 )
(byte) plot::x#4 ← phi( line_xdyd::@1/(byte) plot::x#1 line_xdyi::@1/(byte) plot::x#0 line_ydxd::@1/(byte) plot::x#3 line_ydxi::@1/(byte) plot::x#2 ) (byte) plot::x#4 ← phi( line_xdyd::@1/(byte) plot::x#1 line_xdyi::@1/(byte) plot::x#0 line_ydxd::@1/(byte) plot::x#3 line_ydxi::@1/(byte) plot::x#2 )
(word) plot::plotter_x#0 ← *((byte[]) plot_xhi#0 + (byte) plot::x#4) w= *((byte[]) plot_xlo#0 + (byte) plot::x#4) (word) plot::plotter_x#0 ← { *((byte[]) plot_xhi#0 + (byte) plot::x#4), *((byte[]) plot_xlo#0 + (byte) plot::x#4) }
(word) plot::plotter_y#0 ← *((byte[]) plot_yhi#0 + (byte) plot::y#4) w= *((byte[]) plot_ylo#0 + (byte) plot::y#4) (word) plot::plotter_y#0 ← { *((byte[]) plot_yhi#0 + (byte) plot::y#4), *((byte[]) plot_ylo#0 + (byte) plot::y#4) }
(word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0 (word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0
(byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0 (byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0
(byte~) plot::$1 ← *((byte*) plot::plotter#0) | *((byte[]) plot_bit#0 + (byte) plot::x#4) (byte~) plot::$1 ← *((byte*) plot::plotter#0) | *((byte[]) plot_bit#0 + (byte) plot::x#4)
@ -6878,8 +6876,8 @@ line_ydxd::@return: scope:[line_ydxd] from line_ydxd::@2
plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1 plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1
(byte) plot::y#4 ← phi( line_xdyd::@1/(byte) plot::y#1 line_xdyi::@1/(byte) plot::y#0 line_ydxd::@1/(byte) plot::y#3 line_ydxi::@1/(byte) plot::y#2 ) (byte) plot::y#4 ← phi( line_xdyd::@1/(byte) plot::y#1 line_xdyi::@1/(byte) plot::y#0 line_ydxd::@1/(byte) plot::y#3 line_ydxi::@1/(byte) plot::y#2 )
(byte) plot::x#4 ← phi( line_xdyd::@1/(byte) plot::x#1 line_xdyi::@1/(byte) plot::x#0 line_ydxd::@1/(byte) plot::x#3 line_ydxi::@1/(byte) plot::x#2 ) (byte) plot::x#4 ← phi( line_xdyd::@1/(byte) plot::x#1 line_xdyi::@1/(byte) plot::x#0 line_ydxd::@1/(byte) plot::x#3 line_ydxi::@1/(byte) plot::x#2 )
(word) plot::plotter_x#0 ← *((byte[]) plot_xhi#0 + (byte) plot::x#4) w= *((byte[]) plot_xlo#0 + (byte) plot::x#4) (word) plot::plotter_x#0 ← { *((byte[]) plot_xhi#0 + (byte) plot::x#4), *((byte[]) plot_xlo#0 + (byte) plot::x#4) }
(word) plot::plotter_y#0 ← *((byte[]) plot_yhi#0 + (byte) plot::y#4) w= *((byte[]) plot_ylo#0 + (byte) plot::y#4) (word) plot::plotter_y#0 ← { *((byte[]) plot_yhi#0 + (byte) plot::y#4), *((byte[]) plot_ylo#0 + (byte) plot::y#4) }
(word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0 (word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0
(byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0 (byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0
(byte~) plot::$1 ← *((byte*) plot::plotter#0) | *((byte[]) plot_bit#0 + (byte) plot::x#4) (byte~) plot::$1 ← *((byte*) plot::plotter#0) | *((byte[]) plot_bit#0 + (byte) plot::x#4)
@ -7335,8 +7333,8 @@ line_ydxd::@return: scope:[line_ydxd] from line_ydxd::@2
plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1 plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1
(byte) plot::y#4 ← phi( line_xdyd::@1/(byte) plot::y#1 line_xdyi::@1/(byte) plot::y#0 line_ydxd::@1/(byte) plot::y#3 line_ydxi::@1/(byte) plot::y#2 ) (byte) plot::y#4 ← phi( line_xdyd::@1/(byte) plot::y#1 line_xdyi::@1/(byte) plot::y#0 line_ydxd::@1/(byte) plot::y#3 line_ydxi::@1/(byte) plot::y#2 )
(byte) plot::x#4 ← phi( line_xdyd::@1/(byte) plot::x#1 line_xdyi::@1/(byte) plot::x#0 line_ydxd::@1/(byte) plot::x#3 line_ydxi::@1/(byte) plot::x#2 ) (byte) plot::x#4 ← phi( line_xdyd::@1/(byte) plot::x#1 line_xdyi::@1/(byte) plot::x#0 line_ydxd::@1/(byte) plot::x#3 line_ydxi::@1/(byte) plot::x#2 )
(word) plot::plotter_x#0 ← *((byte[]) plot_xhi#0 + (byte) plot::x#4) w= *((byte[]) plot_xlo#0 + (byte) plot::x#4) (word) plot::plotter_x#0 ← { *((byte[]) plot_xhi#0 + (byte) plot::x#4), *((byte[]) plot_xlo#0 + (byte) plot::x#4) }
(word) plot::plotter_y#0 ← *((byte[]) plot_yhi#0 + (byte) plot::y#4) w= *((byte[]) plot_ylo#0 + (byte) plot::y#4) (word) plot::plotter_y#0 ← { *((byte[]) plot_yhi#0 + (byte) plot::y#4), *((byte[]) plot_ylo#0 + (byte) plot::y#4) }
(word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0 (word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0
(byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0 (byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0
(byte~) plot::$1 ← *((byte*) plot::plotter#0) | *((byte[]) plot_bit#0 + (byte) plot::x#4) (byte~) plot::$1 ← *((byte*) plot::plotter#0) | *((byte[]) plot_bit#0 + (byte) plot::x#4)
@ -7756,8 +7754,8 @@ line_ydxd::@return: scope:[line_ydxd] from line_ydxd::@2
plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1 plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1
(byte) plot::y#4 ← phi( line_xdyd::@1/(byte) plot::y#1 line_xdyi::@1/(byte) plot::y#0 line_ydxd::@1/(byte) plot::y#3 line_ydxi::@1/(byte) plot::y#2 ) (byte) plot::y#4 ← phi( line_xdyd::@1/(byte) plot::y#1 line_xdyi::@1/(byte) plot::y#0 line_ydxd::@1/(byte) plot::y#3 line_ydxi::@1/(byte) plot::y#2 )
(byte) plot::x#4 ← phi( line_xdyd::@1/(byte) plot::x#1 line_xdyi::@1/(byte) plot::x#0 line_ydxd::@1/(byte) plot::x#3 line_ydxi::@1/(byte) plot::x#2 ) (byte) plot::x#4 ← phi( line_xdyd::@1/(byte) plot::x#1 line_xdyi::@1/(byte) plot::x#0 line_ydxd::@1/(byte) plot::x#3 line_ydxi::@1/(byte) plot::x#2 )
(word) plot::plotter_x#0 ← *((byte[]) plot_xhi#0 + (byte) plot::x#4) w= *((byte[]) plot_xlo#0 + (byte) plot::x#4) (word) plot::plotter_x#0 ← { *((byte[]) plot_xhi#0 + (byte) plot::x#4), *((byte[]) plot_xlo#0 + (byte) plot::x#4) }
(word) plot::plotter_y#0 ← *((byte[]) plot_yhi#0 + (byte) plot::y#4) w= *((byte[]) plot_ylo#0 + (byte) plot::y#4) (word) plot::plotter_y#0 ← { *((byte[]) plot_yhi#0 + (byte) plot::y#4), *((byte[]) plot_ylo#0 + (byte) plot::y#4) }
(word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0 (word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0
(byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0 (byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0
(byte~) plot::$1 ← *((byte*) plot::plotter#0) | *((byte[]) plot_bit#0 + (byte) plot::x#4) (byte~) plot::$1 ← *((byte*) plot::plotter#0) | *((byte[]) plot_bit#0 + (byte) plot::x#4)
@ -8155,8 +8153,8 @@ line_ydxd::@return: scope:[line_ydxd] from line_ydxd::@2
plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1 plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1
(byte) plot::y#4 ← phi( line_xdyd::@1/(byte) plot::y#1 line_xdyi::@1/(byte) plot::y#0 line_ydxd::@1/(byte) plot::y#3 line_ydxi::@1/(byte) plot::y#2 ) (byte) plot::y#4 ← phi( line_xdyd::@1/(byte) plot::y#1 line_xdyi::@1/(byte) plot::y#0 line_ydxd::@1/(byte) plot::y#3 line_ydxi::@1/(byte) plot::y#2 )
(byte) plot::x#4 ← phi( line_xdyd::@1/(byte) plot::x#1 line_xdyi::@1/(byte) plot::x#0 line_ydxd::@1/(byte) plot::x#3 line_ydxi::@1/(byte) plot::x#2 ) (byte) plot::x#4 ← phi( line_xdyd::@1/(byte) plot::x#1 line_xdyi::@1/(byte) plot::x#0 line_ydxd::@1/(byte) plot::x#3 line_ydxi::@1/(byte) plot::x#2 )
(word) plot::plotter_x#0 ← *((const byte[]) plot_xhi#0 + (byte) plot::x#4) w= *((const byte[]) plot_xlo#0 + (byte) plot::x#4) (word) plot::plotter_x#0 ← { *((const byte[]) plot_xhi#0 + (byte) plot::x#4), *((const byte[]) plot_xlo#0 + (byte) plot::x#4) }
(word) plot::plotter_y#0 ← *((const byte[]) plot_yhi#0 + (byte) plot::y#4) w= *((const byte[]) plot_ylo#0 + (byte) plot::y#4) (word) plot::plotter_y#0 ← { *((const byte[]) plot_yhi#0 + (byte) plot::y#4), *((const byte[]) plot_ylo#0 + (byte) plot::y#4) }
(word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0 (word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0
(byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0 (byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0
(byte~) plot::$1 ← *((byte*) plot::plotter#0) | *((const byte[]) plot_bit#0 + (byte) plot::x#4) (byte~) plot::$1 ← *((byte*) plot::plotter#0) | *((const byte[]) plot_bit#0 + (byte) plot::x#4)
@ -8529,8 +8527,8 @@ line_ydxd::@return: scope:[line_ydxd] from line_ydxd::@2
plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1 plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1
(byte) plot::y#4 ← phi( line_xdyd::@1/(byte) plot::y#1 line_xdyi::@1/(byte) plot::y#0 line_ydxd::@1/(byte) plot::y#3 line_ydxi::@1/(byte) plot::y#2 ) (byte) plot::y#4 ← phi( line_xdyd::@1/(byte) plot::y#1 line_xdyi::@1/(byte) plot::y#0 line_ydxd::@1/(byte) plot::y#3 line_ydxi::@1/(byte) plot::y#2 )
(byte) plot::x#4 ← phi( line_xdyd::@1/(byte) plot::x#1 line_xdyi::@1/(byte) plot::x#0 line_ydxd::@1/(byte) plot::x#3 line_ydxi::@1/(byte) plot::x#2 ) (byte) plot::x#4 ← phi( line_xdyd::@1/(byte) plot::x#1 line_xdyi::@1/(byte) plot::x#0 line_ydxd::@1/(byte) plot::x#3 line_ydxi::@1/(byte) plot::x#2 )
(word) plot::plotter_x#0 ← *((const byte[]) plot_xhi#0 + (byte) plot::x#4) w= *((const byte[]) plot_xlo#0 + (byte) plot::x#4) (word) plot::plotter_x#0 ← { *((const byte[]) plot_xhi#0 + (byte) plot::x#4), *((const byte[]) plot_xlo#0 + (byte) plot::x#4) }
(word) plot::plotter_y#0 ← *((const byte[]) plot_yhi#0 + (byte) plot::y#4) w= *((const byte[]) plot_ylo#0 + (byte) plot::y#4) (word) plot::plotter_y#0 ← { *((const byte[]) plot_yhi#0 + (byte) plot::y#4), *((const byte[]) plot_ylo#0 + (byte) plot::y#4) }
(word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0 (word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0
(byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0 (byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0
(byte~) plot::$1 ← *((byte*) plot::plotter#0) | *((const byte[]) plot_bit#0 + (byte) plot::x#4) (byte~) plot::$1 ← *((byte*) plot::plotter#0) | *((const byte[]) plot_bit#0 + (byte) plot::x#4)
@ -8890,8 +8888,8 @@ line_ydxd::@return: scope:[line_ydxd] from line_ydxd::@2
plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1 plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1
(byte) plot::y#4 ← phi( line_xdyd::@1/(byte) plot::y#1 line_xdyi::@1/(byte) plot::y#0 line_ydxd::@1/(byte) plot::y#3 line_ydxi::@1/(byte) plot::y#2 ) (byte) plot::y#4 ← phi( line_xdyd::@1/(byte) plot::y#1 line_xdyi::@1/(byte) plot::y#0 line_ydxd::@1/(byte) plot::y#3 line_ydxi::@1/(byte) plot::y#2 )
(byte) plot::x#4 ← phi( line_xdyd::@1/(byte) plot::x#1 line_xdyi::@1/(byte) plot::x#0 line_ydxd::@1/(byte) plot::x#3 line_ydxi::@1/(byte) plot::x#2 ) (byte) plot::x#4 ← phi( line_xdyd::@1/(byte) plot::x#1 line_xdyi::@1/(byte) plot::x#0 line_ydxd::@1/(byte) plot::x#3 line_ydxi::@1/(byte) plot::x#2 )
(word) plot::plotter_x#0 ← *((const byte[]) plot_xhi#0 + (byte) plot::x#4) w= *((const byte[]) plot_xlo#0 + (byte) plot::x#4) (word) plot::plotter_x#0 ← { *((const byte[]) plot_xhi#0 + (byte) plot::x#4), *((const byte[]) plot_xlo#0 + (byte) plot::x#4) }
(word) plot::plotter_y#0 ← *((const byte[]) plot_yhi#0 + (byte) plot::y#4) w= *((const byte[]) plot_ylo#0 + (byte) plot::y#4) (word) plot::plotter_y#0 ← { *((const byte[]) plot_yhi#0 + (byte) plot::y#4), *((const byte[]) plot_ylo#0 + (byte) plot::y#4) }
(word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0 (word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0
(byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0 (byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0
(byte~) plot::$1 ← *((byte*) plot::plotter#0) | *((const byte[]) plot_bit#0 + (byte) plot::x#4) (byte~) plot::$1 ← *((byte*) plot::plotter#0) | *((const byte[]) plot_bit#0 + (byte) plot::x#4)
@ -9248,8 +9246,8 @@ line_ydxd::@return: scope:[line_ydxd] from line_ydxd::@2
plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1 plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1
(byte) plot::y#4 ← phi( line_xdyd::@1/(byte) plot::y#1 line_xdyi::@1/(byte) plot::y#0 line_ydxd::@1/(byte) plot::y#3 line_ydxi::@1/(byte) plot::y#2 ) (byte) plot::y#4 ← phi( line_xdyd::@1/(byte) plot::y#1 line_xdyi::@1/(byte) plot::y#0 line_ydxd::@1/(byte) plot::y#3 line_ydxi::@1/(byte) plot::y#2 )
(byte) plot::x#4 ← phi( line_xdyd::@1/(byte) plot::x#1 line_xdyi::@1/(byte) plot::x#0 line_ydxd::@1/(byte) plot::x#3 line_ydxi::@1/(byte) plot::x#2 ) (byte) plot::x#4 ← phi( line_xdyd::@1/(byte) plot::x#1 line_xdyi::@1/(byte) plot::x#0 line_ydxd::@1/(byte) plot::x#3 line_ydxi::@1/(byte) plot::x#2 )
(word) plot::plotter_x#0 ← *((const byte[]) plot_xhi#0 + (byte) plot::x#4) w= *((const byte[]) plot_xlo#0 + (byte) plot::x#4) (word) plot::plotter_x#0 ← { *((const byte[]) plot_xhi#0 + (byte) plot::x#4), *((const byte[]) plot_xlo#0 + (byte) plot::x#4) }
(word) plot::plotter_y#0 ← *((const byte[]) plot_yhi#0 + (byte) plot::y#4) w= *((const byte[]) plot_ylo#0 + (byte) plot::y#4) (word) plot::plotter_y#0 ← { *((const byte[]) plot_yhi#0 + (byte) plot::y#4), *((const byte[]) plot_ylo#0 + (byte) plot::y#4) }
(word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0 (word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0
(byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0 (byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0
(byte~) plot::$1 ← *((byte*) plot::plotter#0) | *((const byte[]) plot_bit#0 + (byte) plot::x#4) (byte~) plot::$1 ← *((byte*) plot::plotter#0) | *((const byte[]) plot_bit#0 + (byte) plot::x#4)
@ -9604,8 +9602,8 @@ line_ydxd::@return: scope:[line_ydxd] from line_ydxd::@2
plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1 plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1
(byte) plot::y#4 ← phi( line_xdyd::@1/(byte) plot::y#1 line_xdyi::@1/(byte) plot::y#0 line_ydxd::@1/(byte) plot::y#3 line_ydxi::@1/(byte) plot::y#2 ) (byte) plot::y#4 ← phi( line_xdyd::@1/(byte) plot::y#1 line_xdyi::@1/(byte) plot::y#0 line_ydxd::@1/(byte) plot::y#3 line_ydxi::@1/(byte) plot::y#2 )
(byte) plot::x#4 ← phi( line_xdyd::@1/(byte) plot::x#1 line_xdyi::@1/(byte) plot::x#0 line_ydxd::@1/(byte) plot::x#3 line_ydxi::@1/(byte) plot::x#2 ) (byte) plot::x#4 ← phi( line_xdyd::@1/(byte) plot::x#1 line_xdyi::@1/(byte) plot::x#0 line_ydxd::@1/(byte) plot::x#3 line_ydxi::@1/(byte) plot::x#2 )
(word) plot::plotter_x#0 ← *((const byte[]) plot_xhi#0 + (byte) plot::x#4) w= *((const byte[]) plot_xlo#0 + (byte) plot::x#4) (word) plot::plotter_x#0 ← { *((const byte[]) plot_xhi#0 + (byte) plot::x#4), *((const byte[]) plot_xlo#0 + (byte) plot::x#4) }
(word) plot::plotter_y#0 ← *((const byte[]) plot_yhi#0 + (byte) plot::y#4) w= *((const byte[]) plot_ylo#0 + (byte) plot::y#4) (word) plot::plotter_y#0 ← { *((const byte[]) plot_yhi#0 + (byte) plot::y#4), *((const byte[]) plot_ylo#0 + (byte) plot::y#4) }
(word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0 (word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0
(byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0 (byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0
(byte~) plot::$1 ← *((byte*) plot::plotter#0) | *((const byte[]) plot_bit#0 + (byte) plot::x#4) (byte~) plot::$1 ← *((byte*) plot::plotter#0) | *((const byte[]) plot_bit#0 + (byte) plot::x#4)
@ -9977,8 +9975,8 @@ line_ydxd::@return: scope:[line_ydxd] from line_ydxd::@2
plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1 plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1
(byte) plot::y#4 ← phi( line_xdyd::@1/(byte) plot::y#1 line_xdyi::@1/(byte) plot::y#0 line_ydxd::@1/(byte) plot::y#3 line_ydxi::@1/(byte) plot::y#2 ) (byte) plot::y#4 ← phi( line_xdyd::@1/(byte) plot::y#1 line_xdyi::@1/(byte) plot::y#0 line_ydxd::@1/(byte) plot::y#3 line_ydxi::@1/(byte) plot::y#2 )
(byte) plot::x#4 ← phi( line_xdyd::@1/(byte) plot::x#1 line_xdyi::@1/(byte) plot::x#0 line_ydxd::@1/(byte) plot::x#3 line_ydxi::@1/(byte) plot::x#2 ) (byte) plot::x#4 ← phi( line_xdyd::@1/(byte) plot::x#1 line_xdyi::@1/(byte) plot::x#0 line_ydxd::@1/(byte) plot::x#3 line_ydxi::@1/(byte) plot::x#2 )
(word) plot::plotter_x#0 ← *((const byte[]) plot_xhi#0 + (byte) plot::x#4) w= *((const byte[]) plot_xlo#0 + (byte) plot::x#4) (word) plot::plotter_x#0 ← { *((const byte[]) plot_xhi#0 + (byte) plot::x#4), *((const byte[]) plot_xlo#0 + (byte) plot::x#4) }
(word) plot::plotter_y#0 ← *((const byte[]) plot_yhi#0 + (byte) plot::y#4) w= *((const byte[]) plot_ylo#0 + (byte) plot::y#4) (word) plot::plotter_y#0 ← { *((const byte[]) plot_yhi#0 + (byte) plot::y#4), *((const byte[]) plot_ylo#0 + (byte) plot::y#4) }
(word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0 (word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0
(byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0 (byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0
(byte~) plot::$1 ← *((byte*) plot::plotter#0) | *((const byte[]) plot_bit#0 + (byte) plot::x#4) (byte~) plot::$1 ← *((byte*) plot::plotter#0) | *((const byte[]) plot_bit#0 + (byte) plot::x#4)
@ -10069,6 +10067,363 @@ Multiple usages for variable. Not optimizing sub-constant (byte) init_plot_table
Multiple usages for variable. Not optimizing sub-constant (byte) init_plot_tables::y#2 Multiple usages for variable. Not optimizing sub-constant (byte) init_plot_tables::y#2
Multiple usages for variable. Not optimizing sub-constant (byte) init_plot_tables::y#2 Multiple usages for variable. Not optimizing sub-constant (byte) init_plot_tables::y#2
Multiple usages for variable. Not optimizing sub-constant (byte*) init_plot_tables::yoffs#2 Multiple usages for variable. Not optimizing sub-constant (byte*) init_plot_tables::yoffs#2
Fixing word constructor with plot::plotter_x#0 ← *(plot_xhi#0 + plot::x#4) w= *(plot_xlo#0 + plot::x#4)
Fixing word constructor with plot::plotter_y#0 ← *(plot_yhi#0 + plot::y#4) w= *(plot_ylo#0 + plot::y#4)
Succesful SSA optimization Pass2FixWordConstructors
CONTROL FLOW GRAPH
@begin: scope:[] from
to:@10
main: scope:[main] from @10
*((const byte*) BGCOL#0) ← (byte/signed byte/word/signed word) 0
*((const byte*) FGCOL#0) ← (byte/signed byte/word/signed word) 0
*((const byte*) D011#0) ← (const byte) main::$2
*((const byte*) D018#0) ← (const byte) main::$8
call init_screen param-assignment
to:main::@3
main::@3: scope:[main] from main
call init_plot_tables param-assignment
to:main::@4
main::@4: scope:[main] from main::@3
to:main::@1
main::@1: scope:[main] from main::@4 main::@5
call lines param-assignment
to:main::@5
main::@5: scope:[main] from main::@1
if(true) goto main::@1
to:main::@return
main::@return: scope:[main] from main::@5
return
to:@return
lines: scope:[lines] from main::@1
to:lines::@1
lines::@1: scope:[lines] from lines lines::@3
(byte) lines::l#2 ← phi( lines/(const byte) lines::l#0 lines::@3/(byte) lines::l#1 )
(byte~) lines::$0 ← (byte) lines::l#2
(byte~) lines::$1 ← (byte) lines::l#2
(byte) line::x0#0 ← *((const byte[]) lines_x#0 + (byte) lines::l#2)
(byte) line::x1#0 ← *((const byte[]) lines_x#0+(byte/signed byte/word/signed word) 1 + (byte~) lines::$0)
(byte) line::y0#0 ← *((const byte[]) lines_y#0 + (byte) lines::l#2)
(byte) line::y1#0 ← *((const byte[]) lines_y#0+(byte/signed byte/word/signed word) 1 + (byte~) lines::$1)
call line param-assignment
to:lines::@3
lines::@3: scope:[lines] from lines::@1
(byte) lines::l#1 ← ++ (byte) lines::l#2
if((byte) lines::l#1<(const byte) lines_cnt#0) goto lines::@1
to:lines::@return
lines::@return: scope:[lines] from lines::@3
return
to:@return
line: scope:[line] from lines::@1
if((byte) line::x0#0>=(byte) line::x1#0) goto line::@1
to:line::@15
line::@1: scope:[line] from line
(byte) line::xd#0 ← (byte) line::x0#0 - (byte) line::x1#0
if((byte) line::y0#0>=(byte) line::y1#0) goto line::@9
to:line::@23
line::@15: scope:[line] from line
(byte) line::xd#1 ← (byte) line::x1#0 - (byte) line::x0#0
if((byte) line::y0#0>=(byte) line::y1#0) goto line::@2
to:line::@16
line::@2: scope:[line] from line::@15
(byte) line::yd#0 ← (byte) line::y0#0 - (byte) line::y1#0
if((byte) line::yd#0>=(byte) line::xd#1) goto line::@6
to:line::@20
line::@16: scope:[line] from line::@15
(byte) line::yd#1 ← (byte) line::y1#0 - (byte) line::y0#0
if((byte) line::yd#1>=(byte) line::xd#1) goto line::@3
to:line::@17
line::@3: scope:[line] from line::@16
(byte) line_ydxi::y#0 ← (byte) line::y0#0
(byte) line_ydxi::x#0 ← (byte) line::x0#0
(byte) line_ydxi::y1#0 ← (byte) line::y1#0
(byte) line_ydxi::yd#0 ← (byte) line::yd#1
(byte) line_ydxi::xd#0 ← (byte) line::xd#1
call line_ydxi param-assignment
to:line::@return
line::@17: scope:[line] from line::@16
(byte) line_xdyi::x#0 ← (byte) line::x0#0
(byte) line_xdyi::y#0 ← (byte) line::y0#0
(byte) line_xdyi::x1#0 ← (byte) line::x1#0
(byte) line_xdyi::xd#0 ← (byte) line::xd#1
(byte) line_xdyi::yd#0 ← (byte) line::yd#1
call line_xdyi param-assignment
to:line::@return
line::@6: scope:[line] from line::@2
(byte) line_ydxd::y#0 ← (byte) line::y1#0
(byte) line_ydxd::x#0 ← (byte) line::x1#0
(byte) line_ydxd::y1#0 ← (byte) line::y0#0
(byte) line_ydxd::yd#0 ← (byte) line::yd#0
(byte) line_ydxd::xd#0 ← (byte) line::xd#1
call line_ydxd param-assignment
to:line::@return
line::@20: scope:[line] from line::@2
(byte) line_xdyd::x#0 ← (byte) line::x0#0
(byte) line_xdyd::y#0 ← (byte) line::y0#0
(byte) line_xdyd::x1#0 ← (byte) line::x1#0
(byte) line_xdyd::xd#0 ← (byte) line::xd#1
(byte) line_xdyd::yd#0 ← (byte) line::yd#0
call line_xdyd param-assignment
to:line::@return
line::@9: scope:[line] from line::@1
(byte) line::yd#10 ← (byte) line::y0#0 - (byte) line::y1#0
if((byte) line::yd#10>=(byte) line::xd#0) goto line::@13
to:line::@27
line::@23: scope:[line] from line::@1
(byte) line::yd#3 ← (byte) line::y1#0 - (byte) line::y0#0
if((byte) line::yd#3>=(byte) line::xd#0) goto line::@10
to:line::@24
line::@10: scope:[line] from line::@23
(byte) line_ydxd::y#1 ← (byte) line::y0#0
(byte) line_ydxd::x#1 ← (byte) line::x0#0
(byte) line_ydxd::y1#1 ← (byte) line::y1#0
(byte) line_ydxd::yd#1 ← (byte) line::yd#3
(byte) line_ydxd::xd#1 ← (byte) line::xd#0
call line_ydxd param-assignment
to:line::@return
line::@24: scope:[line] from line::@23
(byte) line_xdyd::x#1 ← (byte) line::x1#0
(byte) line_xdyd::y#1 ← (byte) line::y1#0
(byte) line_xdyd::x1#1 ← (byte) line::x0#0
(byte) line_xdyd::xd#1 ← (byte) line::xd#0
(byte) line_xdyd::yd#1 ← (byte) line::yd#3
call line_xdyd param-assignment
to:line::@return
line::@13: scope:[line] from line::@9
(byte) line_ydxi::y#1 ← (byte) line::y1#0
(byte) line_ydxi::x#1 ← (byte) line::x1#0
(byte) line_ydxi::y1#1 ← (byte) line::y0#0
(byte) line_ydxi::yd#1 ← (byte) line::yd#10
(byte) line_ydxi::xd#1 ← (byte) line::xd#0
call line_ydxi param-assignment
to:line::@return
line::@27: scope:[line] from line::@9
(byte) line_xdyi::x#1 ← (byte) line::x1#0
(byte) line_xdyi::y#1 ← (byte) line::y1#0
(byte) line_xdyi::x1#1 ← (byte) line::x0#0
(byte) line_xdyi::xd#1 ← (byte) line::xd#0
(byte) line_xdyi::yd#1 ← (byte) line::yd#10
call line_xdyi param-assignment
to:line::@return
line::@return: scope:[line] from line::@10 line::@13 line::@17 line::@20 line::@24 line::@27 line::@3 line::@6
return
to:@return
line_xdyi: scope:[line_xdyi] from line::@17 line::@27
(byte) line_xdyi::x1#6 ← phi( line::@17/(byte) line_xdyi::x1#0 line::@27/(byte) line_xdyi::x1#1 )
(byte) line_xdyi::xd#5 ← phi( line::@17/(byte) line_xdyi::xd#0 line::@27/(byte) line_xdyi::xd#1 )
(byte) line_xdyi::y#5 ← phi( line::@17/(byte) line_xdyi::y#0 line::@27/(byte) line_xdyi::y#1 )
(byte) line_xdyi::x#6 ← phi( line::@17/(byte) line_xdyi::x#0 line::@27/(byte) line_xdyi::x#1 )
(byte) line_xdyi::yd#2 ← phi( line::@17/(byte) line_xdyi::yd#0 line::@27/(byte) line_xdyi::yd#1 )
(byte) line_xdyi::e#0 ← (byte) line_xdyi::yd#2 >> (byte/signed byte/word/signed word) 1
to:line_xdyi::@1
line_xdyi::@1: scope:[line_xdyi] from line_xdyi line_xdyi::@2
(byte) line_xdyi::e#3 ← phi( line_xdyi/(byte) line_xdyi::e#0 line_xdyi::@2/(byte) line_xdyi::e#6 )
(byte) line_xdyi::y#3 ← phi( line_xdyi/(byte) line_xdyi::y#5 line_xdyi::@2/(byte) line_xdyi::y#6 )
(byte) line_xdyi::x#3 ← phi( line_xdyi/(byte) line_xdyi::x#6 line_xdyi::@2/(byte) line_xdyi::x#2 )
(byte) plot::x#0 ← (byte) line_xdyi::x#3
(byte) plot::y#0 ← (byte) line_xdyi::y#3
call plot param-assignment
to:line_xdyi::@5
line_xdyi::@5: scope:[line_xdyi] from line_xdyi::@1
(byte) line_xdyi::x#2 ← (byte) line_xdyi::x#3 + (byte/signed byte/word/signed word) 1
(byte) line_xdyi::e#1 ← (byte) line_xdyi::e#3 + (byte) line_xdyi::yd#2
if((byte) line_xdyi::xd#5>=(byte) line_xdyi::e#1) goto line_xdyi::@2
to:line_xdyi::@3
line_xdyi::@2: scope:[line_xdyi] from line_xdyi::@3 line_xdyi::@5
(byte) line_xdyi::e#6 ← phi( line_xdyi::@3/(byte) line_xdyi::e#2 line_xdyi::@5/(byte) line_xdyi::e#1 )
(byte) line_xdyi::y#6 ← phi( line_xdyi::@3/(byte) line_xdyi::y#2 line_xdyi::@5/(byte) line_xdyi::y#3 )
(byte~) line_xdyi::$8 ← (byte) line_xdyi::x1#6 + (byte/signed byte/word/signed word) 1
if((byte) line_xdyi::x#2<(byte~) line_xdyi::$8) goto line_xdyi::@1
to:line_xdyi::@return
line_xdyi::@3: scope:[line_xdyi] from line_xdyi::@5
(byte) line_xdyi::y#2 ← (byte) line_xdyi::y#3 + (byte/signed byte/word/signed word) 1
(byte) line_xdyi::e#2 ← (byte) line_xdyi::e#1 - (byte) line_xdyi::xd#5
to:line_xdyi::@2
line_xdyi::@return: scope:[line_xdyi] from line_xdyi::@2
return
to:@return
line_xdyd: scope:[line_xdyd] from line::@20 line::@24
(byte) line_xdyd::x1#6 ← phi( line::@20/(byte) line_xdyd::x1#0 line::@24/(byte) line_xdyd::x1#1 )
(byte) line_xdyd::xd#5 ← phi( line::@20/(byte) line_xdyd::xd#0 line::@24/(byte) line_xdyd::xd#1 )
(byte) line_xdyd::y#5 ← phi( line::@20/(byte) line_xdyd::y#0 line::@24/(byte) line_xdyd::y#1 )
(byte) line_xdyd::x#6 ← phi( line::@20/(byte) line_xdyd::x#0 line::@24/(byte) line_xdyd::x#1 )
(byte) line_xdyd::yd#2 ← phi( line::@20/(byte) line_xdyd::yd#0 line::@24/(byte) line_xdyd::yd#1 )
(byte) line_xdyd::e#0 ← (byte) line_xdyd::yd#2 >> (byte/signed byte/word/signed word) 1
to:line_xdyd::@1
line_xdyd::@1: scope:[line_xdyd] from line_xdyd line_xdyd::@2
(byte) line_xdyd::e#3 ← phi( line_xdyd/(byte) line_xdyd::e#0 line_xdyd::@2/(byte) line_xdyd::e#6 )
(byte) line_xdyd::y#3 ← phi( line_xdyd/(byte) line_xdyd::y#5 line_xdyd::@2/(byte) line_xdyd::y#6 )
(byte) line_xdyd::x#3 ← phi( line_xdyd/(byte) line_xdyd::x#6 line_xdyd::@2/(byte) line_xdyd::x#2 )
(byte) plot::x#1 ← (byte) line_xdyd::x#3
(byte) plot::y#1 ← (byte) line_xdyd::y#3
call plot param-assignment
to:line_xdyd::@5
line_xdyd::@5: scope:[line_xdyd] from line_xdyd::@1
(byte) line_xdyd::x#2 ← (byte) line_xdyd::x#3 + (byte/signed byte/word/signed word) 1
(byte) line_xdyd::e#1 ← (byte) line_xdyd::e#3 + (byte) line_xdyd::yd#2
if((byte) line_xdyd::xd#5>=(byte) line_xdyd::e#1) goto line_xdyd::@2
to:line_xdyd::@3
line_xdyd::@2: scope:[line_xdyd] from line_xdyd::@3 line_xdyd::@5
(byte) line_xdyd::e#6 ← phi( line_xdyd::@3/(byte) line_xdyd::e#2 line_xdyd::@5/(byte) line_xdyd::e#1 )
(byte) line_xdyd::y#6 ← phi( line_xdyd::@3/(byte) line_xdyd::y#2 line_xdyd::@5/(byte) line_xdyd::y#3 )
(byte~) line_xdyd::$8 ← (byte) line_xdyd::x1#6 + (byte/signed byte/word/signed word) 1
if((byte) line_xdyd::x#2<(byte~) line_xdyd::$8) goto line_xdyd::@1
to:line_xdyd::@return
line_xdyd::@3: scope:[line_xdyd] from line_xdyd::@5
(byte) line_xdyd::y#2 ← (byte) line_xdyd::y#3 - (byte/signed byte/word/signed word) 1
(byte) line_xdyd::e#2 ← (byte) line_xdyd::e#1 - (byte) line_xdyd::xd#5
to:line_xdyd::@2
line_xdyd::@return: scope:[line_xdyd] from line_xdyd::@2
return
to:@return
line_ydxi: scope:[line_ydxi] from line::@13 line::@3
(byte) line_ydxi::y1#6 ← phi( line::@13/(byte) line_ydxi::y1#1 line::@3/(byte) line_ydxi::y1#0 )
(byte) line_ydxi::yd#5 ← phi( line::@13/(byte) line_ydxi::yd#1 line::@3/(byte) line_ydxi::yd#0 )
(byte) line_ydxi::y#6 ← phi( line::@13/(byte) line_ydxi::y#1 line::@3/(byte) line_ydxi::y#0 )
(byte) line_ydxi::x#5 ← phi( line::@13/(byte) line_ydxi::x#1 line::@3/(byte) line_ydxi::x#0 )
(byte) line_ydxi::xd#2 ← phi( line::@13/(byte) line_ydxi::xd#1 line::@3/(byte) line_ydxi::xd#0 )
(byte) line_ydxi::e#0 ← (byte) line_ydxi::xd#2 >> (byte/signed byte/word/signed word) 1
to:line_ydxi::@1
line_ydxi::@1: scope:[line_ydxi] from line_ydxi line_ydxi::@2
(byte) line_ydxi::e#3 ← phi( line_ydxi/(byte) line_ydxi::e#0 line_ydxi::@2/(byte) line_ydxi::e#6 )
(byte) line_ydxi::y#3 ← phi( line_ydxi/(byte) line_ydxi::y#6 line_ydxi::@2/(byte) line_ydxi::y#2 )
(byte) line_ydxi::x#3 ← phi( line_ydxi/(byte) line_ydxi::x#5 line_ydxi::@2/(byte) line_ydxi::x#6 )
(byte) plot::x#2 ← (byte) line_ydxi::x#3
(byte) plot::y#2 ← (byte) line_ydxi::y#3
call plot param-assignment
to:line_ydxi::@5
line_ydxi::@5: scope:[line_ydxi] from line_ydxi::@1
(byte) line_ydxi::y#2 ← (byte) line_ydxi::y#3 + (byte/signed byte/word/signed word) 1
(byte) line_ydxi::e#1 ← (byte) line_ydxi::e#3 + (byte) line_ydxi::xd#2
if((byte) line_ydxi::yd#5>=(byte) line_ydxi::e#1) goto line_ydxi::@2
to:line_ydxi::@3
line_ydxi::@2: scope:[line_ydxi] from line_ydxi::@3 line_ydxi::@5
(byte) line_ydxi::e#6 ← phi( line_ydxi::@3/(byte) line_ydxi::e#2 line_ydxi::@5/(byte) line_ydxi::e#1 )
(byte) line_ydxi::x#6 ← phi( line_ydxi::@3/(byte) line_ydxi::x#2 line_ydxi::@5/(byte) line_ydxi::x#3 )
(byte~) line_ydxi::$8 ← (byte) line_ydxi::y1#6 + (byte/signed byte/word/signed word) 1
if((byte) line_ydxi::y#2<(byte~) line_ydxi::$8) goto line_ydxi::@1
to:line_ydxi::@return
line_ydxi::@3: scope:[line_ydxi] from line_ydxi::@5
(byte) line_ydxi::x#2 ← (byte) line_ydxi::x#3 + (byte/signed byte/word/signed word) 1
(byte) line_ydxi::e#2 ← (byte) line_ydxi::e#1 - (byte) line_ydxi::yd#5
to:line_ydxi::@2
line_ydxi::@return: scope:[line_ydxi] from line_ydxi::@2
return
to:@return
line_ydxd: scope:[line_ydxd] from line::@10 line::@6
(byte) line_ydxd::y1#6 ← phi( line::@10/(byte) line_ydxd::y1#1 line::@6/(byte) line_ydxd::y1#0 )
(byte) line_ydxd::yd#5 ← phi( line::@10/(byte) line_ydxd::yd#1 line::@6/(byte) line_ydxd::yd#0 )
(byte) line_ydxd::y#6 ← phi( line::@10/(byte) line_ydxd::y#1 line::@6/(byte) line_ydxd::y#0 )
(byte) line_ydxd::x#5 ← phi( line::@10/(byte) line_ydxd::x#1 line::@6/(byte) line_ydxd::x#0 )
(byte) line_ydxd::xd#2 ← phi( line::@10/(byte) line_ydxd::xd#1 line::@6/(byte) line_ydxd::xd#0 )
(byte) line_ydxd::e#0 ← (byte) line_ydxd::xd#2 >> (byte/signed byte/word/signed word) 1
to:line_ydxd::@1
line_ydxd::@1: scope:[line_ydxd] from line_ydxd line_ydxd::@2
(byte) line_ydxd::e#3 ← phi( line_ydxd/(byte) line_ydxd::e#0 line_ydxd::@2/(byte) line_ydxd::e#6 )
(byte) line_ydxd::y#3 ← phi( line_ydxd/(byte) line_ydxd::y#6 line_ydxd::@2/(byte) line_ydxd::y#2 )
(byte) line_ydxd::x#3 ← phi( line_ydxd/(byte) line_ydxd::x#5 line_ydxd::@2/(byte) line_ydxd::x#6 )
(byte) plot::x#3 ← (byte) line_ydxd::x#3
(byte) plot::y#3 ← (byte) line_ydxd::y#3
call plot param-assignment
to:line_ydxd::@5
line_ydxd::@5: scope:[line_ydxd] from line_ydxd::@1
(byte) line_ydxd::y#2 ← (byte) line_ydxd::y#3 + (byte/signed byte/word/signed word) 1
(byte) line_ydxd::e#1 ← (byte) line_ydxd::e#3 + (byte) line_ydxd::xd#2
if((byte) line_ydxd::yd#5>=(byte) line_ydxd::e#1) goto line_ydxd::@2
to:line_ydxd::@3
line_ydxd::@2: scope:[line_ydxd] from line_ydxd::@3 line_ydxd::@5
(byte) line_ydxd::e#6 ← phi( line_ydxd::@3/(byte) line_ydxd::e#2 line_ydxd::@5/(byte) line_ydxd::e#1 )
(byte) line_ydxd::x#6 ← phi( line_ydxd::@3/(byte) line_ydxd::x#2 line_ydxd::@5/(byte) line_ydxd::x#3 )
(byte~) line_ydxd::$8 ← (byte) line_ydxd::y1#6 + (byte/signed byte/word/signed word) 1
if((byte) line_ydxd::y#2<(byte~) line_ydxd::$8) goto line_ydxd::@1
to:line_ydxd::@return
line_ydxd::@3: scope:[line_ydxd] from line_ydxd::@5
(byte) line_ydxd::x#2 ← (byte) line_ydxd::x#3 - (byte/signed byte/word/signed word) 1
(byte) line_ydxd::e#2 ← (byte) line_ydxd::e#1 - (byte) line_ydxd::yd#5
to:line_ydxd::@2
line_ydxd::@return: scope:[line_ydxd] from line_ydxd::@2
return
to:@return
plot: scope:[plot] from line_xdyd::@1 line_xdyi::@1 line_ydxd::@1 line_ydxi::@1
(byte) plot::y#4 ← phi( line_xdyd::@1/(byte) plot::y#1 line_xdyi::@1/(byte) plot::y#0 line_ydxd::@1/(byte) plot::y#3 line_ydxi::@1/(byte) plot::y#2 )
(byte) plot::x#4 ← phi( line_xdyd::@1/(byte) plot::x#1 line_xdyi::@1/(byte) plot::x#0 line_ydxd::@1/(byte) plot::x#3 line_ydxi::@1/(byte) plot::x#2 )
(word) plot::plotter_x#0 ← *((const byte[]) plot_xhi#0 + (byte) plot::x#4) w= *((const byte[]) plot_xlo#0 + (byte) plot::x#4)
(word) plot::plotter_y#0 ← *((const byte[]) plot_yhi#0 + (byte) plot::y#4) w= *((const byte[]) plot_ylo#0 + (byte) plot::y#4)
(word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0
(byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0
(byte~) plot::$1 ← *((byte*) plot::plotter#0) | *((const byte[]) plot_bit#0 + (byte) plot::x#4)
*((byte*) plot::plotter#0) ← (byte~) plot::$1
to:plot::@return
plot::@return: scope:[plot] from plot
return
to:@return
init_plot_tables: scope:[init_plot_tables] from main::@3
to:init_plot_tables::@1
init_plot_tables::@1: scope:[init_plot_tables] from init_plot_tables init_plot_tables::@2
(byte) init_plot_tables::bits#3 ← phi( init_plot_tables/(const byte) init_plot_tables::bits#0 init_plot_tables::@2/(byte) init_plot_tables::bits#4 )
(byte) init_plot_tables::x#2 ← phi( init_plot_tables/(const byte) init_plot_tables::x#0 init_plot_tables::@2/(byte) init_plot_tables::x#1 )
(byte~) init_plot_tables::$0 ← (byte) init_plot_tables::x#2 & (byte/word/signed word) 248
*((const byte[]) plot_xlo#0 + (byte) init_plot_tables::x#2) ← (byte~) init_plot_tables::$0
*((const byte[]) plot_xhi#0 + (byte) init_plot_tables::x#2) ← (const byte) init_plot_tables::$1
*((const byte[]) plot_bit#0 + (byte) init_plot_tables::x#2) ← (byte) init_plot_tables::bits#3
(byte) init_plot_tables::bits#1 ← (byte) init_plot_tables::bits#3 >> (byte/signed byte/word/signed word) 1
if((byte) init_plot_tables::bits#1!=(byte/signed byte/word/signed word) 0) goto init_plot_tables::@2
to:init_plot_tables::@5
init_plot_tables::@2: scope:[init_plot_tables] from init_plot_tables::@1 init_plot_tables::@5
(byte) init_plot_tables::bits#4 ← phi( init_plot_tables::@1/(byte) init_plot_tables::bits#1 init_plot_tables::@5/(const byte) init_plot_tables::bits#2 )
(byte) init_plot_tables::x#1 ← ++ (byte) init_plot_tables::x#2
if((byte) init_plot_tables::x#1!=(byte/signed byte/word/signed word) 0) goto init_plot_tables::@1
to:init_plot_tables::@6
init_plot_tables::@5: scope:[init_plot_tables] from init_plot_tables::@1
to:init_plot_tables::@2
init_plot_tables::@6: scope:[init_plot_tables] from init_plot_tables::@2
to:init_plot_tables::@3
init_plot_tables::@3: scope:[init_plot_tables] from init_plot_tables::@4 init_plot_tables::@6
(byte*) init_plot_tables::yoffs#2 ← phi( init_plot_tables::@4/(byte*) init_plot_tables::yoffs#4 init_plot_tables::@6/(const byte*) init_plot_tables::yoffs#0 )
(byte) init_plot_tables::y#2 ← phi( init_plot_tables::@4/(byte) init_plot_tables::y#1 init_plot_tables::@6/(const byte) init_plot_tables::y#0 )
(byte~) init_plot_tables::$6 ← (byte) init_plot_tables::y#2 & (byte/signed byte/word/signed word) 7
(byte~) init_plot_tables::$7 ← < (byte*) init_plot_tables::yoffs#2
(byte~) init_plot_tables::$8 ← (byte~) init_plot_tables::$6 | (byte~) init_plot_tables::$7
*((const byte[]) plot_ylo#0 + (byte) init_plot_tables::y#2) ← (byte~) init_plot_tables::$8
(byte~) init_plot_tables::$9 ← > (byte*) init_plot_tables::yoffs#2
*((const byte[]) plot_yhi#0 + (byte) init_plot_tables::y#2) ← (byte~) init_plot_tables::$9
(byte~) init_plot_tables::$10 ← (byte) init_plot_tables::y#2 & (byte/signed byte/word/signed word) 7
if((byte~) init_plot_tables::$10!=(byte/signed byte/word/signed word) 7) goto init_plot_tables::@4
to:init_plot_tables::@7
init_plot_tables::@4: scope:[init_plot_tables] from init_plot_tables::@3 init_plot_tables::@7
(byte*) init_plot_tables::yoffs#4 ← phi( init_plot_tables::@3/(byte*) init_plot_tables::yoffs#2 init_plot_tables::@7/(byte*) init_plot_tables::yoffs#1 )
(byte) init_plot_tables::y#1 ← ++ (byte) init_plot_tables::y#2
if((byte) init_plot_tables::y#1!=(byte/signed byte/word/signed word) 0) goto init_plot_tables::@3
to:init_plot_tables::@return
init_plot_tables::@7: scope:[init_plot_tables] from init_plot_tables::@3
(byte*) init_plot_tables::yoffs#1 ← (byte*) init_plot_tables::yoffs#2 + (const word/signed word) init_plot_tables::$13
to:init_plot_tables::@4
init_plot_tables::@return: scope:[init_plot_tables] from init_plot_tables::@4
return
to:@return
init_screen: scope:[init_screen] from main
to:init_screen::@1
init_screen::@1: scope:[init_screen] from init_screen init_screen::@1
(byte*) init_screen::b#2 ← phi( init_screen/(const byte*) init_screen::b#0 init_screen::@1/(byte*) init_screen::b#1 )
*((byte*) init_screen::b#2) ← (byte/signed byte/word/signed word) 0
(byte*) init_screen::b#1 ← ++ (byte*) init_screen::b#2
if((byte*) init_screen::b#1!=(const byte*) init_screen::$0) goto init_screen::@1
to:init_screen::@3
init_screen::@3: scope:[init_screen] from init_screen::@1
to:init_screen::@2
init_screen::@2: scope:[init_screen] from init_screen::@2 init_screen::@3
(byte*) init_screen::c#2 ← phi( init_screen::@2/(byte*) init_screen::c#1 init_screen::@3/(const byte*) init_screen::c#0 )
*((byte*) init_screen::c#2) ← (byte/signed byte/word/signed word) 20
(byte*) init_screen::c#1 ← ++ (byte*) init_screen::c#2
if((byte*) init_screen::c#1!=(const byte*) init_screen::$2) goto init_screen::@2
to:init_screen::@return
init_screen::@return: scope:[init_screen] from init_screen::@2
return
to:@return
@10: scope:[] from @begin
call main param-assignment
to:@end
@end: scope:[] from @10
Culled Empty Block (label) main::@4 Culled Empty Block (label) main::@4
Not culling empty block because it shares successor with its predecessor. (label) init_plot_tables::@5 Not culling empty block because it shares successor with its predecessor. (label) init_plot_tables::@5
Culled Empty Block (label) init_plot_tables::@6 Culled Empty Block (label) init_plot_tables::@6
@ -15163,7 +15518,7 @@ Removing always clobbered register reg byte a as potential for zp ZP_BYTE:28 [ l
Statement [104] (word) plot::plotter_y#0 ← *((const byte[]) plot_yhi#0 + (byte) plot::y#4) w= *((const byte[]) plot_ylo#0 + (byte) plot::y#4) [ plot::x#4 plot::plotter_x#0 plot::plotter_y#0 ] ( main:2::lines:12::line:21::line_ydxi:42::plot:92 [ lines::l#2 line_ydxi::xd#2 line_ydxi::yd#5 line_ydxi::y1#6 line_ydxi::x#3 line_ydxi::y#3 line_ydxi::e#3 plot::x#4 plot::plotter_x#0 plot::plotter_y#0 ] main:2::lines:12::line:21::line_ydxi:86::plot:92 [ lines::l#2 line_ydxi::xd#2 line_ydxi::yd#5 line_ydxi::y1#6 line_ydxi::x#3 line_ydxi::y#3 line_ydxi::e#3 plot::x#4 plot::plotter_x#0 plot::plotter_y#0 ] main:2::lines:12::line:21::line_xdyi:35::plot:115 [ lines::l#2 line_xdyi::yd#2 line_xdyi::xd#5 line_xdyi::x1#6 line_xdyi::x#3 line_xdyi::y#3 line_xdyi::e#3 plot::x#4 plot::plotter_x#0 plot::plotter_y#0 ] main:2::lines:12::line:21::line_xdyi:80::plot:115 [ lines::l#2 line_xdyi::yd#2 line_xdyi::xd#5 line_xdyi::x1#6 line_xdyi::x#3 line_xdyi::y#3 line_xdyi::e#3 plot::x#4 plot::plotter_x#0 plot::plotter_y#0 ] main:2::lines:12::line:21::line_ydxd:56::plot:130 [ lines::l#2 line_ydxd::xd#2 line_ydxd::yd#5 line_ydxd::y1#6 line_ydxd::x#3 line_ydxd::y#3 line_ydxd::e#3 plot::x#4 plot::plotter_x#0 plot::plotter_y#0 ] main:2::lines:12::line:21::line_ydxd:72::plot:130 [ lines::l#2 line_ydxd::xd#2 line_ydxd::yd#5 line_ydxd::y1#6 line_ydxd::x#3 line_ydxd::y#3 line_ydxd::e#3 plot::x#4 plot::plotter_x#0 plot::plotter_y#0 ] main:2::lines:12::line:21::line_xdyd:50::plot:145 [ lines::l#2 line_xdyd::yd#2 line_xdyd::xd#5 line_xdyd::x1#6 line_xdyd::x#3 line_xdyd::y#3 line_xdyd::e#3 plot::x#4 plot::plotter_x#0 plot::plotter_y#0 ] main:2::lines:12::line:21::line_xdyd:66::plot:145 [ lines::l#2 line_xdyd::yd#2 line_xdyd::xd#5 line_xdyd::x1#6 line_xdyd::x#3 line_xdyd::y#3 line_xdyd::e#3 plot::x#4 plot::plotter_x#0 plot::plotter_y#0 ] ) always clobbers reg byte a Statement [104] (word) plot::plotter_y#0 ← *((const byte[]) plot_yhi#0 + (byte) plot::y#4) w= *((const byte[]) plot_ylo#0 + (byte) plot::y#4) [ plot::x#4 plot::plotter_x#0 plot::plotter_y#0 ] ( main:2::lines:12::line:21::line_ydxi:42::plot:92 [ lines::l#2 line_ydxi::xd#2 line_ydxi::yd#5 line_ydxi::y1#6 line_ydxi::x#3 line_ydxi::y#3 line_ydxi::e#3 plot::x#4 plot::plotter_x#0 plot::plotter_y#0 ] main:2::lines:12::line:21::line_ydxi:86::plot:92 [ lines::l#2 line_ydxi::xd#2 line_ydxi::yd#5 line_ydxi::y1#6 line_ydxi::x#3 line_ydxi::y#3 line_ydxi::e#3 plot::x#4 plot::plotter_x#0 plot::plotter_y#0 ] main:2::lines:12::line:21::line_xdyi:35::plot:115 [ lines::l#2 line_xdyi::yd#2 line_xdyi::xd#5 line_xdyi::x1#6 line_xdyi::x#3 line_xdyi::y#3 line_xdyi::e#3 plot::x#4 plot::plotter_x#0 plot::plotter_y#0 ] main:2::lines:12::line:21::line_xdyi:80::plot:115 [ lines::l#2 line_xdyi::yd#2 line_xdyi::xd#5 line_xdyi::x1#6 line_xdyi::x#3 line_xdyi::y#3 line_xdyi::e#3 plot::x#4 plot::plotter_x#0 plot::plotter_y#0 ] main:2::lines:12::line:21::line_ydxd:56::plot:130 [ lines::l#2 line_ydxd::xd#2 line_ydxd::yd#5 line_ydxd::y1#6 line_ydxd::x#3 line_ydxd::y#3 line_ydxd::e#3 plot::x#4 plot::plotter_x#0 plot::plotter_y#0 ] main:2::lines:12::line:21::line_ydxd:72::plot:130 [ lines::l#2 line_ydxd::xd#2 line_ydxd::yd#5 line_ydxd::y1#6 line_ydxd::x#3 line_ydxd::y#3 line_ydxd::e#3 plot::x#4 plot::plotter_x#0 plot::plotter_y#0 ] main:2::lines:12::line:21::line_xdyd:50::plot:145 [ lines::l#2 line_xdyd::yd#2 line_xdyd::xd#5 line_xdyd::x1#6 line_xdyd::x#3 line_xdyd::y#3 line_xdyd::e#3 plot::x#4 plot::plotter_x#0 plot::plotter_y#0 ] main:2::lines:12::line:21::line_xdyd:66::plot:145 [ lines::l#2 line_xdyd::yd#2 line_xdyd::xd#5 line_xdyd::x1#6 line_xdyd::x#3 line_xdyd::y#3 line_xdyd::e#3 plot::x#4 plot::plotter_x#0 plot::plotter_y#0 ] ) always clobbers reg byte a
Statement [105] (word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0 [ plot::x#4 plot::$0 ] ( main:2::lines:12::line:21::line_ydxi:42::plot:92 [ lines::l#2 line_ydxi::xd#2 line_ydxi::yd#5 line_ydxi::y1#6 line_ydxi::x#3 line_ydxi::y#3 line_ydxi::e#3 plot::x#4 plot::$0 ] main:2::lines:12::line:21::line_ydxi:86::plot:92 [ lines::l#2 line_ydxi::xd#2 line_ydxi::yd#5 line_ydxi::y1#6 line_ydxi::x#3 line_ydxi::y#3 line_ydxi::e#3 plot::x#4 plot::$0 ] main:2::lines:12::line:21::line_xdyi:35::plot:115 [ lines::l#2 line_xdyi::yd#2 line_xdyi::xd#5 line_xdyi::x1#6 line_xdyi::x#3 line_xdyi::y#3 line_xdyi::e#3 plot::x#4 plot::$0 ] main:2::lines:12::line:21::line_xdyi:80::plot:115 [ lines::l#2 line_xdyi::yd#2 line_xdyi::xd#5 line_xdyi::x1#6 line_xdyi::x#3 line_xdyi::y#3 line_xdyi::e#3 plot::x#4 plot::$0 ] main:2::lines:12::line:21::line_ydxd:56::plot:130 [ lines::l#2 line_ydxd::xd#2 line_ydxd::yd#5 line_ydxd::y1#6 line_ydxd::x#3 line_ydxd::y#3 line_ydxd::e#3 plot::x#4 plot::$0 ] main:2::lines:12::line:21::line_ydxd:72::plot:130 [ lines::l#2 line_ydxd::xd#2 line_ydxd::yd#5 line_ydxd::y1#6 line_ydxd::x#3 line_ydxd::y#3 line_ydxd::e#3 plot::x#4 plot::$0 ] main:2::lines:12::line:21::line_xdyd:50::plot:145 [ lines::l#2 line_xdyd::yd#2 line_xdyd::xd#5 line_xdyd::x1#6 line_xdyd::x#3 line_xdyd::y#3 line_xdyd::e#3 plot::x#4 plot::$0 ] main:2::lines:12::line:21::line_xdyd:66::plot:145 [ lines::l#2 line_xdyd::yd#2 line_xdyd::xd#5 line_xdyd::x1#6 line_xdyd::x#3 line_xdyd::y#3 line_xdyd::e#3 plot::x#4 plot::$0 ] ) always clobbers reg byte a Statement [105] (word~) plot::$0 ← (word) plot::plotter_x#0 + (word) plot::plotter_y#0 [ plot::x#4 plot::$0 ] ( main:2::lines:12::line:21::line_ydxi:42::plot:92 [ lines::l#2 line_ydxi::xd#2 line_ydxi::yd#5 line_ydxi::y1#6 line_ydxi::x#3 line_ydxi::y#3 line_ydxi::e#3 plot::x#4 plot::$0 ] main:2::lines:12::line:21::line_ydxi:86::plot:92 [ lines::l#2 line_ydxi::xd#2 line_ydxi::yd#5 line_ydxi::y1#6 line_ydxi::x#3 line_ydxi::y#3 line_ydxi::e#3 plot::x#4 plot::$0 ] main:2::lines:12::line:21::line_xdyi:35::plot:115 [ lines::l#2 line_xdyi::yd#2 line_xdyi::xd#5 line_xdyi::x1#6 line_xdyi::x#3 line_xdyi::y#3 line_xdyi::e#3 plot::x#4 plot::$0 ] main:2::lines:12::line:21::line_xdyi:80::plot:115 [ lines::l#2 line_xdyi::yd#2 line_xdyi::xd#5 line_xdyi::x1#6 line_xdyi::x#3 line_xdyi::y#3 line_xdyi::e#3 plot::x#4 plot::$0 ] main:2::lines:12::line:21::line_ydxd:56::plot:130 [ lines::l#2 line_ydxd::xd#2 line_ydxd::yd#5 line_ydxd::y1#6 line_ydxd::x#3 line_ydxd::y#3 line_ydxd::e#3 plot::x#4 plot::$0 ] main:2::lines:12::line:21::line_ydxd:72::plot:130 [ lines::l#2 line_ydxd::xd#2 line_ydxd::yd#5 line_ydxd::y1#6 line_ydxd::x#3 line_ydxd::y#3 line_ydxd::e#3 plot::x#4 plot::$0 ] main:2::lines:12::line:21::line_xdyd:50::plot:145 [ lines::l#2 line_xdyd::yd#2 line_xdyd::xd#5 line_xdyd::x1#6 line_xdyd::x#3 line_xdyd::y#3 line_xdyd::e#3 plot::x#4 plot::$0 ] main:2::lines:12::line:21::line_xdyd:66::plot:145 [ lines::l#2 line_xdyd::yd#2 line_xdyd::xd#5 line_xdyd::x1#6 line_xdyd::x#3 line_xdyd::y#3 line_xdyd::e#3 plot::x#4 plot::$0 ] ) always clobbers reg byte a
Statement [106] (byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0 [ plot::x#4 plot::plotter#0 ] ( main:2::lines:12::line:21::line_ydxi:42::plot:92 [ lines::l#2 line_ydxi::xd#2 line_ydxi::yd#5 line_ydxi::y1#6 line_ydxi::x#3 line_ydxi::y#3 line_ydxi::e#3 plot::x#4 plot::plotter#0 ] main:2::lines:12::line:21::line_ydxi:86::plot:92 [ lines::l#2 line_ydxi::xd#2 line_ydxi::yd#5 line_ydxi::y1#6 line_ydxi::x#3 line_ydxi::y#3 line_ydxi::e#3 plot::x#4 plot::plotter#0 ] main:2::lines:12::line:21::line_xdyi:35::plot:115 [ lines::l#2 line_xdyi::yd#2 line_xdyi::xd#5 line_xdyi::x1#6 line_xdyi::x#3 line_xdyi::y#3 line_xdyi::e#3 plot::x#4 plot::plotter#0 ] main:2::lines:12::line:21::line_xdyi:80::plot:115 [ lines::l#2 line_xdyi::yd#2 line_xdyi::xd#5 line_xdyi::x1#6 line_xdyi::x#3 line_xdyi::y#3 line_xdyi::e#3 plot::x#4 plot::plotter#0 ] main:2::lines:12::line:21::line_ydxd:56::plot:130 [ lines::l#2 line_ydxd::xd#2 line_ydxd::yd#5 line_ydxd::y1#6 line_ydxd::x#3 line_ydxd::y#3 line_ydxd::e#3 plot::x#4 plot::plotter#0 ] main:2::lines:12::line:21::line_ydxd:72::plot:130 [ lines::l#2 line_ydxd::xd#2 line_ydxd::yd#5 line_ydxd::y1#6 line_ydxd::x#3 line_ydxd::y#3 line_ydxd::e#3 plot::x#4 plot::plotter#0 ] main:2::lines:12::line:21::line_xdyd:50::plot:145 [ lines::l#2 line_xdyd::yd#2 line_xdyd::xd#5 line_xdyd::x1#6 line_xdyd::x#3 line_xdyd::y#3 line_xdyd::e#3 plot::x#4 plot::plotter#0 ] main:2::lines:12::line:21::line_xdyd:66::plot:145 [ lines::l#2 line_xdyd::yd#2 line_xdyd::xd#5 line_xdyd::x1#6 line_xdyd::x#3 line_xdyd::y#3 line_xdyd::e#3 plot::x#4 plot::plotter#0 ] ) always clobbers reg byte a Statement [106] (byte*) plot::plotter#0 ← ((byte*)) (word~) plot::$0 [ plot::x#4 plot::plotter#0 ] ( main:2::lines:12::line:21::line_ydxi:42::plot:92 [ lines::l#2 line_ydxi::xd#2 line_ydxi::yd#5 line_ydxi::y1#6 line_ydxi::x#3 line_ydxi::y#3 line_ydxi::e#3 plot::x#4 plot::plotter#0 ] main:2::lines:12::line:21::line_ydxi:86::plot:92 [ lines::l#2 line_ydxi::xd#2 line_ydxi::yd#5 line_ydxi::y1#6 line_ydxi::x#3 line_ydxi::y#3 line_ydxi::e#3 plot::x#4 plot::plotter#0 ] main:2::lines:12::line:21::line_xdyi:35::plot:115 [ lines::l#2 line_xdyi::yd#2 line_xdyi::xd#5 line_xdyi::x1#6 line_xdyi::x#3 line_xdyi::y#3 line_xdyi::e#3 plot::x#4 plot::plotter#0 ] main:2::lines:12::line:21::line_xdyi:80::plot:115 [ lines::l#2 line_xdyi::yd#2 line_xdyi::xd#5 line_xdyi::x1#6 line_xdyi::x#3 line_xdyi::y#3 line_xdyi::e#3 plot::x#4 plot::plotter#0 ] main:2::lines:12::line:21::line_ydxd:56::plot:130 [ lines::l#2 line_ydxd::xd#2 line_ydxd::yd#5 line_ydxd::y1#6 line_ydxd::x#3 line_ydxd::y#3 line_ydxd::e#3 plot::x#4 plot::plotter#0 ] main:2::lines:12::line:21::line_ydxd:72::plot:130 [ lines::l#2 line_ydxd::xd#2 line_ydxd::yd#5 line_ydxd::y1#6 line_ydxd::x#3 line_ydxd::y#3 line_ydxd::e#3 plot::x#4 plot::plotter#0 ] main:2::lines:12::line:21::line_xdyd:50::plot:145 [ lines::l#2 line_xdyd::yd#2 line_xdyd::xd#5 line_xdyd::x1#6 line_xdyd::x#3 line_xdyd::y#3 line_xdyd::e#3 plot::x#4 plot::plotter#0 ] main:2::lines:12::line:21::line_xdyd:66::plot:145 [ lines::l#2 line_xdyd::yd#2 line_xdyd::xd#5 line_xdyd::x1#6 line_xdyd::x#3 line_xdyd::y#3 line_xdyd::e#3 plot::x#4 plot::plotter#0 ] ) always clobbers reg byte a
Statement [107] (byte~) plotAsm::$1 ← *((byte*) plot::plotter#0) | *((const byte[]) plot_bit#0 + (byte) plot::x#4) [ plot::plotter#0 plot::$1 ] ( main:2::lines:12::line:21::line_ydxi:42::plot:92 [ lines::l#2 line_ydxi::xd#2 line_ydxi::yd#5 line_ydxi::y1#6 line_ydxi::x#3 line_ydxi::y#3 line_ydxi::e#3 plot::plotter#0 plot::$1 ] main:2::lines:12::line:21::line_ydxi:86::plot:92 [ lines::l#2 line_ydxi::xd#2 line_ydxi::yd#5 line_ydxi::y1#6 line_ydxi::x#3 line_ydxi::y#3 line_ydxi::e#3 plot::plotter#0 plot::$1 ] main:2::lines:12::line:21::line_xdyi:35::plot:115 [ lines::l#2 line_xdyi::yd#2 line_xdyi::xd#5 line_xdyi::x1#6 line_xdyi::x#3 line_xdyi::y#3 line_xdyi::e#3 plot::plotter#0 plot::$1 ] main:2::lines:12::line:21::line_xdyi:80::plot:115 [ lines::l#2 line_xdyi::yd#2 line_xdyi::xd#5 line_xdyi::x1#6 line_xdyi::x#3 line_xdyi::y#3 line_xdyi::e#3 plot::plotter#0 plot::$1 ] main:2::lines:12::line:21::line_ydxd:56::plot:130 [ lines::l#2 line_ydxd::xd#2 line_ydxd::yd#5 line_ydxd::y1#6 line_ydxd::x#3 line_ydxd::y#3 line_ydxd::e#3 plot::plotter#0 plot::$1 ] main:2::lines:12::line:21::line_ydxd:72::plot:130 [ lines::l#2 line_ydxd::xd#2 line_ydxd::yd#5 line_ydxd::y1#6 line_ydxd::x#3 line_ydxd::y#3 line_ydxd::e#3 plot::plotter#0 plot::$1 ] main:2::lines:12::line:21::line_xdyd:50::plot:145 [ lines::l#2 line_xdyd::yd#2 line_xdyd::xd#5 line_xdyd::x1#6 line_xdyd::x#3 line_xdyd::y#3 line_xdyd::e#3 plot::plotter#0 plot::$1 ] main:2::lines:12::line:21::line_xdyd:66::plot:145 [ lines::l#2 line_xdyd::yd#2 line_xdyd::xd#5 line_xdyd::x1#6 line_xdyd::x#3 line_xdyd::y#3 line_xdyd::e#3 plot::plotter#0 plot::$1 ] ) always clobbers reg byte a reg byte y Statement [107] (byte~) plot::$1 ← *((byte*) plot::plotter#0) | *((const byte[]) plot_bit#0 + (byte) plot::x#4) [ plot::plotter#0 plot::$1 ] ( main:2::lines:12::line:21::line_ydxi:42::plot:92 [ lines::l#2 line_ydxi::xd#2 line_ydxi::yd#5 line_ydxi::y1#6 line_ydxi::x#3 line_ydxi::y#3 line_ydxi::e#3 plot::plotter#0 plot::$1 ] main:2::lines:12::line:21::line_ydxi:86::plot:92 [ lines::l#2 line_ydxi::xd#2 line_ydxi::yd#5 line_ydxi::y1#6 line_ydxi::x#3 line_ydxi::y#3 line_ydxi::e#3 plot::plotter#0 plot::$1 ] main:2::lines:12::line:21::line_xdyi:35::plot:115 [ lines::l#2 line_xdyi::yd#2 line_xdyi::xd#5 line_xdyi::x1#6 line_xdyi::x#3 line_xdyi::y#3 line_xdyi::e#3 plot::plotter#0 plot::$1 ] main:2::lines:12::line:21::line_xdyi:80::plot:115 [ lines::l#2 line_xdyi::yd#2 line_xdyi::xd#5 line_xdyi::x1#6 line_xdyi::x#3 line_xdyi::y#3 line_xdyi::e#3 plot::plotter#0 plot::$1 ] main:2::lines:12::line:21::line_ydxd:56::plot:130 [ lines::l#2 line_ydxd::xd#2 line_ydxd::yd#5 line_ydxd::y1#6 line_ydxd::x#3 line_ydxd::y#3 line_ydxd::e#3 plot::plotter#0 plot::$1 ] main:2::lines:12::line:21::line_ydxd:72::plot:130 [ lines::l#2 line_ydxd::xd#2 line_ydxd::yd#5 line_ydxd::y1#6 line_ydxd::x#3 line_ydxd::y#3 line_ydxd::e#3 plot::plotter#0 plot::$1 ] main:2::lines:12::line:21::line_xdyd:50::plot:145 [ lines::l#2 line_xdyd::yd#2 line_xdyd::xd#5 line_xdyd::x1#6 line_xdyd::x#3 line_xdyd::y#3 line_xdyd::e#3 plot::plotter#0 plot::$1 ] main:2::lines:12::line:21::line_xdyd:66::plot:145 [ lines::l#2 line_xdyd::yd#2 line_xdyd::xd#5 line_xdyd::x1#6 line_xdyd::x#3 line_xdyd::y#3 line_xdyd::e#3 plot::plotter#0 plot::$1 ] ) always clobbers reg byte a reg byte y
Removing always clobbered register reg byte y as potential for zp ZP_BYTE:2 [ lines::l#2 lines::l#1 ] Removing always clobbered register reg byte y as potential for zp ZP_BYTE:2 [ lines::l#2 lines::l#1 ]
Removing always clobbered register reg byte y as potential for zp ZP_BYTE:3 [ line_ydxi::xd#2 line_ydxi::xd#1 line_ydxi::xd#0 ] Removing always clobbered register reg byte y as potential for zp ZP_BYTE:3 [ line_ydxi::xd#2 line_ydxi::xd#1 line_ydxi::xd#0 ]
Removing always clobbered register reg byte y as potential for zp ZP_BYTE:4 [ line_ydxi::yd#5 line_ydxi::yd#1 line_ydxi::yd#0 ] Removing always clobbered register reg byte y as potential for zp ZP_BYTE:4 [ line_ydxi::yd#5 line_ydxi::yd#1 line_ydxi::yd#0 ]

View File

@ -2150,37 +2150,6 @@ Allocated zp ZP_WORD:3 [ line_cursor#6 line_cursor#13 line_cursor#1 ]
Allocated zp ZP_WORD:5 [ print_str::str#2 print_str::str#0 ] Allocated zp ZP_WORD:5 [ print_str::str#2 print_str::str#0 ]
Allocated zp ZP_WORD:7 [ char_cursor#10 char_cursor#19 char_cursor#25 char_cursor#1 ] Allocated zp ZP_WORD:7 [ char_cursor#10 char_cursor#19 char_cursor#25 char_cursor#1 ]
Allocated zp ZP_WORD:9 [ print_cls::sc#2 print_cls::sc#1 ] Allocated zp ZP_WORD:9 [ print_cls::sc#2 print_cls::sc#1 ]
Attempting fragment synthesis vbuz1=vbuc1
Succesfully loaded fragment vbuaa=vbuc1
Succesfully synthesized fragment vbuz1=vbuc1 (from vbuaa=vbuc1)
Attempting fragment synthesis pbuz1=pbuc1
Succesfully loaded fragment pbuz1=vwuc1
Succesfully synthesized fragment pbuz1=pbuc1 (from pbuz1=vwuc1)
Attempting fragment synthesis _deref_pbuc1=_inc__deref_pbuc2
Attempting fragment synthesis _deref_pbuc1=_inc__deref_vwuc2
Attempting fragment synthesis _deref_vwuc1=_inc__deref_vwuc2
Attempting fragment synthesis vbuaa=_inc__deref_vwuc1
Attempting fragment synthesis vbuaa=_deref_vwuc1_plus_1
Succesfully loaded fragment vbuaa=vbuaa_plus_1
Succesfully synthesized fragment vbuaa=_deref_vwuc1_plus_1 (from vbuaa=vbuaa_plus_1)
Succesfully synthesized fragment vbuaa=_inc__deref_vwuc1 (from vbuaa=_deref_vwuc1_plus_1)
Succesfully synthesized fragment _deref_vwuc1=_inc__deref_vwuc2 (from vbuaa=_inc__deref_vwuc1)
Succesfully synthesized fragment _deref_pbuc1=_inc__deref_vwuc2 (from _deref_vwuc1=_inc__deref_vwuc2)
Succesfully synthesized fragment _deref_pbuc1=_inc__deref_pbuc2 (from _deref_pbuc1=_inc__deref_vwuc2)
Succesfully loaded fragment vbuz1=_inc_vbuz1
Succesfully loaded fragment vbuz1_neq_vbuc1_then_la1
Succesfully loaded fragment pbuz1=pbuz2
Succesfully loaded fragment pbuz1=pbuz1_plus_vbuc1
Succesfully loaded fragment pbuz1_lt_pbuz2_then_la1
Attempting fragment synthesis _deref_pbuz1_neq_vbuc1_then_la1
Succesfully loaded fragment vbuaa_neq_vbuc1_then_la1
Succesfully synthesized fragment _deref_pbuz1_neq_vbuc1_then_la1 (from vbuaa_neq_vbuc1_then_la1)
Attempting fragment synthesis _deref_pbuz1=_deref_pbuz2
Succesfully loaded fragment vbuaa=_deref_pbuz1
Succesfully synthesized fragment _deref_pbuz1=_deref_pbuz2 (from vbuaa=_deref_pbuz1)
Succesfully loaded fragment pbuz1=_inc_pbuz1
Succesfully loaded fragment _deref_pbuz1=vbuc1
Succesfully loaded fragment pbuz1_neq_vwuc1_then_la1
INITIAL ASM INITIAL ASM
//SEG0 Basic Upstart //SEG0 Basic Upstart
.pc = $801 "Basic" .pc = $801 "Basic"
@ -2399,7 +2368,6 @@ print_cls: {
REGISTER UPLIFT POTENTIAL REGISTERS REGISTER UPLIFT POTENTIAL REGISTERS
Statement [10] *((const byte[]) txt#0+(byte/signed byte/word/signed word) 1) ← ++ *((const byte[]) txt#0+(byte/signed byte/word/signed word) 1) [ main::i#2 line_cursor#1 ] ( main:2 [ main::i#2 line_cursor#1 ] ) always clobbers reg byte a Statement [10] *((const byte[]) txt#0+(byte/signed byte/word/signed word) 1) ← ++ *((const byte[]) txt#0+(byte/signed byte/word/signed word) 1) [ main::i#2 line_cursor#1 ] ( main:2 [ main::i#2 line_cursor#1 ] ) always clobbers reg byte a
Removing always clobbered register reg byte a as potential for zp ZP_BYTE:2 [ main::i#2 main::i#1 ] Removing always clobbered register reg byte a as potential for zp ZP_BYTE:2 [ main::i#2 main::i#1 ]
Succesfully loaded fragment vbuxx_neq_vbuc1_then_la1
Statement [14] (byte*~) char_cursor#25 ← (byte*) line_cursor#1 [ char_cursor#25 line_cursor#1 main::i#1 ] ( main:2 [ char_cursor#25 line_cursor#1 main::i#1 ] ) always clobbers reg byte a Statement [14] (byte*~) char_cursor#25 ← (byte*) line_cursor#1 [ char_cursor#25 line_cursor#1 main::i#1 ] ( main:2 [ char_cursor#25 line_cursor#1 main::i#1 ] ) always clobbers reg byte a
Statement [17] (byte*) line_cursor#1 ← (byte*) line_cursor#6 + (byte/signed byte/word/signed word) 40 [ line_cursor#1 char_cursor#10 ] ( main:2::print_ln:9 [ main::i#2 line_cursor#1 char_cursor#10 ] ) always clobbers reg byte a Statement [17] (byte*) line_cursor#1 ← (byte*) line_cursor#6 + (byte/signed byte/word/signed word) 40 [ line_cursor#1 char_cursor#10 ] ( main:2::print_ln:9 [ main::i#2 line_cursor#1 char_cursor#10 ] ) always clobbers reg byte a
Statement [18] if((byte*) line_cursor#1<(byte*) char_cursor#10) goto print_ln::@1 [ line_cursor#1 char_cursor#10 ] ( main:2::print_ln:9 [ main::i#2 line_cursor#1 char_cursor#10 ] ) always clobbers reg byte a Statement [18] if((byte*) line_cursor#1<(byte*) char_cursor#10) goto print_ln::@1 [ line_cursor#1 char_cursor#10 ] ( main:2::print_ln:9 [ main::i#2 line_cursor#1 char_cursor#10 ] ) always clobbers reg byte a
@ -2432,8 +2400,6 @@ Uplift Scope [print_ln]
Uplifting [] best 13477 combination zp ZP_WORD:3 [ line_cursor#6 line_cursor#13 line_cursor#1 ] zp ZP_WORD:7 [ char_cursor#10 char_cursor#19 char_cursor#25 char_cursor#1 ] Uplifting [] best 13477 combination zp ZP_WORD:3 [ line_cursor#6 line_cursor#13 line_cursor#1 ] zp ZP_WORD:7 [ char_cursor#10 char_cursor#19 char_cursor#25 char_cursor#1 ]
Uplifting [print_str] best 13477 combination zp ZP_WORD:5 [ print_str::str#2 print_str::str#0 ] Uplifting [print_str] best 13477 combination zp ZP_WORD:5 [ print_str::str#2 print_str::str#0 ]
Uplifting [print_cls] best 13477 combination zp ZP_WORD:9 [ print_cls::sc#2 print_cls::sc#1 ] Uplifting [print_cls] best 13477 combination zp ZP_WORD:9 [ print_cls::sc#2 print_cls::sc#1 ]
Succesfully loaded fragment vbuxx=vbuc1
Succesfully loaded fragment vbuxx=_inc_vbuxx
Uplifting [main] best 13387 combination reg byte x [ main::i#2 main::i#1 ] Uplifting [main] best 13387 combination reg byte x [ main::i#2 main::i#1 ]
Uplifting [print_ln] best 13387 combination Uplifting [print_ln] best 13387 combination
Coalescing zero page register [ zp ZP_WORD:3 [ line_cursor#6 line_cursor#13 line_cursor#1 ] ] with [ zp ZP_WORD:9 [ print_cls::sc#2 print_cls::sc#1 ] ] Coalescing zero page register [ zp ZP_WORD:3 [ line_cursor#6 line_cursor#13 line_cursor#1 ] ] with [ zp ZP_WORD:9 [ print_cls::sc#2 print_cls::sc#1 ] ]

View File

@ -1,10 +1,10 @@
const byte* SCREEN = $400; const byte* SCREEN = $400;
void main() { void main() {
byte[] his = { >SCREEN, >SCREEN+$100, >SCREEN+$200 }; byte[] his = { >SCREEN, >SCREEN+$100, >SCREEN+$200 }; // constant array
for( byte h: 0..2) { for( byte h: 0..2) {
for (byte l: 4..7) { for (byte l: 4..7) {
word w = { his[h], l }; word w = { his[h], l }; // inline word
byte* sc = (byte*)w; byte* sc = (byte*)w;
*sc = '*'; *sc = '*';
} }
@ -99,7 +99,6 @@ main::@return: scope:[main] from main::@4
to:@end to:@end
@end: scope:[] from @1 @end: scope:[] from @1
Fixing word constructor with main::w ← *(main::his + main::h) w= main::l
Removing empty block main::@4 Removing empty block main::@4
CONTROL FLOW GRAPH CONTROL FLOW GRAPH
@begin: scope:[] from @begin: scope:[] from
@ -118,7 +117,7 @@ main::@1: scope:[main] from main main::@3
(byte) main::l ← (byte/signed byte/word/signed word) 4 (byte) main::l ← (byte/signed byte/word/signed word) 4
to:main::@2 to:main::@2
main::@2: scope:[main] from main::@1 main::@2 main::@2: scope:[main] from main::@1 main::@2
(word) main::w ← *((byte[]) main::his + (byte) main::h) w= (byte) main::l (word) main::w ← { *((byte[]) main::his + (byte) main::h), (byte) main::l }
(byte*~) main::$5 ← ((byte*)) (word) main::w (byte*~) main::$5 ← ((byte*)) (word) main::w
(byte*) main::sc ← (byte*~) main::$5 (byte*) main::sc ← (byte*~) main::$5
*((byte*) main::sc) ← (byte) '*' *((byte*) main::sc) ← (byte) '*'
@ -158,7 +157,7 @@ main::@1: scope:[main] from main main::@3
(byte) main::l ← (byte/signed byte/word/signed word) 4 (byte) main::l ← (byte/signed byte/word/signed word) 4
to:main::@2 to:main::@2
main::@2: scope:[main] from main::@1 main::@2 main::@2: scope:[main] from main::@1 main::@2
(word) main::w ← *((byte[]) main::his + (byte) main::h) w= (byte) main::l (word) main::w ← { *((byte[]) main::his + (byte) main::h), (byte) main::l }
(byte*~) main::$5 ← ((byte*)) (word) main::w (byte*~) main::$5 ← ((byte*)) (word) main::w
(byte*) main::sc ← (byte*~) main::$5 (byte*) main::sc ← (byte*~) main::$5
*((byte*) main::sc) ← (byte) '*' *((byte*) main::sc) ← (byte) '*'
@ -206,7 +205,7 @@ main::@2: scope:[main] from main::@1 main::@2
(byte) main::l#2 ← phi( main::@1/(byte) main::l#0 main::@2/(byte) main::l#1 ) (byte) main::l#2 ← phi( main::@1/(byte) main::l#0 main::@2/(byte) main::l#1 )
(byte) main::h#2 ← phi( main::@1/(byte) main::h#4 main::@2/(byte) main::h#2 ) (byte) main::h#2 ← phi( main::@1/(byte) main::h#4 main::@2/(byte) main::h#2 )
(byte[]) main::his#1 ← phi( main::@1/(byte[]) main::his#2 main::@2/(byte[]) main::his#1 ) (byte[]) main::his#1 ← phi( main::@1/(byte[]) main::his#2 main::@2/(byte[]) main::his#1 )
(word) main::w#0 ← *((byte[]) main::his#1 + (byte) main::h#2) w= (byte) main::l#2 (word) main::w#0 ← { *((byte[]) main::his#1 + (byte) main::h#2), (byte) main::l#2 }
(byte*~) main::$5 ← ((byte*)) (word) main::w#0 (byte*~) main::$5 ← ((byte*)) (word) main::w#0
(byte*) main::sc#0 ← (byte*~) main::$5 (byte*) main::sc#0 ← (byte*~) main::$5
*((byte*) main::sc#0) ← (byte) '*' *((byte*) main::sc#0) ← (byte) '*'
@ -253,7 +252,7 @@ main::@2: scope:[main] from main::@1 main::@2
(byte) main::l#2 ← phi( main::@1/(byte) main::l#0 main::@2/(byte) main::l#1 ) (byte) main::l#2 ← phi( main::@1/(byte) main::l#0 main::@2/(byte) main::l#1 )
(byte) main::h#2 ← phi( main::@1/(byte) main::h#4 main::@2/(byte) main::h#2 ) (byte) main::h#2 ← phi( main::@1/(byte) main::h#4 main::@2/(byte) main::h#2 )
(byte[]) main::his#1 ← phi( main::@1/(byte[]) main::his#2 main::@2/(byte[]) main::his#1 ) (byte[]) main::his#1 ← phi( main::@1/(byte[]) main::his#2 main::@2/(byte[]) main::his#1 )
(word) main::w#0 ← *((byte[]) main::his#1 + (byte) main::h#2) w= (byte) main::l#2 (word) main::w#0 ← { *((byte[]) main::his#1 + (byte) main::h#2), (byte) main::l#2 }
(byte*~) main::$5 ← ((byte*)) (word) main::w#0 (byte*~) main::$5 ← ((byte*)) (word) main::w#0
(byte*) main::sc#0 ← (byte*~) main::$5 (byte*) main::sc#0 ← (byte*~) main::$5
*((byte*) main::sc#0) ← (byte) '*' *((byte*) main::sc#0) ← (byte) '*'
@ -342,7 +341,7 @@ main::@2: scope:[main] from main::@1 main::@2
(byte) main::l#2 ← phi( main::@1/(byte) main::l#0 main::@2/(byte) main::l#1 ) (byte) main::l#2 ← phi( main::@1/(byte) main::l#0 main::@2/(byte) main::l#1 )
(byte) main::h#2 ← phi( main::@1/(byte) main::h#4 main::@2/(byte) main::h#2 ) (byte) main::h#2 ← phi( main::@1/(byte) main::h#4 main::@2/(byte) main::h#2 )
(byte[]) main::his#1 ← phi( main::@1/(byte[]) main::his#2 main::@2/(byte[]) main::his#1 ) (byte[]) main::his#1 ← phi( main::@1/(byte[]) main::his#2 main::@2/(byte[]) main::his#1 )
(word) main::w#0 ← *((byte[]) main::his#1 + (byte) main::h#2) w= (byte) main::l#2 (word) main::w#0 ← { *((byte[]) main::his#1 + (byte) main::h#2), (byte) main::l#2 }
(byte*~) main::$5 ← ((byte*)) (word) main::w#0 (byte*~) main::$5 ← ((byte*)) (word) main::w#0
(byte*) main::sc#0 ← (byte*~) main::$5 (byte*) main::sc#0 ← (byte*~) main::$5
*((byte*) main::sc#0) ← (byte) '*' *((byte*) main::sc#0) ← (byte) '*'
@ -391,7 +390,7 @@ main::@2: scope:[main] from main::@1 main::@2
(byte) main::l#2 ← phi( main::@1/(byte) main::l#0 main::@2/(byte) main::l#1 ) (byte) main::l#2 ← phi( main::@1/(byte) main::l#0 main::@2/(byte) main::l#1 )
(byte) main::h#2 ← phi( main::@1/(byte) main::h#4 main::@2/(byte) main::h#2 ) (byte) main::h#2 ← phi( main::@1/(byte) main::h#4 main::@2/(byte) main::h#2 )
(byte[]) main::his#1 ← phi( main::@1/(byte[]) main::his#2 main::@2/(byte[]) main::his#1 ) (byte[]) main::his#1 ← phi( main::@1/(byte[]) main::his#2 main::@2/(byte[]) main::his#1 )
(word) main::w#0 ← *((byte[]) main::his#1 + (byte) main::h#2) w= (byte) main::l#2 (word) main::w#0 ← { *((byte[]) main::his#1 + (byte) main::h#2), (byte) main::l#2 }
(byte*) main::sc#0 ← ((byte*)) (word) main::w#0 (byte*) main::sc#0 ← ((byte*)) (word) main::w#0
*((byte*) main::sc#0) ← (byte) '*' *((byte*) main::sc#0) ← (byte) '*'
(byte) main::l#1 ← ++ (byte) main::l#2 (byte) main::l#1 ← ++ (byte) main::l#2
@ -436,7 +435,7 @@ main::@2: scope:[main] from main::@1 main::@2
(byte) main::l#2 ← phi( main::@1/(byte) main::l#0 main::@2/(byte) main::l#1 ) (byte) main::l#2 ← phi( main::@1/(byte) main::l#0 main::@2/(byte) main::l#1 )
(byte) main::h#2 ← phi( main::@1/(byte) main::h#4 ) (byte) main::h#2 ← phi( main::@1/(byte) main::h#4 )
(byte[]) main::his#1 ← phi( main::@1/(byte[]) main::his#2 ) (byte[]) main::his#1 ← phi( main::@1/(byte[]) main::his#2 )
(word) main::w#0 ← *((byte[]) main::his#1 + (byte) main::h#2) w= (byte) main::l#2 (word) main::w#0 ← { *((byte[]) main::his#1 + (byte) main::h#2), (byte) main::l#2 }
(byte*) main::sc#0 ← ((byte*)) (word) main::w#0 (byte*) main::sc#0 ← ((byte*)) (word) main::w#0
*((byte*) main::sc#0) ← (byte) '*' *((byte*) main::sc#0) ← (byte) '*'
(byte) main::l#1 ← ++ (byte) main::l#2 (byte) main::l#1 ← ++ (byte) main::l#2
@ -479,7 +478,7 @@ main::@1: scope:[main] from main main::@3
to:main::@2 to:main::@2
main::@2: scope:[main] from main::@1 main::@2 main::@2: scope:[main] from main::@1 main::@2
(byte) main::l#2 ← phi( main::@1/(byte) main::l#0 main::@2/(byte) main::l#1 ) (byte) main::l#2 ← phi( main::@1/(byte) main::l#0 main::@2/(byte) main::l#1 )
(word) main::w#0 ← *((byte[]) main::his#2 + (byte) main::h#4) w= (byte) main::l#2 (word) main::w#0 ← { *((byte[]) main::his#2 + (byte) main::h#4), (byte) main::l#2 }
(byte*) main::sc#0 ← ((byte*)) (word) main::w#0 (byte*) main::sc#0 ← ((byte*)) (word) main::w#0
*((byte*) main::sc#0) ← (byte) '*' *((byte*) main::sc#0) ← (byte) '*'
(byte) main::l#1 ← ++ (byte) main::l#2 (byte) main::l#1 ← ++ (byte) main::l#2
@ -522,7 +521,7 @@ main::@1: scope:[main] from main main::@3
to:main::@2 to:main::@2
main::@2: scope:[main] from main::@1 main::@2 main::@2: scope:[main] from main::@1 main::@2
(byte) main::l#2 ← phi( main::@1/(byte) main::l#0 main::@2/(byte) main::l#1 ) (byte) main::l#2 ← phi( main::@1/(byte) main::l#0 main::@2/(byte) main::l#1 )
(word) main::w#0 ← *((byte[]) main::his#2 + (byte) main::h#4) w= (byte) main::l#2 (word) main::w#0 ← { *((byte[]) main::his#2 + (byte) main::h#4), (byte) main::l#2 }
(byte*) main::sc#0 ← ((byte*)) (word) main::w#0 (byte*) main::sc#0 ← ((byte*)) (word) main::w#0
*((byte*) main::sc#0) ← (byte) '*' *((byte*) main::sc#0) ← (byte) '*'
(byte) main::l#1 ← ++ (byte) main::l#2 (byte) main::l#1 ← ++ (byte) main::l#2
@ -561,7 +560,7 @@ main::@1: scope:[main] from main main::@3
to:main::@2 to:main::@2
main::@2: scope:[main] from main::@1 main::@2 main::@2: scope:[main] from main::@1 main::@2
(byte) main::l#2 ← phi( main::@1/(const byte) main::l#0 main::@2/(byte) main::l#1 ) (byte) main::l#2 ← phi( main::@1/(const byte) main::l#0 main::@2/(byte) main::l#1 )
(word) main::w#0 ← *((byte[]) main::his#2 + (byte) main::h#4) w= (byte) main::l#2 (word) main::w#0 ← { *((byte[]) main::his#2 + (byte) main::h#4), (byte) main::l#2 }
(byte*) main::sc#0 ← ((byte*)) (word) main::w#0 (byte*) main::sc#0 ← ((byte*)) (word) main::w#0
*((byte*) main::sc#0) ← (byte) '*' *((byte*) main::sc#0) ← (byte) '*'
(byte) main::l#1 ← ++ (byte) main::l#2 (byte) main::l#1 ← ++ (byte) main::l#2
@ -597,7 +596,7 @@ main::@1: scope:[main] from main main::@3
to:main::@2 to:main::@2
main::@2: scope:[main] from main::@1 main::@2 main::@2: scope:[main] from main::@1 main::@2
(byte) main::l#2 ← phi( main::@1/(const byte) main::l#0 main::@2/(byte) main::l#1 ) (byte) main::l#2 ← phi( main::@1/(const byte) main::l#0 main::@2/(byte) main::l#1 )
(word) main::w#0 ← *((byte[]) main::his#2 + (byte) main::h#4) w= (byte) main::l#2 (word) main::w#0 ← { *((byte[]) main::his#2 + (byte) main::h#4), (byte) main::l#2 }
(byte*) main::sc#0 ← ((byte*)) (word) main::w#0 (byte*) main::sc#0 ← ((byte*)) (word) main::w#0
*((byte*) main::sc#0) ← (byte) '*' *((byte*) main::sc#0) ← (byte) '*'
(byte) main::l#1 ← ++ (byte) main::l#2 (byte) main::l#1 ← ++ (byte) main::l#2
@ -630,7 +629,7 @@ main::@1: scope:[main] from main main::@3
to:main::@2 to:main::@2
main::@2: scope:[main] from main::@1 main::@2 main::@2: scope:[main] from main::@1 main::@2
(byte) main::l#2 ← phi( main::@1/(const byte) main::l#0 main::@2/(byte) main::l#1 ) (byte) main::l#2 ← phi( main::@1/(const byte) main::l#0 main::@2/(byte) main::l#1 )
(word) main::w#0 ← *((byte[]) main::his#2 + (byte) main::h#4) w= (byte) main::l#2 (word) main::w#0 ← { *((byte[]) main::his#2 + (byte) main::h#4), (byte) main::l#2 }
(byte*) main::sc#0 ← ((byte*)) (word) main::w#0 (byte*) main::sc#0 ← ((byte*)) (word) main::w#0
*((byte*) main::sc#0) ← (byte) '*' *((byte*) main::sc#0) ← (byte) '*'
(byte) main::l#1 ← ++ (byte) main::l#2 (byte) main::l#1 ← ++ (byte) main::l#2
@ -651,6 +650,37 @@ main::@return: scope:[main] from main::@3
Constant (const byte[]) main::his#0 = { main::$0, main::$2, main::$4 } Constant (const byte[]) main::his#0 = { main::$0, main::$2, main::$4 }
Succesful SSA optimization Pass2ConstantIdentification Succesful SSA optimization Pass2ConstantIdentification
CONTROL FLOW GRAPH CONTROL FLOW GRAPH
@begin: scope:[] from
to:@1
main: scope:[main] from @1
to:main::@1
main::@1: scope:[main] from main main::@3
(byte) main::h#4 ← phi( main/(const byte) main::h#0 main::@3/(byte) main::h#1 )
(byte[]) main::his#2 ← phi( main/(const byte[]) main::his#0 main::@3/(byte[]) main::his#2 )
to:main::@2
main::@2: scope:[main] from main::@1 main::@2
(byte) main::l#2 ← phi( main::@1/(const byte) main::l#0 main::@2/(byte) main::l#1 )
(word) main::w#0 ← { *((byte[]) main::his#2 + (byte) main::h#4), (byte) main::l#2 }
(byte*) main::sc#0 ← ((byte*)) (word) main::w#0
*((byte*) main::sc#0) ← (byte) '*'
(byte) main::l#1 ← ++ (byte) main::l#2
if((byte) main::l#1!=(byte/signed byte/word/signed word) 8) goto main::@2
to:main::@3
main::@3: scope:[main] from main::@2
(byte) main::h#1 ← ++ (byte) main::h#4
if((byte) main::h#1!=(byte/signed byte/word/signed word) 3) goto main::@1
to:main::@return
main::@return: scope:[main] from main::@3
return
to:@return
@1: scope:[] from @begin
call main param-assignment
to:@end
@end: scope:[] from @1
Fixing word constructor with main::w#0 ← *(main::his#2 + main::h#4) w= main::l#2
Succesful SSA optimization Pass2FixWordConstructors
CONTROL FLOW GRAPH
@begin: scope:[] from @begin: scope:[] from
to:@1 to:@1
main: scope:[main] from @1 main: scope:[main] from @1

View File

@ -1,13 +1,13 @@
@begin: scope:[] from @begin: scope:[] from
[0] phi() [ ] ( ) [0] phi() [ ] ( )
to:@6 to:@7
@6: scope:[] from @begin @7: scope:[] from @begin
[1] phi() [ ] ( ) [1] phi() [ ] ( )
[2] call main param-assignment [ ] ( ) [2] call main param-assignment [ ] ( )
to:@end to:@end
@end: scope:[] from @6 @end: scope:[] from @7
[3] phi() [ ] ( ) [3] phi() [ ] ( )
main: scope:[main] from @6 main: scope:[main] from @7
[4] phi() [ ] ( main:2 [ ] ) [4] phi() [ ] ( main:2 [ ] )
[5] call print_str param-assignment [ char_cursor#13 ] ( main:2 [ char_cursor#13 ] ) [5] call print_str param-assignment [ char_cursor#13 ] ( main:2 [ char_cursor#13 ] )
to:main::@1 to:main::@1

View File

@ -52,10 +52,19 @@ void print_char(byte ch) {
*(char_cursor++) = ch; *(char_cursor++) = ch;
} }
// Clear the screen
void print_cls() {
for(byte* sc=$0400; sc!=$0400+1000; sc++) {
*sc = ' ';
}
}
Adding pre/post-modifier (byte*) char_cursor ← ++ (byte*) char_cursor Adding pre/post-modifier (byte*) char_cursor ← ++ (byte*) char_cursor
Adding pre/post-modifier (byte*) print_str::str ← ++ (byte*) print_str::str Adding pre/post-modifier (byte*) print_str::str ← ++ (byte*) print_str::str
Adding pre/post-modifier (byte*) char_cursor ← ++ (byte*) char_cursor Adding pre/post-modifier (byte*) char_cursor ← ++ (byte*) char_cursor
Adding pre/post-modifier (byte*) print_cls::sc ← ++ (byte*) print_cls::sc
PROGRAM PROGRAM
(byte*) line_cursor ← (word/signed word) 1024 (byte*) line_cursor ← (word/signed word) 1024
(byte*) char_cursor ← (byte*) line_cursor (byte*) char_cursor ← (byte*) line_cursor
@ -106,6 +115,17 @@ proc (void()) print_char((byte) print_char::ch)
print_char::@return: print_char::@return:
return return
endproc // print_char() endproc // print_char()
proc (void()) print_cls()
(byte*) print_cls::sc ← (word/signed word) 1024
print_cls::@1:
*((byte*) print_cls::sc) ← (byte) ' '
(byte*) print_cls::sc ← ++ (byte*) print_cls::sc
(word/signed word~) print_cls::$0 ← (word/signed word) 1024 + (word/signed word) 1000
(boolean~) print_cls::$1 ← (byte*) print_cls::sc != (word/signed word~) print_cls::$0
if((boolean~) print_cls::$1) goto print_cls::@1
print_cls::@return:
return
endproc // print_cls()
(byte[]) msg ← (string) "hello world! @" (byte[]) msg ← (string) "hello world! @"
(byte[]) msg2 ← (string) "hello c64! @" (byte[]) msg2 ← (string) "hello c64! @"
(byte[]) msg3 ← (string) "hello 2017! @" (byte[]) msg3 ← (string) "hello 2017! @"
@ -146,6 +166,12 @@ SYMBOLS
(void()) print_char((byte) print_char::ch) (void()) print_char((byte) print_char::ch)
(label) print_char::@return (label) print_char::@return
(byte) print_char::ch (byte) print_char::ch
(void()) print_cls()
(word/signed word~) print_cls::$0
(boolean~) print_cls::$1
(label) print_cls::@1
(label) print_cls::@return
(byte*) print_cls::sc
(void()) print_ln() (void()) print_ln()
(byte*~) print_ln::$0 (byte*~) print_ln::$0
(boolean~) print_ln::$1 (boolean~) print_ln::$1
@ -167,6 +193,7 @@ SYMBOLS
(word) print_word::w (word) print_word::w
Promoting word/signed word to byte* in line_cursor ← ((byte*)) 1024 Promoting word/signed word to byte* in line_cursor ← ((byte*)) 1024
Promoting word/signed word to byte* in print_cls::sc ← ((byte*)) 1024
INITIAL CONTROL FLOW GRAPH INITIAL CONTROL FLOW GRAPH
@begin: scope:[] from @begin: scope:[] from
(byte*) line_cursor ← ((byte*)) (word/signed word) 1024 (byte*) line_cursor ← ((byte*)) (word/signed word) 1024
@ -243,10 +270,27 @@ print_char::@return: scope:[print_char] from print_char
return return
to:@return to:@return
@5: scope:[] from @4 @5: scope:[] from @4
to:@6
print_cls: scope:[print_cls] from
(byte*) print_cls::sc ← ((byte*)) (word/signed word) 1024
to:print_cls::@1
print_cls::@1: scope:[print_cls] from print_cls print_cls::@1
*((byte*) print_cls::sc) ← (byte) ' '
(byte*) print_cls::sc ← ++ (byte*) print_cls::sc
(word/signed word~) print_cls::$0 ← (word/signed word) 1024 + (word/signed word) 1000
(boolean~) print_cls::$1 ← (byte*) print_cls::sc != (word/signed word~) print_cls::$0
if((boolean~) print_cls::$1) goto print_cls::@1
to:print_cls::@2
print_cls::@2: scope:[print_cls] from print_cls::@1
to:print_cls::@return
print_cls::@return: scope:[print_cls] from print_cls::@2
return
to:@return
@6: scope:[] from @5
(byte[]) msg ← (string) "hello world! @" (byte[]) msg ← (string) "hello world! @"
(byte[]) msg2 ← (string) "hello c64! @" (byte[]) msg2 ← (string) "hello c64! @"
(byte[]) msg3 ← (string) "hello 2017! @" (byte[]) msg3 ← (string) "hello 2017! @"
to:@6 to:@7
main: scope:[main] from main: scope:[main] from
(void~) main::$0 ← call print_str (byte[]) msg (void~) main::$0 ← call print_str (byte[]) msg
(void~) main::$1 ← call print_ln (void~) main::$1 ← call print_ln
@ -258,12 +302,13 @@ main: scope:[main] from
main::@return: scope:[main] from main main::@return: scope:[main] from main
return return
to:@return to:@return
@6: scope:[] from @5 @7: scope:[] from @6
call main call main
to:@end to:@end
@end: scope:[] from @6 @end: scope:[] from @7
Removing unused procedure print_word Removing unused procedure print_word
Removing unused procedure print_cls
Removing unused procedure print_byte Removing unused procedure print_byte
Removing unused procedure print_char Removing unused procedure print_char
Eliminating unused variable - keeping the call (void~) main::$0 Eliminating unused variable - keeping the call (void~) main::$0
@ -280,11 +325,12 @@ Removing empty block @1
Removing empty block @2 Removing empty block @2
Removing empty block @3 Removing empty block @3
Removing empty block @4 Removing empty block @4
Removing empty block @5
CONTROL FLOW GRAPH CONTROL FLOW GRAPH
@begin: scope:[] from @begin: scope:[] from
(byte*) line_cursor ← ((byte*)) (word/signed word) 1024 (byte*) line_cursor ← ((byte*)) (word/signed word) 1024
(byte*) char_cursor ← (byte*) line_cursor (byte*) char_cursor ← (byte*) line_cursor
to:@5 to:@6
print_str: scope:[print_str] from print_str: scope:[print_str] from
to:print_str::@1 to:print_str::@1
print_str::@1: scope:[print_str] from print_str print_str::@2 print_str::@1: scope:[print_str] from print_str print_str::@2
@ -313,11 +359,11 @@ print_ln::@2: scope:[print_ln] from print_ln::@1
print_ln::@return: scope:[print_ln] from print_ln::@2 print_ln::@return: scope:[print_ln] from print_ln::@2
return return
to:@return to:@return
@5: scope:[] from @begin @6: scope:[] from @begin
(byte[]) msg ← (string) "hello world! @" (byte[]) msg ← (string) "hello world! @"
(byte[]) msg2 ← (string) "hello c64! @" (byte[]) msg2 ← (string) "hello c64! @"
(byte[]) msg3 ← (string) "hello 2017! @" (byte[]) msg3 ← (string) "hello 2017! @"
to:@6 to:@7
main: scope:[main] from main: scope:[main] from
call print_str (byte[]) msg call print_str (byte[]) msg
call print_ln call print_ln
@ -329,10 +375,10 @@ main: scope:[main] from
main::@return: scope:[main] from main main::@return: scope:[main] from main
return return
to:@return to:@return
@6: scope:[] from @5 @7: scope:[] from @6
call main call main
to:@end to:@end
@end: scope:[] from @6 @end: scope:[] from @7
PROCEDURE MODIFY VARIABLE ANALYSIS PROCEDURE MODIFY VARIABLE ANALYSIS
print_str modifies char_cursor print_str modifies char_cursor
@ -345,7 +391,7 @@ CONTROL FLOW GRAPH WITH ASSIGNMENT CALL
@begin: scope:[] from @begin: scope:[] from
(byte*) line_cursor ← ((byte*)) (word/signed word) 1024 (byte*) line_cursor ← ((byte*)) (word/signed word) 1024
(byte*) char_cursor ← (byte*) line_cursor (byte*) char_cursor ← (byte*) line_cursor
to:@5 to:@6
print_str: scope:[print_str] from main main::@2 main::@4 print_str: scope:[print_str] from main main::@2 main::@4
to:print_str::@1 to:print_str::@1
print_str::@1: scope:[print_str] from print_str print_str::@2 print_str::@1: scope:[print_str] from print_str print_str::@2
@ -377,12 +423,12 @@ print_ln::@return: scope:[print_ln] from print_ln::@2
(byte*) char_cursor ← (byte*) char_cursor (byte*) char_cursor ← (byte*) char_cursor
return return
to:@return to:@return
@5: scope:[] from @begin @6: scope:[] from @begin
(byte[]) msg ← (string) "hello world! @" (byte[]) msg ← (string) "hello world! @"
(byte[]) msg2 ← (string) "hello c64! @" (byte[]) msg2 ← (string) "hello c64! @"
(byte[]) msg3 ← (string) "hello 2017! @" (byte[]) msg3 ← (string) "hello 2017! @"
to:@6 to:@7
main: scope:[main] from @6 main: scope:[main] from @7
(byte*) print_str::str ← (byte[]) msg (byte*) print_str::str ← (byte[]) msg
call print_str param-assignment call print_str param-assignment
to:main::@1 to:main::@1
@ -419,14 +465,14 @@ main::@return: scope:[main] from main::@6
(byte*) line_cursor ← (byte*) line_cursor (byte*) line_cursor ← (byte*) line_cursor
return return
to:@return to:@return
@6: scope:[] from @5
call main param-assignment
to:@7
@7: scope:[] from @6 @7: scope:[] from @6
call main param-assignment
to:@8
@8: scope:[] from @7
(byte*) char_cursor ← (byte*) char_cursor (byte*) char_cursor ← (byte*) char_cursor
(byte*) line_cursor ← (byte*) line_cursor (byte*) line_cursor ← (byte*) line_cursor
to:@end to:@end
@end: scope:[] from @7 @end: scope:[] from @8
Completing Phi functions... Completing Phi functions...
Completing Phi functions... Completing Phi functions...
@ -438,7 +484,7 @@ CONTROL FLOW GRAPH SSA
@begin: scope:[] from @begin: scope:[] from
(byte*) line_cursor#0 ← ((byte*)) (word/signed word) 1024 (byte*) line_cursor#0 ← ((byte*)) (word/signed word) 1024
(byte*) char_cursor#0 ← (byte*) line_cursor#0 (byte*) char_cursor#0 ← (byte*) line_cursor#0
to:@5 to:@6
print_str: scope:[print_str] from main main::@2 main::@4 print_str: scope:[print_str] from main main::@2 main::@4
(byte*) char_cursor#29 ← phi( main/(byte*) char_cursor#27 main::@2/(byte*) char_cursor#6 main::@4/(byte*) char_cursor#8 ) (byte*) char_cursor#29 ← phi( main/(byte*) char_cursor#27 main::@2/(byte*) char_cursor#6 main::@4/(byte*) char_cursor#8 )
(byte*) print_str::str#6 ← phi( main/(byte*) print_str::str#1 main::@2/(byte*) print_str::str#2 main::@4/(byte*) print_str::str#3 ) (byte*) print_str::str#6 ← phi( main/(byte*) print_str::str#1 main::@2/(byte*) print_str::str#2 main::@4/(byte*) print_str::str#3 )
@ -484,19 +530,19 @@ print_ln::@return: scope:[print_ln] from print_ln::@2
(byte*) char_cursor#4 ← (byte*) char_cursor#16 (byte*) char_cursor#4 ← (byte*) char_cursor#16
return return
to:@return to:@return
@5: scope:[] from @begin @6: scope:[] from @begin
(byte*) line_cursor#22 ← phi( @begin/(byte*) line_cursor#0 ) (byte*) line_cursor#22 ← phi( @begin/(byte*) line_cursor#0 )
(byte*) char_cursor#30 ← phi( @begin/(byte*) char_cursor#0 ) (byte*) char_cursor#30 ← phi( @begin/(byte*) char_cursor#0 )
(byte[]) msg#0 ← (string) "hello world! @" (byte[]) msg#0 ← (string) "hello world! @"
(byte[]) msg2#0 ← (string) "hello c64! @" (byte[]) msg2#0 ← (string) "hello c64! @"
(byte[]) msg3#0 ← (string) "hello 2017! @" (byte[]) msg3#0 ← (string) "hello 2017! @"
to:@6 to:@7
main: scope:[main] from @6 main: scope:[main] from @7
(byte[]) msg3#5 ← phi( @6/(byte[]) msg3#6 ) (byte[]) msg3#5 ← phi( @7/(byte[]) msg3#6 )
(byte[]) msg2#3 ← phi( @6/(byte[]) msg2#4 ) (byte[]) msg2#3 ← phi( @7/(byte[]) msg2#4 )
(byte*) line_cursor#21 ← phi( @6/(byte*) line_cursor#20 ) (byte*) line_cursor#21 ← phi( @7/(byte*) line_cursor#20 )
(byte*) char_cursor#27 ← phi( @6/(byte*) char_cursor#28 ) (byte*) char_cursor#27 ← phi( @7/(byte*) char_cursor#28 )
(byte[]) msg#1 ← phi( @6/(byte[]) msg#2 ) (byte[]) msg#1 ← phi( @7/(byte[]) msg#2 )
(byte*) print_str::str#1 ← (byte[]) msg#1 (byte*) print_str::str#1 ← (byte[]) msg#1
call print_str param-assignment call print_str param-assignment
to:main::@1 to:main::@1
@ -553,27 +599,27 @@ main::@return: scope:[main] from main::@6
(byte*) line_cursor#6 ← (byte*) line_cursor#14 (byte*) line_cursor#6 ← (byte*) line_cursor#14
return return
to:@return to:@return
@6: scope:[] from @5
(byte[]) msg3#6 ← phi( @5/(byte[]) msg3#0 )
(byte[]) msg2#4 ← phi( @5/(byte[]) msg2#0 )
(byte*) line_cursor#20 ← phi( @5/(byte*) line_cursor#22 )
(byte*) char_cursor#28 ← phi( @5/(byte*) char_cursor#30 )
(byte[]) msg#2 ← phi( @5/(byte[]) msg#0 )
call main param-assignment
to:@7
@7: scope:[] from @6 @7: scope:[] from @6
(byte*) line_cursor#15 ← phi( @6/(byte*) line_cursor#20 ) (byte[]) msg3#6 ← phi( @6/(byte[]) msg3#0 )
(byte*) char_cursor#24 ← phi( @6/(byte*) char_cursor#28 ) (byte[]) msg2#4 ← phi( @6/(byte[]) msg2#0 )
(byte*) line_cursor#20 ← phi( @6/(byte*) line_cursor#22 )
(byte*) char_cursor#28 ← phi( @6/(byte*) char_cursor#30 )
(byte[]) msg#2 ← phi( @6/(byte[]) msg#0 )
call main param-assignment
to:@8
@8: scope:[] from @7
(byte*) line_cursor#15 ← phi( @7/(byte*) line_cursor#20 )
(byte*) char_cursor#24 ← phi( @7/(byte*) char_cursor#28 )
(byte*) char_cursor#12 ← (byte*) char_cursor#24 (byte*) char_cursor#12 ← (byte*) char_cursor#24
(byte*) line_cursor#7 ← (byte*) line_cursor#15 (byte*) line_cursor#7 ← (byte*) line_cursor#15
to:@end to:@end
@end: scope:[] from @7 @end: scope:[] from @8
CONTROL FLOW GRAPH WITH ASSIGNMENT CALL & RETURN CONTROL FLOW GRAPH WITH ASSIGNMENT CALL & RETURN
@begin: scope:[] from @begin: scope:[] from
(byte*) line_cursor#0 ← ((byte*)) (word/signed word) 1024 (byte*) line_cursor#0 ← ((byte*)) (word/signed word) 1024
(byte*) char_cursor#0 ← (byte*) line_cursor#0 (byte*) char_cursor#0 ← (byte*) line_cursor#0
to:@5 to:@6
print_str: scope:[print_str] from main main::@2 main::@4 print_str: scope:[print_str] from main main::@2 main::@4
(byte*) char_cursor#29 ← phi( main/(byte*) char_cursor#27 main::@2/(byte*) char_cursor#6 main::@4/(byte*) char_cursor#8 ) (byte*) char_cursor#29 ← phi( main/(byte*) char_cursor#27 main::@2/(byte*) char_cursor#6 main::@4/(byte*) char_cursor#8 )
(byte*) print_str::str#6 ← phi( main/(byte*) print_str::str#1 main::@2/(byte*) print_str::str#2 main::@4/(byte*) print_str::str#3 ) (byte*) print_str::str#6 ← phi( main/(byte*) print_str::str#1 main::@2/(byte*) print_str::str#2 main::@4/(byte*) print_str::str#3 )
@ -619,19 +665,19 @@ print_ln::@return: scope:[print_ln] from print_ln::@2
(byte*) char_cursor#4 ← (byte*) char_cursor#16 (byte*) char_cursor#4 ← (byte*) char_cursor#16
return return
to:@return to:@return
@5: scope:[] from @begin @6: scope:[] from @begin
(byte*) line_cursor#22 ← phi( @begin/(byte*) line_cursor#0 ) (byte*) line_cursor#22 ← phi( @begin/(byte*) line_cursor#0 )
(byte*) char_cursor#30 ← phi( @begin/(byte*) char_cursor#0 ) (byte*) char_cursor#30 ← phi( @begin/(byte*) char_cursor#0 )
(byte[]) msg#0 ← (string) "hello world! @" (byte[]) msg#0 ← (string) "hello world! @"
(byte[]) msg2#0 ← (string) "hello c64! @" (byte[]) msg2#0 ← (string) "hello c64! @"
(byte[]) msg3#0 ← (string) "hello 2017! @" (byte[]) msg3#0 ← (string) "hello 2017! @"
to:@6 to:@7
main: scope:[main] from @6 main: scope:[main] from @7
(byte[]) msg3#5 ← phi( @6/(byte[]) msg3#6 ) (byte[]) msg3#5 ← phi( @7/(byte[]) msg3#6 )
(byte[]) msg2#3 ← phi( @6/(byte[]) msg2#4 ) (byte[]) msg2#3 ← phi( @7/(byte[]) msg2#4 )
(byte*) line_cursor#21 ← phi( @6/(byte*) line_cursor#20 ) (byte*) line_cursor#21 ← phi( @7/(byte*) line_cursor#20 )
(byte*) char_cursor#27 ← phi( @6/(byte*) char_cursor#28 ) (byte*) char_cursor#27 ← phi( @7/(byte*) char_cursor#28 )
(byte[]) msg#1 ← phi( @6/(byte[]) msg#2 ) (byte[]) msg#1 ← phi( @7/(byte[]) msg#2 )
(byte*) print_str::str#1 ← (byte[]) msg#1 (byte*) print_str::str#1 ← (byte[]) msg#1
call print_str param-assignment call print_str param-assignment
to:main::@1 to:main::@1
@ -688,26 +734,26 @@ main::@return: scope:[main] from main::@6
(byte*) line_cursor#6 ← (byte*) line_cursor#14 (byte*) line_cursor#6 ← (byte*) line_cursor#14
return return
to:@return to:@return
@6: scope:[] from @5
(byte[]) msg3#6 ← phi( @5/(byte[]) msg3#0 )
(byte[]) msg2#4 ← phi( @5/(byte[]) msg2#0 )
(byte*) line_cursor#20 ← phi( @5/(byte*) line_cursor#22 )
(byte*) char_cursor#28 ← phi( @5/(byte*) char_cursor#30 )
(byte[]) msg#2 ← phi( @5/(byte[]) msg#0 )
call main param-assignment
to:@7
@7: scope:[] from @6 @7: scope:[] from @6
(byte*) line_cursor#15 ← phi( @6/(byte*) line_cursor#6 ) (byte[]) msg3#6 ← phi( @6/(byte[]) msg3#0 )
(byte*) char_cursor#24 ← phi( @6/(byte*) char_cursor#11 ) (byte[]) msg2#4 ← phi( @6/(byte[]) msg2#0 )
(byte*) line_cursor#20 ← phi( @6/(byte*) line_cursor#22 )
(byte*) char_cursor#28 ← phi( @6/(byte*) char_cursor#30 )
(byte[]) msg#2 ← phi( @6/(byte[]) msg#0 )
call main param-assignment
to:@8
@8: scope:[] from @7
(byte*) line_cursor#15 ← phi( @7/(byte*) line_cursor#6 )
(byte*) char_cursor#24 ← phi( @7/(byte*) char_cursor#11 )
(byte*) char_cursor#12 ← (byte*) char_cursor#24 (byte*) char_cursor#12 ← (byte*) char_cursor#24
(byte*) line_cursor#7 ← (byte*) line_cursor#15 (byte*) line_cursor#7 ← (byte*) line_cursor#15
to:@end to:@end
@end: scope:[] from @7 @end: scope:[] from @8
INITIAL SSA SYMBOL TABLE INITIAL SSA SYMBOL TABLE
(label) @5
(label) @6 (label) @6
(label) @7 (label) @7
(label) @8
(label) @begin (label) @begin
(label) @end (label) @end
(byte*) char_cursor (byte*) char_cursor
@ -860,7 +906,7 @@ Succesful SSA optimization Pass2AliasElimination
CONTROL FLOW GRAPH CONTROL FLOW GRAPH
@begin: scope:[] from @begin: scope:[] from
(byte*) char_cursor#0 ← ((byte*)) (word/signed word) 1024 (byte*) char_cursor#0 ← ((byte*)) (word/signed word) 1024
to:@5 to:@6
print_str: scope:[print_str] from main main::@2 main::@4 print_str: scope:[print_str] from main main::@2 main::@4
(byte*) char_cursor#29 ← phi( main/(byte*) char_cursor#27 main::@2/(byte*) char_cursor#18 main::@4/(byte*) char_cursor#20 ) (byte*) char_cursor#29 ← phi( main/(byte*) char_cursor#27 main::@2/(byte*) char_cursor#18 main::@4/(byte*) char_cursor#20 )
(byte*) print_str::str#6 ← phi( main/(byte*) print_str::str#1 main::@2/(byte*) print_str::str#2 main::@4/(byte*) print_str::str#3 ) (byte*) print_str::str#6 ← phi( main/(byte*) print_str::str#1 main::@2/(byte*) print_str::str#2 main::@4/(byte*) print_str::str#3 )
@ -895,17 +941,17 @@ print_ln::@2: scope:[print_ln] from print_ln::@1
print_ln::@return: scope:[print_ln] from print_ln::@2 print_ln::@return: scope:[print_ln] from print_ln::@2
return return
to:@return to:@return
@5: scope:[] from @begin @6: scope:[] from @begin
(byte[]) msg#0 ← (string) "hello world! @" (byte[]) msg#0 ← (string) "hello world! @"
(byte[]) msg2#0 ← (string) "hello c64! @" (byte[]) msg2#0 ← (string) "hello c64! @"
(byte[]) msg3#0 ← (string) "hello 2017! @" (byte[]) msg3#0 ← (string) "hello 2017! @"
to:@6 to:@7
main: scope:[main] from @6 main: scope:[main] from @7
(byte[]) msg3#1 ← phi( @6/(byte[]) msg3#0 ) (byte[]) msg3#1 ← phi( @7/(byte[]) msg3#0 )
(byte[]) msg2#1 ← phi( @6/(byte[]) msg2#0 ) (byte[]) msg2#1 ← phi( @7/(byte[]) msg2#0 )
(byte*) line_cursor#17 ← phi( @6/(byte*) char_cursor#0 ) (byte*) line_cursor#17 ← phi( @7/(byte*) char_cursor#0 )
(byte*) char_cursor#27 ← phi( @6/(byte*) char_cursor#0 ) (byte*) char_cursor#27 ← phi( @7/(byte*) char_cursor#0 )
(byte[]) msg#1 ← phi( @6/(byte[]) msg#0 ) (byte[]) msg#1 ← phi( @7/(byte[]) msg#0 )
(byte*) print_str::str#1 ← (byte[]) msg#1 (byte*) print_str::str#1 ← (byte[]) msg#1
call print_str param-assignment call print_str param-assignment
to:main::@1 to:main::@1
@ -940,14 +986,14 @@ main::@6: scope:[main] from main::@5
main::@return: scope:[main] from main::@6 main::@return: scope:[main] from main::@6
return return
to:@return to:@return
@6: scope:[] from @5
call main param-assignment
to:@7
@7: scope:[] from @6 @7: scope:[] from @6
(byte*) line_cursor#15 ← phi( @6/(byte*) line_cursor#13 ) call main param-assignment
(byte*) char_cursor#12 ← phi( @6/(byte*) char_cursor#10 ) to:@8
@8: scope:[] from @7
(byte*) line_cursor#15 ← phi( @7/(byte*) line_cursor#13 )
(byte*) char_cursor#12 ← phi( @7/(byte*) char_cursor#10 )
to:@end to:@end
@end: scope:[] from @7 @end: scope:[] from @8
Not aliassing across scopes: print_str::str#6 print_str::str#1 Not aliassing across scopes: print_str::str#6 print_str::str#1
Not aliassing across scopes: char_cursor#29 char_cursor#27 Not aliassing across scopes: char_cursor#29 char_cursor#27
@ -977,7 +1023,7 @@ Succesful SSA optimization Pass2SelfPhiElimination
CONTROL FLOW GRAPH CONTROL FLOW GRAPH
@begin: scope:[] from @begin: scope:[] from
(byte*) char_cursor#0 ← ((byte*)) (word/signed word) 1024 (byte*) char_cursor#0 ← ((byte*)) (word/signed word) 1024
to:@5 to:@6
print_str: scope:[print_str] from main main::@2 main::@4 print_str: scope:[print_str] from main main::@2 main::@4
(byte*) char_cursor#29 ← phi( main/(byte*) char_cursor#27 main::@2/(byte*) char_cursor#18 main::@4/(byte*) char_cursor#20 ) (byte*) char_cursor#29 ← phi( main/(byte*) char_cursor#27 main::@2/(byte*) char_cursor#18 main::@4/(byte*) char_cursor#20 )
(byte*) print_str::str#6 ← phi( main/(byte*) print_str::str#1 main::@2/(byte*) print_str::str#2 main::@4/(byte*) print_str::str#3 ) (byte*) print_str::str#6 ← phi( main/(byte*) print_str::str#1 main::@2/(byte*) print_str::str#2 main::@4/(byte*) print_str::str#3 )
@ -1012,17 +1058,17 @@ print_ln::@2: scope:[print_ln] from print_ln::@1
print_ln::@return: scope:[print_ln] from print_ln::@2 print_ln::@return: scope:[print_ln] from print_ln::@2
return return
to:@return to:@return
@5: scope:[] from @begin @6: scope:[] from @begin
(byte[]) msg#0 ← (string) "hello world! @" (byte[]) msg#0 ← (string) "hello world! @"
(byte[]) msg2#0 ← (string) "hello c64! @" (byte[]) msg2#0 ← (string) "hello c64! @"
(byte[]) msg3#0 ← (string) "hello 2017! @" (byte[]) msg3#0 ← (string) "hello 2017! @"
to:@6 to:@7
main: scope:[main] from @6 main: scope:[main] from @7
(byte[]) msg3#1 ← phi( @6/(byte[]) msg3#0 ) (byte[]) msg3#1 ← phi( @7/(byte[]) msg3#0 )
(byte[]) msg2#1 ← phi( @6/(byte[]) msg2#0 ) (byte[]) msg2#1 ← phi( @7/(byte[]) msg2#0 )
(byte*) line_cursor#17 ← phi( @6/(byte*) char_cursor#0 ) (byte*) line_cursor#17 ← phi( @7/(byte*) char_cursor#0 )
(byte*) char_cursor#27 ← phi( @6/(byte*) char_cursor#0 ) (byte*) char_cursor#27 ← phi( @7/(byte*) char_cursor#0 )
(byte[]) msg#1 ← phi( @6/(byte[]) msg#0 ) (byte[]) msg#1 ← phi( @7/(byte[]) msg#0 )
(byte*) print_str::str#1 ← (byte[]) msg#1 (byte*) print_str::str#1 ← (byte[]) msg#1
call print_str param-assignment call print_str param-assignment
to:main::@1 to:main::@1
@ -1057,14 +1103,14 @@ main::@6: scope:[main] from main::@5
main::@return: scope:[main] from main::@6 main::@return: scope:[main] from main::@6
return return
to:@return to:@return
@6: scope:[] from @5
call main param-assignment
to:@7
@7: scope:[] from @6 @7: scope:[] from @6
(byte*) line_cursor#15 ← phi( @6/(byte*) line_cursor#13 ) call main param-assignment
(byte*) char_cursor#12 ← phi( @6/(byte*) char_cursor#10 ) to:@8
@8: scope:[] from @7
(byte*) line_cursor#15 ← phi( @7/(byte*) line_cursor#13 )
(byte*) char_cursor#12 ← phi( @7/(byte*) char_cursor#10 )
to:@end to:@end
@end: scope:[] from @7 @end: scope:[] from @8
Redundant Phi (byte*) char_cursor#15 (byte*) char_cursor#26 Redundant Phi (byte*) char_cursor#15 (byte*) char_cursor#26
Redundant Phi (byte[]) msg#1 (byte[]) msg#0 Redundant Phi (byte[]) msg#1 (byte[]) msg#0
@ -1087,7 +1133,7 @@ Succesful SSA optimization Pass2RedundantPhiElimination
CONTROL FLOW GRAPH CONTROL FLOW GRAPH
@begin: scope:[] from @begin: scope:[] from
(byte*) char_cursor#0 ← ((byte*)) (word/signed word) 1024 (byte*) char_cursor#0 ← ((byte*)) (word/signed word) 1024
to:@5 to:@6
print_str: scope:[print_str] from main main::@2 main::@4 print_str: scope:[print_str] from main main::@2 main::@4
(byte*) char_cursor#29 ← phi( main/(byte*) char_cursor#0 main::@2/(byte*) line_cursor#1 main::@4/(byte*) line_cursor#1 ) (byte*) char_cursor#29 ← phi( main/(byte*) char_cursor#0 main::@2/(byte*) line_cursor#1 main::@4/(byte*) line_cursor#1 )
(byte*) print_str::str#6 ← phi( main/(byte*) print_str::str#1 main::@2/(byte*) print_str::str#2 main::@4/(byte*) print_str::str#3 ) (byte*) print_str::str#6 ← phi( main/(byte*) print_str::str#1 main::@2/(byte*) print_str::str#2 main::@4/(byte*) print_str::str#3 )
@ -1121,12 +1167,12 @@ print_ln::@2: scope:[print_ln] from print_ln::@1
print_ln::@return: scope:[print_ln] from print_ln::@2 print_ln::@return: scope:[print_ln] from print_ln::@2
return return
to:@return to:@return
@5: scope:[] from @begin @6: scope:[] from @begin
(byte[]) msg#0 ← (string) "hello world! @" (byte[]) msg#0 ← (string) "hello world! @"
(byte[]) msg2#0 ← (string) "hello c64! @" (byte[]) msg2#0 ← (string) "hello c64! @"
(byte[]) msg3#0 ← (string) "hello 2017! @" (byte[]) msg3#0 ← (string) "hello 2017! @"
to:@6 to:@7
main: scope:[main] from @6 main: scope:[main] from @7
(byte*) print_str::str#1 ← (byte[]) msg#0 (byte*) print_str::str#1 ← (byte[]) msg#0
call print_str param-assignment call print_str param-assignment
to:main::@1 to:main::@1
@ -1152,19 +1198,19 @@ main::@6: scope:[main] from main::@5
main::@return: scope:[main] from main::@6 main::@return: scope:[main] from main::@6
return return
to:@return to:@return
@6: scope:[] from @5
call main param-assignment
to:@7
@7: scope:[] from @6 @7: scope:[] from @6
call main param-assignment
to:@8
@8: scope:[] from @7
to:@end to:@end
@end: scope:[] from @7 @end: scope:[] from @8
Redundant Phi (byte*) char_cursor#26 (byte*) char_cursor#13 Redundant Phi (byte*) char_cursor#26 (byte*) char_cursor#13
Succesful SSA optimization Pass2RedundantPhiElimination Succesful SSA optimization Pass2RedundantPhiElimination
CONTROL FLOW GRAPH CONTROL FLOW GRAPH
@begin: scope:[] from @begin: scope:[] from
(byte*) char_cursor#0 ← ((byte*)) (word/signed word) 1024 (byte*) char_cursor#0 ← ((byte*)) (word/signed word) 1024
to:@5 to:@6
print_str: scope:[print_str] from main main::@2 main::@4 print_str: scope:[print_str] from main main::@2 main::@4
(byte*) char_cursor#29 ← phi( main/(byte*) char_cursor#0 main::@2/(byte*) line_cursor#1 main::@4/(byte*) line_cursor#1 ) (byte*) char_cursor#29 ← phi( main/(byte*) char_cursor#0 main::@2/(byte*) line_cursor#1 main::@4/(byte*) line_cursor#1 )
(byte*) print_str::str#6 ← phi( main/(byte*) print_str::str#1 main::@2/(byte*) print_str::str#2 main::@4/(byte*) print_str::str#3 ) (byte*) print_str::str#6 ← phi( main/(byte*) print_str::str#1 main::@2/(byte*) print_str::str#2 main::@4/(byte*) print_str::str#3 )
@ -1197,12 +1243,12 @@ print_ln::@2: scope:[print_ln] from print_ln::@1
print_ln::@return: scope:[print_ln] from print_ln::@2 print_ln::@return: scope:[print_ln] from print_ln::@2
return return
to:@return to:@return
@5: scope:[] from @begin @6: scope:[] from @begin
(byte[]) msg#0 ← (string) "hello world! @" (byte[]) msg#0 ← (string) "hello world! @"
(byte[]) msg2#0 ← (string) "hello c64! @" (byte[]) msg2#0 ← (string) "hello c64! @"
(byte[]) msg3#0 ← (string) "hello 2017! @" (byte[]) msg3#0 ← (string) "hello 2017! @"
to:@6 to:@7
main: scope:[main] from @6 main: scope:[main] from @7
(byte*) print_str::str#1 ← (byte[]) msg#0 (byte*) print_str::str#1 ← (byte[]) msg#0
call print_str param-assignment call print_str param-assignment
to:main::@1 to:main::@1
@ -1228,12 +1274,12 @@ main::@6: scope:[main] from main::@5
main::@return: scope:[main] from main::@6 main::@return: scope:[main] from main::@6
return return
to:@return to:@return
@6: scope:[] from @5
call main param-assignment
to:@7
@7: scope:[] from @6 @7: scope:[] from @6
call main param-assignment
to:@8
@8: scope:[] from @7
to:@end to:@end
@end: scope:[] from @7 @end: scope:[] from @8
Simple Condition (boolean~) print_str::$0 if(*((byte*) print_str::str#4)!=(byte) '@') goto print_str::@2 Simple Condition (boolean~) print_str::$0 if(*((byte*) print_str::str#4)!=(byte) '@') goto print_str::@2
Simple Condition (boolean~) print_ln::$1 if((byte*) line_cursor#1<(byte*) char_cursor#13) goto print_ln::@1 Simple Condition (boolean~) print_ln::$1 if((byte*) line_cursor#1<(byte*) char_cursor#13) goto print_ln::@1
@ -1241,7 +1287,7 @@ Succesful SSA optimization Pass2ConditionalJumpSimplification
CONTROL FLOW GRAPH CONTROL FLOW GRAPH
@begin: scope:[] from @begin: scope:[] from
(byte*) char_cursor#0 ← ((byte*)) (word/signed word) 1024 (byte*) char_cursor#0 ← ((byte*)) (word/signed word) 1024
to:@5 to:@6
print_str: scope:[print_str] from main main::@2 main::@4 print_str: scope:[print_str] from main main::@2 main::@4
(byte*) char_cursor#29 ← phi( main/(byte*) char_cursor#0 main::@2/(byte*) line_cursor#1 main::@4/(byte*) line_cursor#1 ) (byte*) char_cursor#29 ← phi( main/(byte*) char_cursor#0 main::@2/(byte*) line_cursor#1 main::@4/(byte*) line_cursor#1 )
(byte*) print_str::str#6 ← phi( main/(byte*) print_str::str#1 main::@2/(byte*) print_str::str#2 main::@4/(byte*) print_str::str#3 ) (byte*) print_str::str#6 ← phi( main/(byte*) print_str::str#1 main::@2/(byte*) print_str::str#2 main::@4/(byte*) print_str::str#3 )
@ -1272,12 +1318,12 @@ print_ln::@2: scope:[print_ln] from print_ln::@1
print_ln::@return: scope:[print_ln] from print_ln::@2 print_ln::@return: scope:[print_ln] from print_ln::@2
return return
to:@return to:@return
@5: scope:[] from @begin @6: scope:[] from @begin
(byte[]) msg#0 ← (string) "hello world! @" (byte[]) msg#0 ← (string) "hello world! @"
(byte[]) msg2#0 ← (string) "hello c64! @" (byte[]) msg2#0 ← (string) "hello c64! @"
(byte[]) msg3#0 ← (string) "hello 2017! @" (byte[]) msg3#0 ← (string) "hello 2017! @"
to:@6 to:@7
main: scope:[main] from @6 main: scope:[main] from @7
(byte*) print_str::str#1 ← (byte[]) msg#0 (byte*) print_str::str#1 ← (byte[]) msg#0
call print_str param-assignment call print_str param-assignment
to:main::@1 to:main::@1
@ -1303,12 +1349,12 @@ main::@6: scope:[main] from main::@5
main::@return: scope:[main] from main::@6 main::@return: scope:[main] from main::@6
return return
to:@return to:@return
@6: scope:[] from @5
call main param-assignment
to:@7
@7: scope:[] from @6 @7: scope:[] from @6
call main param-assignment
to:@8
@8: scope:[] from @7
to:@end to:@end
@end: scope:[] from @7 @end: scope:[] from @8
Constant (const byte*) char_cursor#0 = ((byte*))1024 Constant (const byte*) char_cursor#0 = ((byte*))1024
Constant (const byte[]) msg#0 = "hello world! @" Constant (const byte[]) msg#0 = "hello world! @"
@ -1317,7 +1363,7 @@ Constant (const byte[]) msg3#0 = "hello 2017! @"
Succesful SSA optimization Pass2ConstantIdentification Succesful SSA optimization Pass2ConstantIdentification
CONTROL FLOW GRAPH CONTROL FLOW GRAPH
@begin: scope:[] from @begin: scope:[] from
to:@5 to:@6
print_str: scope:[print_str] from main main::@2 main::@4 print_str: scope:[print_str] from main main::@2 main::@4
(byte*) char_cursor#29 ← phi( main/(const byte*) char_cursor#0 main::@2/(byte*) line_cursor#1 main::@4/(byte*) line_cursor#1 ) (byte*) char_cursor#29 ← phi( main/(const byte*) char_cursor#0 main::@2/(byte*) line_cursor#1 main::@4/(byte*) line_cursor#1 )
(byte*) print_str::str#6 ← phi( main/(byte*) print_str::str#1 main::@2/(byte*) print_str::str#2 main::@4/(byte*) print_str::str#3 ) (byte*) print_str::str#6 ← phi( main/(byte*) print_str::str#1 main::@2/(byte*) print_str::str#2 main::@4/(byte*) print_str::str#3 )
@ -1348,9 +1394,9 @@ print_ln::@2: scope:[print_ln] from print_ln::@1
print_ln::@return: scope:[print_ln] from print_ln::@2 print_ln::@return: scope:[print_ln] from print_ln::@2
return return
to:@return to:@return
@5: scope:[] from @begin @6: scope:[] from @begin
to:@6 to:@7
main: scope:[main] from @6 main: scope:[main] from @7
(byte*) print_str::str#1 ← (const byte[]) msg#0 (byte*) print_str::str#1 ← (const byte[]) msg#0
call print_str param-assignment call print_str param-assignment
to:main::@1 to:main::@1
@ -1376,12 +1422,12 @@ main::@6: scope:[main] from main::@5
main::@return: scope:[main] from main::@6 main::@return: scope:[main] from main::@6
return return
to:@return to:@return
@6: scope:[] from @5
call main param-assignment
to:@7
@7: scope:[] from @6 @7: scope:[] from @6
call main param-assignment
to:@8
@8: scope:[] from @7
to:@end to:@end
@end: scope:[] from @7 @end: scope:[] from @8
Constant (const byte*) print_str::str#1 = msg#0 Constant (const byte*) print_str::str#1 = msg#0
Constant (const byte*) print_str::str#2 = msg2#0 Constant (const byte*) print_str::str#2 = msg2#0
@ -1389,7 +1435,7 @@ Constant (const byte*) print_str::str#3 = msg3#0
Succesful SSA optimization Pass2ConstantIdentification Succesful SSA optimization Pass2ConstantIdentification
CONTROL FLOW GRAPH CONTROL FLOW GRAPH
@begin: scope:[] from @begin: scope:[] from
to:@5 to:@6
print_str: scope:[print_str] from main main::@2 main::@4 print_str: scope:[print_str] from main main::@2 main::@4
(byte*) char_cursor#29 ← phi( main/(const byte*) char_cursor#0 main::@2/(byte*) line_cursor#1 main::@4/(byte*) line_cursor#1 ) (byte*) char_cursor#29 ← phi( main/(const byte*) char_cursor#0 main::@2/(byte*) line_cursor#1 main::@4/(byte*) line_cursor#1 )
(byte*) print_str::str#6 ← phi( main/(const byte*) print_str::str#1 main::@2/(const byte*) print_str::str#2 main::@4/(const byte*) print_str::str#3 ) (byte*) print_str::str#6 ← phi( main/(const byte*) print_str::str#1 main::@2/(const byte*) print_str::str#2 main::@4/(const byte*) print_str::str#3 )
@ -1420,9 +1466,9 @@ print_ln::@2: scope:[print_ln] from print_ln::@1
print_ln::@return: scope:[print_ln] from print_ln::@2 print_ln::@return: scope:[print_ln] from print_ln::@2
return return
to:@return to:@return
@5: scope:[] from @begin @6: scope:[] from @begin
to:@6 to:@7
main: scope:[main] from @6 main: scope:[main] from @7
call print_str param-assignment call print_str param-assignment
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
@ -1445,21 +1491,21 @@ main::@6: scope:[main] from main::@5
main::@return: scope:[main] from main::@6 main::@return: scope:[main] from main::@6
return return
to:@return to:@return
@6: scope:[] from @5
call main param-assignment
to:@7
@7: scope:[] from @6 @7: scope:[] from @6
call main param-assignment
to:@8
@8: scope:[] from @7
to:@end to:@end
@end: scope:[] from @7 @end: scope:[] from @8
Culled Empty Block (label) print_ln::@2 Culled Empty Block (label) print_ln::@2
Culled Empty Block (label) @5 Culled Empty Block (label) @6
Culled Empty Block (label) main::@6 Culled Empty Block (label) main::@6
Culled Empty Block (label) @7 Culled Empty Block (label) @8
Succesful SSA optimization Pass2CullEmptyBlocks Succesful SSA optimization Pass2CullEmptyBlocks
CONTROL FLOW GRAPH CONTROL FLOW GRAPH
@begin: scope:[] from @begin: scope:[] from
to:@6 to:@7
print_str: scope:[print_str] from main main::@2 main::@4 print_str: scope:[print_str] from main main::@2 main::@4
(byte*) char_cursor#29 ← phi( main/(const byte*) char_cursor#0 main::@2/(byte*) line_cursor#1 main::@4/(byte*) line_cursor#1 ) (byte*) char_cursor#29 ← phi( main/(const byte*) char_cursor#0 main::@2/(byte*) line_cursor#1 main::@4/(byte*) line_cursor#1 )
(byte*) print_str::str#6 ← phi( main/(const byte*) print_str::str#1 main::@2/(const byte*) print_str::str#2 main::@4/(const byte*) print_str::str#3 ) (byte*) print_str::str#6 ← phi( main/(const byte*) print_str::str#1 main::@2/(const byte*) print_str::str#2 main::@4/(const byte*) print_str::str#3 )
@ -1488,7 +1534,7 @@ print_ln::@1: scope:[print_ln] from print_ln print_ln::@1
print_ln::@return: scope:[print_ln] from print_ln::@1 print_ln::@return: scope:[print_ln] from print_ln::@1
return return
to:@return to:@return
main: scope:[main] from @6 main: scope:[main] from @7
call print_str param-assignment call print_str param-assignment
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
@ -1509,10 +1555,10 @@ main::@5: scope:[main] from main::@4
main::@return: scope:[main] from main::@5 main::@return: scope:[main] from main::@5
return return
to:@return to:@return
@6: scope:[] from @begin @7: scope:[] from @begin
call main param-assignment call main param-assignment
to:@end to:@end
@end: scope:[] from @6 @end: scope:[] from @7
Inlining constant with var siblings (const byte*) print_str::str#1 Inlining constant with var siblings (const byte*) print_str::str#1
Inlining constant with var siblings (const byte*) print_str::str#1 Inlining constant with var siblings (const byte*) print_str::str#1
@ -1533,7 +1579,7 @@ Constant inlined print_str::str#1 = (const byte[]) msg#0
Succesful SSA optimization Pass2ConstantInlining Succesful SSA optimization Pass2ConstantInlining
CONTROL FLOW GRAPH CONTROL FLOW GRAPH
@begin: scope:[] from @begin: scope:[] from
to:@6 to:@7
print_str: scope:[print_str] from main main::@2 main::@4 print_str: scope:[print_str] from main main::@2 main::@4
(byte*) char_cursor#29 ← phi( main/((byte*))(word/signed word) 1024 main::@2/(byte*) line_cursor#1 main::@4/(byte*) line_cursor#1 ) (byte*) char_cursor#29 ← phi( main/((byte*))(word/signed word) 1024 main::@2/(byte*) line_cursor#1 main::@4/(byte*) line_cursor#1 )
(byte*) print_str::str#6 ← phi( main/(const byte[]) msg#0 main::@2/(const byte[]) msg2#0 main::@4/(const byte[]) msg3#0 ) (byte*) print_str::str#6 ← phi( main/(const byte[]) msg#0 main::@2/(const byte[]) msg2#0 main::@4/(const byte[]) msg3#0 )
@ -1562,7 +1608,7 @@ print_ln::@1: scope:[print_ln] from print_ln print_ln::@1
print_ln::@return: scope:[print_ln] from print_ln::@1 print_ln::@return: scope:[print_ln] from print_ln::@1
return return
to:@return to:@return
main: scope:[main] from @6 main: scope:[main] from @7
call print_str param-assignment call print_str param-assignment
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
@ -1583,13 +1629,13 @@ main::@5: scope:[main] from main::@4
main::@return: scope:[main] from main::@5 main::@return: scope:[main] from main::@5
return return
to:@return to:@return
@6: scope:[] from @begin @7: scope:[] from @begin
call main param-assignment call main param-assignment
to:@end to:@end
@end: scope:[] from @6 @end: scope:[] from @7
FINAL SYMBOL TABLE FINAL SYMBOL TABLE
(label) @6 (label) @7
(label) @begin (label) @begin
(label) @end (label) @end
(byte*) char_cursor (byte*) char_cursor
@ -1625,17 +1671,17 @@ FINAL SYMBOL TABLE
(byte*) print_str::str#4 (byte*) print_str::str#4
(byte*) print_str::str#6 (byte*) print_str::str#6
Block Sequence Planned @begin @6 @end main main::@1 main::@2 main::@3 main::@4 main::@5 main::@return print_ln print_ln::@1 print_ln::@return print_str print_str::@1 print_str::@return print_str::@2 Block Sequence Planned @begin @7 @end main main::@1 main::@2 main::@3 main::@4 main::@5 main::@return print_ln print_ln::@1 print_ln::@return print_str print_str::@1 print_str::@return print_str::@2
Added new block during phi lifting print_ln::@3(between print_ln::@1 and print_ln::@1) Added new block during phi lifting print_ln::@3(between print_ln::@1 and print_ln::@1)
Block Sequence Planned @begin @6 @end main main::@1 main::@2 main::@3 main::@4 main::@5 main::@return print_ln print_ln::@1 print_ln::@return print_ln::@3 print_str print_str::@1 print_str::@return print_str::@2 Block Sequence Planned @begin @7 @end main main::@1 main::@2 main::@3 main::@4 main::@5 main::@return print_ln print_ln::@1 print_ln::@return print_ln::@3 print_str print_str::@1 print_str::@return print_str::@2
CONTROL FLOW GRAPH - PHI LIFTED CONTROL FLOW GRAPH - PHI LIFTED
@begin: scope:[] from @begin: scope:[] from
to:@6 to:@7
@6: scope:[] from @begin @7: scope:[] from @begin
call main param-assignment call main param-assignment
to:@end to:@end
@end: scope:[] from @6 @end: scope:[] from @7
main: scope:[main] from @6 main: scope:[main] from @7
call print_str param-assignment call print_str param-assignment
to:main::@1 to:main::@1
main::@1: scope:[main] from main main::@1: scope:[main] from main
@ -1698,7 +1744,7 @@ print_str::@2: scope:[print_str] from print_str::@1
to:print_str::@1 to:print_str::@1
Adding NOP phi() at start of @begin Adding NOP phi() at start of @begin
Adding NOP phi() at start of @6 Adding NOP phi() at start of @7
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
Adding NOP phi() at start of main::@1 Adding NOP phi() at start of main::@1
@ -1717,14 +1763,14 @@ Propagating live ranges...
CONTROL FLOW GRAPH - LIVE RANGES FOUND CONTROL FLOW GRAPH - LIVE RANGES FOUND
@begin: scope:[] from @begin: scope:[] from
[0] phi() [ ] [0] phi() [ ]
to:@6 to:@7
@6: scope:[] from @begin @7: scope:[] from @begin
[1] phi() [ ] [1] phi() [ ]
[2] call main param-assignment [ ] [2] call main param-assignment [ ]
to:@end to:@end
@end: scope:[] from @6 @end: scope:[] from @7
[3] phi() [ ] [3] phi() [ ]
main: scope:[main] from @6 main: scope:[main] from @7
[4] phi() [ ] [4] phi() [ ]
[5] call print_str param-assignment [ char_cursor#13 ] [5] call print_str param-assignment [ char_cursor#13 ]
to:main::@1 to:main::@1
@ -1801,9 +1847,9 @@ Coalesced [33] print_str::str#8 ← print_str::str#0
Coalesced [34] char_cursor#34 ← char_cursor#1 Coalesced [34] char_cursor#34 ← char_cursor#1
Coalesced down to 3 phi equivalence classes Coalesced down to 3 phi equivalence classes
Culled Empty Block (label) print_ln::@3 Culled Empty Block (label) print_ln::@3
Block Sequence Planned @begin @6 @end main main::@1 main::@2 main::@3 main::@4 main::@5 main::@return print_ln print_ln::@1 print_ln::@return print_str print_str::@1 print_str::@return print_str::@2 Block Sequence Planned @begin @7 @end main main::@1 main::@2 main::@3 main::@4 main::@5 main::@return print_ln print_ln::@1 print_ln::@return print_str print_str::@1 print_str::@return print_str::@2
Adding NOP phi() at start of @begin Adding NOP phi() at start of @begin
Adding NOP phi() at start of @6 Adding NOP phi() at start of @7
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
Adding NOP phi() at start of main::@1 Adding NOP phi() at start of main::@1
@ -1819,14 +1865,14 @@ Propagating live ranges...
CONTROL FLOW GRAPH - BEFORE EFFECTIVE LIVE RANGES CONTROL FLOW GRAPH - BEFORE EFFECTIVE LIVE RANGES
@begin: scope:[] from @begin: scope:[] from
[0] phi() [ ] [0] phi() [ ]
to:@6 to:@7
@6: scope:[] from @begin @7: scope:[] from @begin
[1] phi() [ ] [1] phi() [ ]
[2] call main param-assignment [ ] [2] call main param-assignment [ ]
to:@end to:@end
@end: scope:[] from @6 @end: scope:[] from @7
[3] phi() [ ] [3] phi() [ ]
main: scope:[main] from @6 main: scope:[main] from @7
[4] phi() [ ] [4] phi() [ ]
[5] call print_str param-assignment [ char_cursor#13 ] [5] call print_str param-assignment [ char_cursor#13 ]
to:main::@1 to:main::@1
@ -1885,14 +1931,14 @@ print_str::@2: scope:[print_str] from print_str::@1
CONTROL FLOW GRAPH - PHI MEM COALESCED CONTROL FLOW GRAPH - PHI MEM COALESCED
@begin: scope:[] from @begin: scope:[] from
[0] phi() [ ] ( ) [0] phi() [ ] ( )
to:@6 to:@7
@6: scope:[] from @begin @7: scope:[] from @begin
[1] phi() [ ] ( ) [1] phi() [ ] ( )
[2] call main param-assignment [ ] ( ) [2] call main param-assignment [ ] ( )
to:@end to:@end
@end: scope:[] from @6 @end: scope:[] from @7
[3] phi() [ ] ( ) [3] phi() [ ] ( )
main: scope:[main] from @6 main: scope:[main] from @7
[4] phi() [ ] ( main:2 [ ] ) [4] phi() [ ] ( main:2 [ ] )
[5] call print_str param-assignment [ char_cursor#13 ] ( main:2 [ char_cursor#13 ] ) [5] call print_str param-assignment [ char_cursor#13 ] ( main:2 [ char_cursor#13 ] )
to:main::@1 to:main::@1
@ -1950,22 +1996,22 @@ print_str::@2: scope:[print_str] from print_str::@1
DOMINATORS DOMINATORS
@begin dominated by @begin @begin dominated by @begin
@6 dominated by @begin @6 @7 dominated by @begin @7
@end dominated by @begin @end @6 @end dominated by @begin @end @7
main dominated by @begin main @6 main dominated by @begin main @7
main::@1 dominated by @begin main @6 main::@1 main::@1 dominated by @begin main @7 main::@1
main::@2 dominated by @begin main @6 main::@1 main::@2 main::@2 dominated by @begin main @7 main::@1 main::@2
main::@3 dominated by @begin main @6 main::@1 main::@2 main::@3 main::@3 dominated by @begin main @7 main::@1 main::@2 main::@3
main::@4 dominated by @begin main @6 main::@1 main::@2 main::@3 main::@4 main::@4 dominated by @begin main @7 main::@1 main::@2 main::@3 main::@4
main::@5 dominated by @begin main @6 main::@1 main::@2 main::@5 main::@3 main::@4 main::@5 dominated by @begin main @7 main::@1 main::@2 main::@5 main::@3 main::@4
main::@return dominated by main::@return @begin main @6 main::@1 main::@2 main::@5 main::@3 main::@4 main::@return dominated by main::@return @begin main @7 main::@1 main::@2 main::@5 main::@3 main::@4
print_ln dominated by @begin main print_ln @6 main::@1 print_ln dominated by @begin main print_ln @7 main::@1
print_ln::@1 dominated by print_ln::@1 @begin main print_ln @6 main::@1 print_ln::@1 dominated by print_ln::@1 @begin main print_ln @7 main::@1
print_ln::@return dominated by print_ln::@1 @begin main print_ln print_ln::@return @6 main::@1 print_ln::@return dominated by print_ln::@1 @begin main print_ln print_ln::@return @7 main::@1
print_str dominated by @begin main @6 print_str print_str dominated by @begin main print_str @7
print_str::@1 dominated by @begin main print_str::@1 @6 print_str print_str::@1 dominated by @begin main print_str::@1 print_str @7
print_str::@return dominated by @begin print_str::@return main print_str::@1 @6 print_str print_str::@return dominated by @begin print_str::@return main print_str::@1 print_str @7
print_str::@2 dominated by @begin main print_str::@1 print_str::@2 @6 print_str print_str::@2 dominated by @begin main print_str::@1 print_str::@2 print_str @7
Found back edge: Loop head: print_ln::@1 tails: print_ln::@1 blocks: null Found back edge: Loop head: print_ln::@1 tails: print_ln::@1 blocks: null
Found back edge: Loop head: print_str::@1 tails: print_str::@2 blocks: null Found back edge: Loop head: print_str::@1 tails: print_str::@2 blocks: null
@ -2032,17 +2078,17 @@ INITIAL ASM
msg3: .text "hello 2017! @" msg3: .text "hello 2017! @"
//SEG2 @begin //SEG2 @begin
bbegin: bbegin:
//SEG3 [1] phi from @begin to @6 [phi:@begin->@6] //SEG3 [1] phi from @begin to @7 [phi:@begin->@7]
b6_from_bbegin: b7_from_bbegin:
jmp b6 jmp b7
//SEG4 @6 //SEG4 @7
b6: b7:
//SEG5 [2] call main param-assignment [ ] ( ) //SEG5 [2] call main param-assignment [ ] ( )
//SEG6 [4] phi from @6 to main [phi:@6->main] //SEG6 [4] phi from @7 to main [phi:@7->main]
main_from_b6: main_from_b7:
jsr main jsr main
//SEG7 [3] phi from @6 to @end [phi:@6->@end] //SEG7 [3] phi from @7 to @end [phi:@7->@end]
bend_from_b6: bend_from_b7:
jmp bend jmp bend
//SEG8 @end //SEG8 @end
bend: bend:
@ -2246,17 +2292,17 @@ ASSEMBLER BEFORE OPTIMIZATION
msg3: .text "hello 2017! @" msg3: .text "hello 2017! @"
//SEG2 @begin //SEG2 @begin
bbegin: bbegin:
//SEG3 [1] phi from @begin to @6 [phi:@begin->@6] //SEG3 [1] phi from @begin to @7 [phi:@begin->@7]
b6_from_bbegin: b7_from_bbegin:
jmp b6 jmp b7
//SEG4 @6 //SEG4 @7
b6: b7:
//SEG5 [2] call main param-assignment [ ] ( ) //SEG5 [2] call main param-assignment [ ] ( )
//SEG6 [4] phi from @6 to main [phi:@6->main] //SEG6 [4] phi from @7 to main [phi:@7->main]
main_from_b6: main_from_b7:
jsr main jsr main
//SEG7 [3] phi from @6 to @end [phi:@6->@end] //SEG7 [3] phi from @7 to @end [phi:@7->@end]
bend_from_b6: bend_from_b7:
jmp bend jmp bend
//SEG8 @end //SEG8 @end
bend: bend:
@ -2426,7 +2472,7 @@ print_str: {
} }
ASSEMBLER OPTIMIZATIONS ASSEMBLER OPTIMIZATIONS
Removing instruction jmp b6 Removing instruction jmp b7
Removing instruction jmp bend Removing instruction jmp bend
Removing instruction jmp b1 Removing instruction jmp b1
Removing instruction jmp b2 Removing instruction jmp b2
@ -2445,9 +2491,9 @@ Replacing label b1_from_b1 with b1
Replacing label b1_from_b1 with b1 Replacing label b1_from_b1 with b1
Replacing label b1_from_b2 with b1 Replacing label b1_from_b2 with b1
Removing instruction bbegin: Removing instruction bbegin:
Removing instruction b6_from_bbegin: Removing instruction b7_from_bbegin:
Removing instruction main_from_b6: Removing instruction main_from_b7:
Removing instruction bend_from_b6: Removing instruction bend_from_b7:
Removing instruction b1_from_main: Removing instruction b1_from_main:
Removing instruction print_ln_from_b1: Removing instruction print_ln_from_b1:
Removing instruction b3_from_b2: Removing instruction b3_from_b2:
@ -2459,7 +2505,7 @@ Removing instruction b1_from_b1:
Removing instruction b1_from_print_str: Removing instruction b1_from_print_str:
Removing instruction b1_from_b2: Removing instruction b1_from_b2:
Succesful ASM optimization Pass5RedundantLabelElimination Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction b6: Removing instruction b7:
Removing instruction bend: Removing instruction bend:
Removing instruction print_str_from_main: Removing instruction print_str_from_main:
Removing instruction b1: Removing instruction b1:
@ -2475,7 +2521,7 @@ Removing instruction breturn:
Succesful ASM optimization Pass5UnusedLabelElimination Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE FINAL SYMBOL TABLE
(label) @6 (label) @7
(label) @begin (label) @begin
(label) @end (label) @end
(byte*) char_cursor (byte*) char_cursor
@ -2529,12 +2575,12 @@ FINAL CODE
msg2: .text "hello c64! @" msg2: .text "hello c64! @"
msg3: .text "hello 2017! @" msg3: .text "hello 2017! @"
//SEG2 @begin //SEG2 @begin
//SEG3 [1] phi from @begin to @6 [phi:@begin->@6] //SEG3 [1] phi from @begin to @7 [phi:@begin->@7]
//SEG4 @6 //SEG4 @7
//SEG5 [2] call main param-assignment [ ] ( ) //SEG5 [2] call main param-assignment [ ] ( )
//SEG6 [4] phi from @6 to main [phi:@6->main] //SEG6 [4] phi from @7 to main [phi:@7->main]
jsr main jsr main
//SEG7 [3] phi from @6 to @end [phi:@6->@end] //SEG7 [3] phi from @7 to @end [phi:@7->@end]
//SEG8 @end //SEG8 @end
//SEG9 main //SEG9 main
main: { main: {

View File

@ -1,4 +1,4 @@
(label) @6 (label) @7
(label) @begin (label) @begin
(label) @end (label) @end
(byte*) char_cursor (byte*) char_cursor

View File

@ -1,13 +1,13 @@
@begin: scope:[] from @begin: scope:[] from
[0] phi() [ ] ( ) [0] phi() [ ] ( )
to:@33 to:@34
@33: scope:[] from @begin @34: scope:[] from @begin
[1] phi() [ ] ( ) [1] phi() [ ] ( )
[2] call main param-assignment [ ] ( ) [2] call main param-assignment [ ] ( )
to:@end to:@end
@end: scope:[] from @33 @end: scope:[] from @34
[3] phi() [ ] ( ) [3] phi() [ ] ( )
main: scope:[main] from @33 main: scope:[main] from @34
[4] phi() [ ] ( main:2 [ ] ) [4] phi() [ ] ( main:2 [ ] )
[5] call setFAC param-assignment [ ] ( main:2 [ ] ) [5] call setFAC param-assignment [ ] ( main:2 [ ] )
to:main::@3 to:main::@3

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
(label) @33 (label) @34
(label) @begin (label) @begin
(label) @end (label) @end
(void()) addMEMtoFAC((byte*) addMEMtoFAC::mem) (void()) addMEMtoFAC((byte*) addMEMtoFAC::mem)

View File

@ -1,13 +1,13 @@
@begin: scope:[] from @begin: scope:[] from
[0] phi() [ ] ( ) [0] phi() [ ] ( )
to:@42 to:@43
@42: scope:[] from @begin @43: scope:[] from @begin
[1] phi() [ ] ( ) [1] phi() [ ] ( )
[2] call main param-assignment [ ] ( ) [2] call main param-assignment [ ] ( )
to:@end to:@end
@end: scope:[] from @42 @end: scope:[] from @43
[3] phi() [ ] ( ) [3] phi() [ ] ( )
main: scope:[main] from @42 main: scope:[main] from @43
[4] phi() [ ] ( main:2 [ ] ) [4] phi() [ ] ( main:2 [ ] )
[5] call init param-assignment [ ] ( main:2 [ ] ) [5] call init param-assignment [ ] ( main:2 [ ] )
to:main::@2 to:main::@2

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
(label) @42 (label) @43
(label) @begin (label) @begin
(label) @end (label) @end
(byte*) BORDERCOL (byte*) BORDERCOL

View File

@ -0,0 +1,10 @@
void main() {
byte[] bs = { 'c', 'm' }; // constant byte array
byte b = 4; // constant byte
word w = { b, 0 }; // constant inline word
word w2 = { 1, 1 } + w; // constant inline word inside expression
byte* sc = w2; // implicit cast to (byte*)
*sc = bs[0];
}