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 Pass1EliminateUnusedVars(program).execute();
new Pass1ExtractInlineStrings(program).execute();
new Pass1FixWordConstructors(program).execute();
new Pass1EliminateEmptyBlocks(program).execute();
getLog().append("CONTROL FLOW GRAPH");
@ -181,6 +180,7 @@ public class Compiler {
optimizations.add(new Pass2ConditionalJumpSimplification(program));
optimizations.add(new Pass2ConstantIdentification(program));
optimizations.add(new Pass2ConstantAdditionElimination(program));
optimizations.add(new Pass2FixWordConstructors(program));
pass2OptimizeSSA(optimizations);
// 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 {
static boolean verboseFragmentLog = true;
static boolean verboseFragmentLog = false;
/**
* 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_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));
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));
// Convert array indexing with A register to X/Y register by prefixing tax/tay (..._derefidx_vbuaa... -> ..._derefidx_vbuxx... /... _derefidx_vbuyy... )
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));
// 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(.*)", ".*=.*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(.*)", ".*=.*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(.*)", ".*=.*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.*|.*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.*|.*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("(.*)=(.*)_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..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)=(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)=_(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.)_(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.)=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.)=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("(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
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
// Convert INC/DEC to +1/-1 ( ..._inc_xxx... -> ...xxx_plus_1_... / ..._dec_xxx... -> ...xxx_minus_1_... )
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));

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();
for (int i = 0; i < size; 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) {
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
continue;
}
execute(new VariableReplacer.ReplacableRValue1(assignment), blockScope, null);
execute(new VariableReplacer.ReplacableRValue2(assignment), blockScope, null);
execute(new ValueReplacer.ReplaceableRValue1(assignment), blockScope, null);
execute(new ValueReplacer.ReplaceableRValue2(assignment), blockScope, null);
} else if (statement instanceof StatementReturn) {
execute(new VariableReplacer.ReplacableReturn((StatementReturn) statement), blockScope, null);
execute(new ValueReplacer.ReplaceableReturn((StatementReturn) statement), blockScope, null);
}
}
}
return false;
}
private void execute(VariableReplacer.ReplacableValue replacable, Scope blockScope, String nameHint) {
RValue value = replacable.get();
private void execute(ValueReplacer.ReplaceableValue replaceable, Scope blockScope, String nameHint) {
RValue value = replaceable.get();
if(value instanceof ConstantString) {
ConstantVar strConst = createStringConstantVar(blockScope, (ConstantString) replacable.get(), nameHint);
replacable.set(strConst.getRef());
ConstantVar strConst = createStringConstantVar(blockScope, (ConstantString) replaceable.get(), nameHint);
replaceable.set(strConst.getRef());
}
for (VariableReplacer.ReplacableValue subValue : replacable.getSubValues()) {
for (ValueReplacer.ReplaceableValue subValue : replaceable.getSubValues()) {
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 blockNewPhis New phi functions introduced in the block to create versions of variables.
*/
private void execute(
VariableReplacer.ReplacableValue replacableValue,
ValueReplacer.ReplaceableValue replaceableValue,
Map<VariableUnversioned, VariableVersion> blockVersions,
Map<VariableUnversioned, VariableVersion> blockNewPhis) {
RValue value = replacableValue.get();
RValue value = replaceableValue.get();
VariableVersion version = findOrCreateVersion(value, blockVersions, blockNewPhis);
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);
}
}
@ -96,12 +96,12 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base {
Map<VariableUnversioned, VariableVersion> blockNewPhis = new LinkedHashMap<>();
for (Statement statement : block.getStatements()) {
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) {
StatementAssignment assignment = (StatementAssignment) statement;
execute(new VariableReplacer.ReplacableRValue1(assignment), blockVersions, blockNewPhis);
execute(new VariableReplacer.ReplacableRValue2(assignment), blockVersions, blockNewPhis);
execute(new VariableReplacer.ReplacableLValue(assignment), blockVersions, blockNewPhis);
execute(new ValueReplacer.ReplaceableRValue1(assignment), blockVersions, blockNewPhis);
execute(new ValueReplacer.ReplaceableRValue2(assignment), blockVersions, blockNewPhis);
execute(new ValueReplacer.ReplaceableLValue(assignment), blockVersions, blockNewPhis);
// Update map of versions encountered in the block
LValue lValue = assignment.getlValue();

View File

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

View File

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

View File

@ -52,11 +52,10 @@ public class Pass2ConstantInlining extends Pass2SsaOptimization {
* @param inline The replacements to make
*/
private void replaceInSymbolTable(Map<ConstantRef, ConstantValue> inline) {
VariableReplacer replacer = new VariableReplacer(inline);
Collection<ConstantVar> allConstants = getProgram().getScope().getAllConstants(true);
for (ConstantVar constantVar : allConstants) {
ConstantValue constantValue = constantVar.getValue();
RValue replacement = replacer.getReplacement(constantValue);
RValue replacement = AliasReplacer.getReplacement(constantValue, inline);
if(replacement!=null) {
constantVar.setValue((ConstantValue) replacement);
}
@ -68,13 +67,12 @@ public class Pass2ConstantInlining extends Pass2SsaOptimization {
* @param inline The replacements
*/
private void replaceInValues(Map<ConstantRef, ConstantValue> inline) {
VariableReplacer replacer = new VariableReplacer(inline);
boolean replaced = true;
while(replaced) {
replaced = false;
for (ConstantRef constantRef : inline.keySet()) {
ConstantValue constantValue = inline.get(constantRef);
ConstantValue replacement = (ConstantValue) replacer.getReplacement(constantValue);
ConstantValue replacement = (ConstantValue) AliasReplacer.getReplacement(constantValue, inline);
if (replacement != null) {
replaced = true;
inline.put(constantRef, replacement);
@ -112,7 +110,7 @@ public class Pass2ConstantInlining extends Pass2SsaOptimization {
ConstantValue constantValue = constant.getValue();
if(constantValue instanceof ConstantRef) {
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());
constant.setValue(programScope.getConstant((ConstantRef) constantValue).getValue());
} else {

View File

@ -3,17 +3,18 @@ package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.*;
/**
* The syntax for word constructors <code>word w = { b1, b2 };</code>
* is turned into a binary operator <code>word w = b1 _toword_ b2 ;</code>
* Identifies word constructors <code>{ b1, b2 }</code> and replaces
* 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);
}
@Override
boolean executeStep() {
public boolean optimize() {
boolean optimized = false;
ProgramScope programScope = getProgram().getScope();
for (ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) {
for (Statement statement : block.getStatements()) {
@ -33,6 +34,7 @@ public class Pass1FixWordConstructors extends Pass1Base {
assignment.setOperator(Operator.WORD);
assignment.setrValue2(list.getList().get(1));
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.
*/
public void replaceVariables(final Map<? extends SymbolRef, ? extends RValue> aliases) {
VariableReplacer replacer = new VariableReplacer(aliases);
replacer.execute(getGraph());
AliasReplacer replacer = new AliasReplacer(aliases);
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/");
}
public void testTrueInlineWords() throws IOException, URISyntaxException {
compileAndCompare("true-inline-words");
}
public void testIncrementInArray() throws IOException, URISyntaxException {
compileAndCompare("incrementinarray");
}

View File

@ -1,10 +1,10 @@
const byte* SCREEN = $400;
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 l: 4..7) {
word w = { his[h], l };
word w = { his[h], l }; // inline word
byte* sc = (byte*)w;
*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_ydxi::$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 @1
Removing empty block lines::@2
@ -1413,8 +1411,8 @@ line_ydxd::@return: scope:[line_ydxd] from line_ydxd::@2
return
to:@return
plot: scope:[plot] from
(word) plot::plotter_x ← *((byte[]) plot_xhi + (byte) plot::x) w= *((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_x ← { *((byte[]) plot_xhi + (byte) plot::x), *((byte[]) plot_xlo + (byte) plot::x) }
(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
(byte*) plot::plotter ← ((byte*)) (word~) plot::$0
(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
to:@return
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_y ← *((byte[]) plot_yhi + (byte) plot::y) w= *((byte[]) plot_ylo + (byte) plot::y)
(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), *((byte[]) plot_ylo + (byte) plot::y) }
(word~) plot::$0 ← (word) plot::plotter_x + (word) plot::plotter_y
(byte*) plot::plotter ← ((byte*)) (word~) plot::$0
(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
(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 ← *((byte[]) plot_xhi#0 + (byte) plot::x#4) w= *((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_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), *((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) | *((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
(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 ← *((byte[]) plot_xhi#0 + (byte) plot::x#4) w= *((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_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), *((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) | *((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
(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 ← *((byte[]) plot_xhi#0 + (byte) plot::x#4) w= *((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_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), *((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) | *((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
(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 ← *((byte[]) plot_xhi#0 + (byte) plot::x#4) w= *((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_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), *((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) | *((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
(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 ← *((byte[]) plot_xhi#0 + (byte) plot::x#4) w= *((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_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), *((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) | *((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
(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 ← *((byte[]) plot_xhi#0 + (byte) plot::x#4) w= *((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_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), *((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) | *((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
(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 ← *((byte[]) plot_xhi#0 + (byte) plot::x#4) w= *((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_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), *((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) | *((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
(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 ← *((byte[]) plot_xhi#0 + (byte) plot::x#4) w= *((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_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), *((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) | *((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
(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 ← *((byte[]) plot_xhi#0 + (byte) plot::x#4) w= *((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_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), *((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) | *((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
(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::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), *((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)
@ -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
(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::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), *((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)
@ -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
(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::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), *((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)
@ -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
(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::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), *((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)
@ -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
(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::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), *((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)
@ -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
(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::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), *((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)
@ -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::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
Not culling empty block because it shares successor with its predecessor. (label) init_plot_tables::@5
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 [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 [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: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 ]

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: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 ]
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
//SEG0 Basic Upstart
.pc = $801 "Basic"
@ -2399,7 +2368,6 @@ print_cls: {
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
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 [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
@ -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 [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 ]
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 [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 ] ]

View File

@ -1,10 +1,10 @@
const byte* SCREEN = $400;
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 l: 4..7) {
word w = { his[h], l };
word w = { his[h], l }; // inline word
byte* sc = (byte*)w;
*sc = '*';
}
@ -99,7 +99,6 @@ main::@return: scope:[main] from main::@4
to:@end
@end: scope:[] from @1
Fixing word constructor with main::w ← *(main::his + main::h) w= main::l
Removing empty block main::@4
CONTROL FLOW GRAPH
@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
to: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::sc ← (byte*~) main::$5
*((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
to: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::sc ← (byte*~) main::$5
*((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::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 )
(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::sc#0 ← (byte*~) main::$5
*((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::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 )
(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::sc#0 ← (byte*~) main::$5
*((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::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 )
(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::sc#0 ← (byte*~) main::$5
*((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::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 )
(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) '*'
(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::h#2 ← phi( main::@1/(byte) main::h#4 )
(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) '*'
(byte) main::l#1 ← ++ (byte) main::l#2
@ -479,7 +478,7 @@ main::@1: scope:[main] from main main::@3
to: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 )
(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) '*'
(byte) main::l#1 ← ++ (byte) main::l#2
@ -522,7 +521,7 @@ main::@1: scope:[main] from main main::@3
to: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 )
(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) '*'
(byte) main::l#1 ← ++ (byte) main::l#2
@ -561,7 +560,7 @@ main::@1: scope:[main] from main main::@3
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) 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) '*'
(byte) main::l#1 ← ++ (byte) main::l#2
@ -597,7 +596,7 @@ main::@1: scope:[main] from main main::@3
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) 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) '*'
(byte) main::l#1 ← ++ (byte) main::l#2
@ -630,7 +629,7 @@ main::@1: scope:[main] from main main::@3
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) 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) '*'
(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 }
Succesful SSA optimization Pass2ConstantIdentification
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
to:@1
main: scope:[main] from @1

View File

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

View File

@ -52,10 +52,19 @@ void print_char(byte 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*) print_str::str ← ++ (byte*) print_str::str
Adding pre/post-modifier (byte*) char_cursor ← ++ (byte*) char_cursor
Adding pre/post-modifier (byte*) print_cls::sc ← ++ (byte*) print_cls::sc
PROGRAM
(byte*) line_cursor ← (word/signed word) 1024
(byte*) char_cursor ← (byte*) line_cursor
@ -106,6 +115,17 @@ proc (void()) print_char((byte) print_char::ch)
print_char::@return:
return
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[]) msg2 ← (string) "hello c64! @"
(byte[]) msg3 ← (string) "hello 2017! @"
@ -146,6 +166,12 @@ SYMBOLS
(void()) print_char((byte) print_char::ch)
(label) print_char::@return
(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()
(byte*~) print_ln::$0
(boolean~) print_ln::$1
@ -167,6 +193,7 @@ SYMBOLS
(word) print_word::w
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
@begin: scope:[] from
(byte*) line_cursor ← ((byte*)) (word/signed word) 1024
@ -243,10 +270,27 @@ print_char::@return: scope:[print_char] from print_char
return
to:@return
@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[]) msg2 ← (string) "hello c64! @"
(byte[]) msg3 ← (string) "hello 2017! @"
to:@6
to:@7
main: scope:[main] from
(void~) main::$0 ← call print_str (byte[]) msg
(void~) main::$1 ← call print_ln
@ -258,12 +302,13 @@ main: scope:[main] from
main::@return: scope:[main] from main
return
to:@return
@6: scope:[] from @5
@7: scope:[] from @6
call main
to:@end
@end: scope:[] from @6
@end: scope:[] from @7
Removing unused procedure print_word
Removing unused procedure print_cls
Removing unused procedure print_byte
Removing unused procedure print_char
Eliminating unused variable - keeping the call (void~) main::$0
@ -280,11 +325,12 @@ Removing empty block @1
Removing empty block @2
Removing empty block @3
Removing empty block @4
Removing empty block @5
CONTROL FLOW GRAPH
@begin: scope:[] from
(byte*) line_cursor ← ((byte*)) (word/signed word) 1024
(byte*) char_cursor ← (byte*) line_cursor
to:@5
to:@6
print_str: scope:[print_str] from
to:print_str::@1
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
return
to:@return
@5: scope:[] from @begin
@6: scope:[] from @begin
(byte[]) msg ← (string) "hello world! @"
(byte[]) msg2 ← (string) "hello c64! @"
(byte[]) msg3 ← (string) "hello 2017! @"
to:@6
to:@7
main: scope:[main] from
call print_str (byte[]) msg
call print_ln
@ -329,10 +375,10 @@ main: scope:[main] from
main::@return: scope:[main] from main
return
to:@return
@6: scope:[] from @5
@7: scope:[] from @6
call main
to:@end
@end: scope:[] from @6
@end: scope:[] from @7
PROCEDURE MODIFY VARIABLE ANALYSIS
print_str modifies char_cursor
@ -345,7 +391,7 @@ CONTROL FLOW GRAPH WITH ASSIGNMENT CALL
@begin: scope:[] from
(byte*) line_cursor ← ((byte*)) (word/signed word) 1024
(byte*) char_cursor ← (byte*) line_cursor
to:@5
to:@6
print_str: scope:[print_str] from main main::@2 main::@4
to:print_str::@1
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
return
to:@return
@5: scope:[] from @begin
@6: scope:[] from @begin
(byte[]) msg ← (string) "hello world! @"
(byte[]) msg2 ← (string) "hello c64! @"
(byte[]) msg3 ← (string) "hello 2017! @"
to:@6
main: scope:[main] from @6
to:@7
main: scope:[main] from @7
(byte*) print_str::str ← (byte[]) msg
call print_str param-assignment
to:main::@1
@ -419,14 +465,14 @@ main::@return: scope:[main] from main::@6
(byte*) line_cursor ← (byte*) line_cursor
return
to:@return
@6: scope:[] from @5
call main param-assignment
to:@7
@7: scope:[] from @6
call main param-assignment
to:@8
@8: scope:[] from @7
(byte*) char_cursor ← (byte*) char_cursor
(byte*) line_cursor ← (byte*) line_cursor
to:@end
@end: scope:[] from @7
@end: scope:[] from @8
Completing Phi functions...
Completing Phi functions...
@ -438,7 +484,7 @@ CONTROL FLOW GRAPH SSA
@begin: scope:[] from
(byte*) line_cursor#0 ← ((byte*)) (word/signed word) 1024
(byte*) char_cursor#0 ← (byte*) line_cursor#0
to:@5
to:@6
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*) 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
return
to:@return
@5: scope:[] from @begin
@6: scope:[] from @begin
(byte*) line_cursor#22 ← phi( @begin/(byte*) line_cursor#0 )
(byte*) char_cursor#30 ← phi( @begin/(byte*) char_cursor#0 )
(byte[]) msg#0 ← (string) "hello world! @"
(byte[]) msg2#0 ← (string) "hello c64! @"
(byte[]) msg3#0 ← (string) "hello 2017! @"
to:@6
main: scope:[main] from @6
(byte[]) msg3#5 ← phi( @6/(byte[]) msg3#6 )
(byte[]) msg2#3 ← phi( @6/(byte[]) msg2#4 )
(byte*) line_cursor#21 ← phi( @6/(byte*) line_cursor#20 )
(byte*) char_cursor#27 ← phi( @6/(byte*) char_cursor#28 )
(byte[]) msg#1 ← phi( @6/(byte[]) msg#2 )
to:@7
main: scope:[main] from @7
(byte[]) msg3#5 ← phi( @7/(byte[]) msg3#6 )
(byte[]) msg2#3 ← phi( @7/(byte[]) msg2#4 )
(byte*) line_cursor#21 ← phi( @7/(byte*) line_cursor#20 )
(byte*) char_cursor#27 ← phi( @7/(byte*) char_cursor#28 )
(byte[]) msg#1 ← phi( @7/(byte[]) msg#2 )
(byte*) print_str::str#1 ← (byte[]) msg#1
call print_str param-assignment
to:main::@1
@ -553,27 +599,27 @@ main::@return: scope:[main] from main::@6
(byte*) line_cursor#6 ← (byte*) line_cursor#14
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
(byte*) line_cursor#15 ← phi( @6/(byte*) line_cursor#20 )
(byte*) char_cursor#24 ← phi( @6/(byte*) char_cursor#28 )
(byte[]) msg3#6 ← phi( @6/(byte[]) msg3#0 )
(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*) line_cursor#7 ← (byte*) line_cursor#15
to:@end
@end: scope:[] from @7
@end: scope:[] from @8
CONTROL FLOW GRAPH WITH ASSIGNMENT CALL & RETURN
@begin: scope:[] from
(byte*) line_cursor#0 ← ((byte*)) (word/signed word) 1024
(byte*) char_cursor#0 ← (byte*) line_cursor#0
to:@5
to:@6
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*) 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
return
to:@return
@5: scope:[] from @begin
@6: scope:[] from @begin
(byte*) line_cursor#22 ← phi( @begin/(byte*) line_cursor#0 )
(byte*) char_cursor#30 ← phi( @begin/(byte*) char_cursor#0 )
(byte[]) msg#0 ← (string) "hello world! @"
(byte[]) msg2#0 ← (string) "hello c64! @"
(byte[]) msg3#0 ← (string) "hello 2017! @"
to:@6
main: scope:[main] from @6
(byte[]) msg3#5 ← phi( @6/(byte[]) msg3#6 )
(byte[]) msg2#3 ← phi( @6/(byte[]) msg2#4 )
(byte*) line_cursor#21 ← phi( @6/(byte*) line_cursor#20 )
(byte*) char_cursor#27 ← phi( @6/(byte*) char_cursor#28 )
(byte[]) msg#1 ← phi( @6/(byte[]) msg#2 )
to:@7
main: scope:[main] from @7
(byte[]) msg3#5 ← phi( @7/(byte[]) msg3#6 )
(byte[]) msg2#3 ← phi( @7/(byte[]) msg2#4 )
(byte*) line_cursor#21 ← phi( @7/(byte*) line_cursor#20 )
(byte*) char_cursor#27 ← phi( @7/(byte*) char_cursor#28 )
(byte[]) msg#1 ← phi( @7/(byte[]) msg#2 )
(byte*) print_str::str#1 ← (byte[]) msg#1
call print_str param-assignment
to:main::@1
@ -688,26 +734,26 @@ main::@return: scope:[main] from main::@6
(byte*) line_cursor#6 ← (byte*) line_cursor#14
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
(byte*) line_cursor#15 ← phi( @6/(byte*) line_cursor#6 )
(byte*) char_cursor#24 ← phi( @6/(byte*) char_cursor#11 )
(byte[]) msg3#6 ← phi( @6/(byte[]) msg3#0 )
(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*) line_cursor#7 ← (byte*) line_cursor#15
to:@end
@end: scope:[] from @7
@end: scope:[] from @8
INITIAL SSA SYMBOL TABLE
(label) @5
(label) @6
(label) @7
(label) @8
(label) @begin
(label) @end
(byte*) char_cursor
@ -860,7 +906,7 @@ Succesful SSA optimization Pass2AliasElimination
CONTROL FLOW GRAPH
@begin: scope:[] from
(byte*) char_cursor#0 ← ((byte*)) (word/signed word) 1024
to:@5
to:@6
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*) 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
return
to:@return
@5: scope:[] from @begin
@6: scope:[] from @begin
(byte[]) msg#0 ← (string) "hello world! @"
(byte[]) msg2#0 ← (string) "hello c64! @"
(byte[]) msg3#0 ← (string) "hello 2017! @"
to:@6
main: scope:[main] from @6
(byte[]) msg3#1 ← phi( @6/(byte[]) msg3#0 )
(byte[]) msg2#1 ← phi( @6/(byte[]) msg2#0 )
(byte*) line_cursor#17 ← phi( @6/(byte*) char_cursor#0 )
(byte*) char_cursor#27 ← phi( @6/(byte*) char_cursor#0 )
(byte[]) msg#1 ← phi( @6/(byte[]) msg#0 )
to:@7
main: scope:[main] from @7
(byte[]) msg3#1 ← phi( @7/(byte[]) msg3#0 )
(byte[]) msg2#1 ← phi( @7/(byte[]) msg2#0 )
(byte*) line_cursor#17 ← phi( @7/(byte*) char_cursor#0 )
(byte*) char_cursor#27 ← phi( @7/(byte*) char_cursor#0 )
(byte[]) msg#1 ← phi( @7/(byte[]) msg#0 )
(byte*) print_str::str#1 ← (byte[]) msg#1
call print_str param-assignment
to:main::@1
@ -940,14 +986,14 @@ main::@6: scope:[main] from main::@5
main::@return: scope:[main] from main::@6
return
to:@return
@6: scope:[] from @5
call main param-assignment
to:@7
@7: scope:[] from @6
(byte*) line_cursor#15 ← phi( @6/(byte*) line_cursor#13 )
(byte*) char_cursor#12 ← phi( @6/(byte*) char_cursor#10 )
call main param-assignment
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
@end: scope:[] from @7
@end: scope:[] from @8
Not aliassing across scopes: print_str::str#6 print_str::str#1
Not aliassing across scopes: char_cursor#29 char_cursor#27
@ -977,7 +1023,7 @@ Succesful SSA optimization Pass2SelfPhiElimination
CONTROL FLOW GRAPH
@begin: scope:[] from
(byte*) char_cursor#0 ← ((byte*)) (word/signed word) 1024
to:@5
to:@6
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*) 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
return
to:@return
@5: scope:[] from @begin
@6: scope:[] from @begin
(byte[]) msg#0 ← (string) "hello world! @"
(byte[]) msg2#0 ← (string) "hello c64! @"
(byte[]) msg3#0 ← (string) "hello 2017! @"
to:@6
main: scope:[main] from @6
(byte[]) msg3#1 ← phi( @6/(byte[]) msg3#0 )
(byte[]) msg2#1 ← phi( @6/(byte[]) msg2#0 )
(byte*) line_cursor#17 ← phi( @6/(byte*) char_cursor#0 )
(byte*) char_cursor#27 ← phi( @6/(byte*) char_cursor#0 )
(byte[]) msg#1 ← phi( @6/(byte[]) msg#0 )
to:@7
main: scope:[main] from @7
(byte[]) msg3#1 ← phi( @7/(byte[]) msg3#0 )
(byte[]) msg2#1 ← phi( @7/(byte[]) msg2#0 )
(byte*) line_cursor#17 ← phi( @7/(byte*) char_cursor#0 )
(byte*) char_cursor#27 ← phi( @7/(byte*) char_cursor#0 )
(byte[]) msg#1 ← phi( @7/(byte[]) msg#0 )
(byte*) print_str::str#1 ← (byte[]) msg#1
call print_str param-assignment
to:main::@1
@ -1057,14 +1103,14 @@ main::@6: scope:[main] from main::@5
main::@return: scope:[main] from main::@6
return
to:@return
@6: scope:[] from @5
call main param-assignment
to:@7
@7: scope:[] from @6
(byte*) line_cursor#15 ← phi( @6/(byte*) line_cursor#13 )
(byte*) char_cursor#12 ← phi( @6/(byte*) char_cursor#10 )
call main param-assignment
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
@end: scope:[] from @7
@end: scope:[] from @8
Redundant Phi (byte*) char_cursor#15 (byte*) char_cursor#26
Redundant Phi (byte[]) msg#1 (byte[]) msg#0
@ -1087,7 +1133,7 @@ Succesful SSA optimization Pass2RedundantPhiElimination
CONTROL FLOW GRAPH
@begin: scope:[] from
(byte*) char_cursor#0 ← ((byte*)) (word/signed word) 1024
to:@5
to:@6
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*) 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
return
to:@return
@5: scope:[] from @begin
@6: scope:[] from @begin
(byte[]) msg#0 ← (string) "hello world! @"
(byte[]) msg2#0 ← (string) "hello c64! @"
(byte[]) msg3#0 ← (string) "hello 2017! @"
to:@6
main: scope:[main] from @6
to:@7
main: scope:[main] from @7
(byte*) print_str::str#1 ← (byte[]) msg#0
call print_str param-assignment
to:main::@1
@ -1152,19 +1198,19 @@ main::@6: scope:[main] from main::@5
main::@return: scope:[main] from main::@6
return
to:@return
@6: scope:[] from @5
call main param-assignment
to:@7
@7: scope:[] from @6
call main param-assignment
to:@8
@8: scope:[] from @7
to:@end
@end: scope:[] from @7
@end: scope:[] from @8
Redundant Phi (byte*) char_cursor#26 (byte*) char_cursor#13
Succesful SSA optimization Pass2RedundantPhiElimination
CONTROL FLOW GRAPH
@begin: scope:[] from
(byte*) char_cursor#0 ← ((byte*)) (word/signed word) 1024
to:@5
to:@6
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*) 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
return
to:@return
@5: scope:[] from @begin
@6: scope:[] from @begin
(byte[]) msg#0 ← (string) "hello world! @"
(byte[]) msg2#0 ← (string) "hello c64! @"
(byte[]) msg3#0 ← (string) "hello 2017! @"
to:@6
main: scope:[main] from @6
to:@7
main: scope:[main] from @7
(byte*) print_str::str#1 ← (byte[]) msg#0
call print_str param-assignment
to:main::@1
@ -1228,12 +1274,12 @@ main::@6: scope:[main] from main::@5
main::@return: scope:[main] from main::@6
return
to:@return
@6: scope:[] from @5
call main param-assignment
to:@7
@7: scope:[] from @6
call main param-assignment
to:@8
@8: scope:[] from @7
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_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
@begin: scope:[] from
(byte*) char_cursor#0 ← ((byte*)) (word/signed word) 1024
to:@5
to:@6
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*) 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
return
to:@return
@5: scope:[] from @begin
@6: scope:[] from @begin
(byte[]) msg#0 ← (string) "hello world! @"
(byte[]) msg2#0 ← (string) "hello c64! @"
(byte[]) msg3#0 ← (string) "hello 2017! @"
to:@6
main: scope:[main] from @6
to:@7
main: scope:[main] from @7
(byte*) print_str::str#1 ← (byte[]) msg#0
call print_str param-assignment
to:main::@1
@ -1303,12 +1349,12 @@ main::@6: scope:[main] from main::@5
main::@return: scope:[main] from main::@6
return
to:@return
@6: scope:[] from @5
call main param-assignment
to:@7
@7: scope:[] from @6
call main param-assignment
to:@8
@8: scope:[] from @7
to:@end
@end: scope:[] from @7
@end: scope:[] from @8
Constant (const byte*) char_cursor#0 = ((byte*))1024
Constant (const byte[]) msg#0 = "hello world! @"
@ -1317,7 +1363,7 @@ Constant (const byte[]) msg3#0 = "hello 2017! @"
Succesful SSA optimization Pass2ConstantIdentification
CONTROL FLOW GRAPH
@begin: scope:[] from
to:@5
to:@6
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*) 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
return
to:@return
@5: scope:[] from @begin
to:@6
main: scope:[main] from @6
@6: scope:[] from @begin
to:@7
main: scope:[main] from @7
(byte*) print_str::str#1 ← (const byte[]) msg#0
call print_str param-assignment
to:main::@1
@ -1376,12 +1422,12 @@ main::@6: scope:[main] from main::@5
main::@return: scope:[main] from main::@6
return
to:@return
@6: scope:[] from @5
call main param-assignment
to:@7
@7: scope:[] from @6
call main param-assignment
to:@8
@8: scope:[] from @7
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#2 = msg2#0
@ -1389,7 +1435,7 @@ Constant (const byte*) print_str::str#3 = msg3#0
Succesful SSA optimization Pass2ConstantIdentification
CONTROL FLOW GRAPH
@begin: scope:[] from
to:@5
to:@6
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*) 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
return
to:@return
@5: scope:[] from @begin
to:@6
main: scope:[main] from @6
@6: scope:[] from @begin
to:@7
main: scope:[main] from @7
call print_str param-assignment
to:main::@1
main::@1: scope:[main] from main
@ -1445,21 +1491,21 @@ main::@6: scope:[main] from main::@5
main::@return: scope:[main] from main::@6
return
to:@return
@6: scope:[] from @5
call main param-assignment
to:@7
@7: scope:[] from @6
call main param-assignment
to:@8
@8: scope:[] from @7
to:@end
@end: scope:[] from @7
@end: scope:[] from @8
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) @7
Culled Empty Block (label) @8
Succesful SSA optimization Pass2CullEmptyBlocks
CONTROL FLOW GRAPH
@begin: scope:[] from
to:@6
to:@7
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*) 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
return
to:@return
main: scope:[main] from @6
main: scope:[main] from @7
call print_str param-assignment
to:main::@1
main::@1: scope:[main] from main
@ -1509,10 +1555,10 @@ main::@5: scope:[main] from main::@4
main::@return: scope:[main] from main::@5
return
to:@return
@6: scope:[] from @begin
@7: scope:[] from @begin
call main param-assignment
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
@ -1533,7 +1579,7 @@ Constant inlined print_str::str#1 = (const byte[]) msg#0
Succesful SSA optimization Pass2ConstantInlining
CONTROL FLOW GRAPH
@begin: scope:[] from
to:@6
to:@7
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*) 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
return
to:@return
main: scope:[main] from @6
main: scope:[main] from @7
call print_str param-assignment
to:main::@1
main::@1: scope:[main] from main
@ -1583,13 +1629,13 @@ main::@5: scope:[main] from main::@4
main::@return: scope:[main] from main::@5
return
to:@return
@6: scope:[] from @begin
@7: scope:[] from @begin
call main param-assignment
to:@end
@end: scope:[] from @6
@end: scope:[] from @7
FINAL SYMBOL TABLE
(label) @6
(label) @7
(label) @begin
(label) @end
(byte*) char_cursor
@ -1625,17 +1671,17 @@ FINAL SYMBOL TABLE
(byte*) print_str::str#4
(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)
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
@begin: scope:[] from
to:@6
@6: scope:[] from @begin
to:@7
@7: scope:[] from @begin
call main param-assignment
to:@end
@end: scope:[] from @6
main: scope:[main] from @6
@end: scope:[] from @7
main: scope:[main] from @7
call print_str param-assignment
to:main::@1
main::@1: scope:[main] from main
@ -1698,7 +1744,7 @@ print_str::@2: scope:[print_str] from print_str::@1
to:print_str::@1
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 main
Adding NOP phi() at start of main::@1
@ -1717,14 +1763,14 @@ Propagating live ranges...
CONTROL FLOW GRAPH - LIVE RANGES FOUND
@begin: scope:[] from
[0] phi() [ ]
to:@6
@6: scope:[] from @begin
to:@7
@7: scope:[] from @begin
[1] phi() [ ]
[2] call main param-assignment [ ]
to:@end
@end: scope:[] from @6
@end: scope:[] from @7
[3] phi() [ ]
main: scope:[main] from @6
main: scope:[main] from @7
[4] phi() [ ]
[5] call print_str param-assignment [ char_cursor#13 ]
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 down to 3 phi equivalence classes
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 @6
Adding NOP phi() at start of @7
Adding NOP phi() at start of @end
Adding NOP phi() at start of main
Adding NOP phi() at start of main::@1
@ -1819,14 +1865,14 @@ Propagating live ranges...
CONTROL FLOW GRAPH - BEFORE EFFECTIVE LIVE RANGES
@begin: scope:[] from
[0] phi() [ ]
to:@6
@6: scope:[] from @begin
to:@7
@7: scope:[] from @begin
[1] phi() [ ]
[2] call main param-assignment [ ]
to:@end
@end: scope:[] from @6
@end: scope:[] from @7
[3] phi() [ ]
main: scope:[main] from @6
main: scope:[main] from @7
[4] phi() [ ]
[5] call print_str param-assignment [ char_cursor#13 ]
to:main::@1
@ -1885,14 +1931,14 @@ print_str::@2: scope:[print_str] from print_str::@1
CONTROL FLOW GRAPH - PHI MEM COALESCED
@begin: scope:[] from
[0] phi() [ ] ( )
to:@6
@6: scope:[] from @begin
to:@7
@7: scope:[] from @begin
[1] phi() [ ] ( )
[2] call main param-assignment [ ] ( )
to:@end
@end: scope:[] from @6
@end: scope:[] from @7
[3] phi() [ ] ( )
main: scope:[main] from @6
main: scope:[main] from @7
[4] phi() [ ] ( main:2 [ ] )
[5] call print_str param-assignment [ char_cursor#13 ] ( main:2 [ char_cursor#13 ] )
to:main::@1
@ -1950,22 +1996,22 @@ print_str::@2: scope:[print_str] from print_str::@1
DOMINATORS
@begin dominated by @begin
@6 dominated by @begin @6
@end dominated by @begin @end @6
main dominated by @begin main @6
main::@1 dominated by @begin main @6 main::@1
main::@2 dominated by @begin main @6 main::@1 main::@2
main::@3 dominated by @begin main @6 main::@1 main::@2 main::@3
main::@4 dominated by @begin main @6 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::@return dominated by main::@return @begin main @6 main::@1 main::@2 main::@5 main::@3 main::@4
print_ln dominated by @begin main print_ln @6 main::@1
print_ln::@1 dominated by print_ln::@1 @begin main print_ln @6 main::@1
print_ln::@return dominated by print_ln::@1 @begin main print_ln print_ln::@return @6 main::@1
print_str dominated by @begin main @6 print_str
print_str::@1 dominated by @begin main print_str::@1 @6 print_str
print_str::@return dominated by @begin print_str::@return main print_str::@1 @6 print_str
print_str::@2 dominated by @begin main print_str::@1 print_str::@2 @6 print_str
@7 dominated by @begin @7
@end dominated by @begin @end @7
main dominated by @begin main @7
main::@1 dominated by @begin main @7 main::@1
main::@2 dominated by @begin main @7 main::@1 main::@2
main::@3 dominated by @begin main @7 main::@1 main::@2 main::@3
main::@4 dominated by @begin main @7 main::@1 main::@2 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 @7 main::@1 main::@2 main::@5 main::@3 main::@4
print_ln dominated by @begin main print_ln @7 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 @7 main::@1
print_str dominated by @begin main print_str @7
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 print_str @7
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_str::@1 tails: print_str::@2 blocks: null
@ -2032,17 +2078,17 @@ INITIAL ASM
msg3: .text "hello 2017! @"
//SEG2 @begin
bbegin:
//SEG3 [1] phi from @begin to @6 [phi:@begin->@6]
b6_from_bbegin:
jmp b6
//SEG4 @6
b6:
//SEG3 [1] phi from @begin to @7 [phi:@begin->@7]
b7_from_bbegin:
jmp b7
//SEG4 @7
b7:
//SEG5 [2] call main param-assignment [ ] ( )
//SEG6 [4] phi from @6 to main [phi:@6->main]
main_from_b6:
//SEG6 [4] phi from @7 to main [phi:@7->main]
main_from_b7:
jsr main
//SEG7 [3] phi from @6 to @end [phi:@6->@end]
bend_from_b6:
//SEG7 [3] phi from @7 to @end [phi:@7->@end]
bend_from_b7:
jmp bend
//SEG8 @end
bend:
@ -2246,17 +2292,17 @@ ASSEMBLER BEFORE OPTIMIZATION
msg3: .text "hello 2017! @"
//SEG2 @begin
bbegin:
//SEG3 [1] phi from @begin to @6 [phi:@begin->@6]
b6_from_bbegin:
jmp b6
//SEG4 @6
b6:
//SEG3 [1] phi from @begin to @7 [phi:@begin->@7]
b7_from_bbegin:
jmp b7
//SEG4 @7
b7:
//SEG5 [2] call main param-assignment [ ] ( )
//SEG6 [4] phi from @6 to main [phi:@6->main]
main_from_b6:
//SEG6 [4] phi from @7 to main [phi:@7->main]
main_from_b7:
jsr main
//SEG7 [3] phi from @6 to @end [phi:@6->@end]
bend_from_b6:
//SEG7 [3] phi from @7 to @end [phi:@7->@end]
bend_from_b7:
jmp bend
//SEG8 @end
bend:
@ -2426,7 +2472,7 @@ print_str: {
}
ASSEMBLER OPTIMIZATIONS
Removing instruction jmp b6
Removing instruction jmp b7
Removing instruction jmp bend
Removing instruction jmp b1
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_b2 with b1
Removing instruction bbegin:
Removing instruction b6_from_bbegin:
Removing instruction main_from_b6:
Removing instruction bend_from_b6:
Removing instruction b7_from_bbegin:
Removing instruction main_from_b7:
Removing instruction bend_from_b7:
Removing instruction b1_from_main:
Removing instruction print_ln_from_b1:
Removing instruction b3_from_b2:
@ -2459,7 +2505,7 @@ Removing instruction b1_from_b1:
Removing instruction b1_from_print_str:
Removing instruction b1_from_b2:
Succesful ASM optimization Pass5RedundantLabelElimination
Removing instruction b6:
Removing instruction b7:
Removing instruction bend:
Removing instruction print_str_from_main:
Removing instruction b1:
@ -2475,7 +2521,7 @@ Removing instruction breturn:
Succesful ASM optimization Pass5UnusedLabelElimination
FINAL SYMBOL TABLE
(label) @6
(label) @7
(label) @begin
(label) @end
(byte*) char_cursor
@ -2529,12 +2575,12 @@ FINAL CODE
msg2: .text "hello c64! @"
msg3: .text "hello 2017! @"
//SEG2 @begin
//SEG3 [1] phi from @begin to @6 [phi:@begin->@6]
//SEG4 @6
//SEG3 [1] phi from @begin to @7 [phi:@begin->@7]
//SEG4 @7
//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
//SEG7 [3] phi from @6 to @end [phi:@6->@end]
//SEG7 [3] phi from @7 to @end [phi:@7->@end]
//SEG8 @end
//SEG9 main
main: {

View File

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

View File

@ -1,13 +1,13 @@
@begin: scope:[] from
[0] phi() [ ] ( )
to:@33
@33: scope:[] from @begin
to:@34
@34: scope:[] from @begin
[1] phi() [ ] ( )
[2] call main param-assignment [ ] ( )
to:@end
@end: scope:[] from @33
@end: scope:[] from @34
[3] phi() [ ] ( )
main: scope:[main] from @33
main: scope:[main] from @34
[4] phi() [ ] ( main:2 [ ] )
[5] call setFAC param-assignment [ ] ( main:2 [ ] )
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) @end
(void()) addMEMtoFAC((byte*) addMEMtoFAC::mem)

View File

@ -1,13 +1,13 @@
@begin: scope:[] from
[0] phi() [ ] ( )
to:@42
@42: scope:[] from @begin
to:@43
@43: scope:[] from @begin
[1] phi() [ ] ( )
[2] call main param-assignment [ ] ( )
to:@end
@end: scope:[] from @42
@end: scope:[] from @43
[3] phi() [ ] ( )
main: scope:[main] from @42
main: scope:[main] from @43
[4] phi() [ ] ( main:2 [ ] )
[5] call init param-assignment [ ] ( 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) @end
(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];
}