mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-11-23 08:32:39 +00:00
Moving __Stackcall stack operations back to pass 1/2 from pass 4 ASM code generation.
This commit is contained in:
parent
689aeb0ca6
commit
9e2e38e671
@ -1,7 +1,6 @@
|
||||
package dk.camelot64.kickc.model;
|
||||
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementInfos;
|
||||
import dk.camelot64.kickc.model.statements.StatementPhiBlock;
|
||||
import dk.camelot64.kickc.model.symbols.Label;
|
||||
import dk.camelot64.kickc.model.symbols.Procedure;
|
||||
|
@ -53,6 +53,8 @@ public class ControlFlowGraphBaseVisitor<T> {
|
||||
return visitAsm((StatementAsm) statement);
|
||||
} else if(statement instanceof StatementKickAsm) {
|
||||
return visitKickAsm((StatementKickAsm) statement);
|
||||
} else if(statement instanceof StatementStackPull) {
|
||||
return visitStackPull((StatementStackPull) statement);
|
||||
} else {
|
||||
throw new RuntimeException("Unhandled statement type " + statement);
|
||||
}
|
||||
@ -117,4 +119,8 @@ public class ControlFlowGraphBaseVisitor<T> {
|
||||
public T visitKickAsm(StatementKickAsm asm) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public T visitStackPull(StatementStackPull stackPull) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -221,4 +221,8 @@ public class ControlFlowGraphCopyVisitor extends ControlFlowGraphBaseVisitor<Obj
|
||||
return new StatementKickAsm(orig.getKickAsmCode(), orig.getLocation(), orig.getBytes(), orig.getCycles(), orig.getUses(), orig.getDeclaredClobber(), orig.getSource(), orig.getComments());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitStackPull(StatementStackPull orig) {
|
||||
return new StatementStackPull(orig.getPullBytes(), orig.getSource(), orig.getComments());
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import dk.camelot64.kickc.CompileLog;
|
||||
import dk.camelot64.kickc.asm.AsmProgram;
|
||||
import dk.camelot64.kickc.fragment.AsmFragmentTemplateSynthesizer;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementInfos;
|
||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||
import dk.camelot64.kickc.model.values.LabelRef;
|
||||
import dk.camelot64.kickc.passes.calcs.*;
|
||||
|
@ -1,9 +1,7 @@
|
||||
package dk.camelot64.kickc.model.statements;
|
||||
package dk.camelot64.kickc.model;
|
||||
|
||||
import dk.camelot64.kickc.model.ControlFlowBlock;
|
||||
import dk.camelot64.kickc.model.ControlFlowGraph;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.values.LabelRef;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
|
||||
import java.util.Map;
|
||||
|
@ -312,6 +312,28 @@ public interface ProgramValue {
|
||||
|
||||
}
|
||||
|
||||
/** Number of bytes constant used by stack pull . */
|
||||
class StackPullBytes implements ProgramValue {
|
||||
|
||||
private StatementStackPull statementStackPull;
|
||||
|
||||
StackPullBytes(StatementStackPull statementStackPull) {
|
||||
this.statementStackPull = statementStackPull;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value get() {
|
||||
return statementStackPull.getPullBytes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(Value value) {
|
||||
statementStackPull.setPullBytes((ConstantValue) value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class BlockLabel implements ProgramValue {
|
||||
|
||||
private final ControlFlowBlock block;
|
||||
@ -790,7 +812,7 @@ public interface ProgramValue {
|
||||
|
||||
@Override
|
||||
public void set(Value val) {
|
||||
stackIdxValue.setStackOffset((ConstantRef) val);
|
||||
stackIdxValue.setStackOffset((ConstantValue) val);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ public class ProgramValueIterator {
|
||||
* @param programValueHandler The programValueHandler to execute
|
||||
*/
|
||||
public static void execute(Variable variable, ProgramValueHandler programValueHandler) {
|
||||
if(variable.getInitValue()!=null) {
|
||||
if(variable.getInitValue() != null) {
|
||||
execute(new ProgramValue.ProgramValueInitValue(variable), programValueHandler, null, null, null);
|
||||
}
|
||||
if(variable.isArray()) {
|
||||
@ -145,15 +145,15 @@ public class ProgramValueIterator {
|
||||
} else if(statement instanceof StatementKickAsm) {
|
||||
StatementKickAsm statementKickAsm = (StatementKickAsm) statement;
|
||||
RValue location = statementKickAsm.getLocation();
|
||||
if(location!=null) {
|
||||
if(location != null) {
|
||||
execute(new ProgramValue.ProgramValueKickAsmLocation(statementKickAsm), handler, statement, statementsIt, block);
|
||||
}
|
||||
RValue bytes = statementKickAsm.getLocation();
|
||||
if(bytes!=null) {
|
||||
if(bytes != null) {
|
||||
execute(new ProgramValue.ProgramValueKickAsmBytes(statementKickAsm), handler, statement, statementsIt, block);
|
||||
}
|
||||
RValue cycles = statementKickAsm.getLocation();
|
||||
if(cycles!=null) {
|
||||
if(cycles != null) {
|
||||
execute(new ProgramValue.ProgramValueKickAsmCycles(statementKickAsm), handler, statement, statementsIt, block);
|
||||
}
|
||||
List<SymbolRef> uses = statementKickAsm.getUses();
|
||||
@ -166,6 +166,9 @@ public class ProgramValueIterator {
|
||||
for(String label : referenced.keySet()) {
|
||||
execute(new ProgramValue.ProgramValueAsmReferenced(statementAsm, label), handler, statement, statementsIt, block);
|
||||
}
|
||||
} else if(statement instanceof StatementStackPull) {
|
||||
StatementStackPull statementStackPull = (StatementStackPull) statement;
|
||||
execute(new ProgramValue.StackPullBytes(statementStackPull), handler, statement, statementsIt, block);
|
||||
}
|
||||
}
|
||||
|
||||
@ -245,13 +248,13 @@ public class ProgramValueIterator {
|
||||
subValues.add(new ProgramValue.ProgramValueLValueIntermediateVariable((LvalueIntermediate) value));
|
||||
} else if(value instanceof ParamValue) {
|
||||
subValues.add(new ProgramValue.ProgramValueParamValue((ParamValue) value));
|
||||
} else if(value instanceof StackIdxValue) {
|
||||
subValues.add(new ProgramValue.ProgramValueStackIdxValue((StackIdxValue) value));
|
||||
} else if(value instanceof MemsetValue) {
|
||||
subValues.add(new ProgramValue.ProgramValueMemsetValue((MemsetValue) value));
|
||||
} else if(value instanceof MemcpyValue) {
|
||||
subValues.add(new ProgramValue.ProgramValueMempySize((MemcpyValue) value));
|
||||
subValues.add(new ProgramValue.ProgramValueMempySource((MemcpyValue) value));
|
||||
} else if(value instanceof StackIdxValue) {
|
||||
subValues.add(new ProgramValue.ProgramValueStackIdxValue((StackIdxValue) value));
|
||||
} else if(value == null ||
|
||||
value instanceof SymbolVariableRef ||
|
||||
value instanceof Variable ||
|
||||
@ -259,8 +262,9 @@ public class ProgramValueIterator {
|
||||
value instanceof ConstantLiteral ||
|
||||
value instanceof StructZero ||
|
||||
value instanceof Label ||
|
||||
value instanceof LabelRef
|
||||
) {
|
||||
value instanceof LabelRef ||
|
||||
value instanceof StackPullValue
|
||||
) {
|
||||
// No sub values
|
||||
} else {
|
||||
throw new RuntimeException("Unhandled value type " + value.getClass());
|
||||
|
@ -26,7 +26,7 @@ public class StatementAsm extends StatementBase {
|
||||
private AsmClobber declaredClobber;
|
||||
|
||||
public StatementAsm(String asmBody, Map<String, SymbolRef> referenced, AsmClobber declaredClobber, StatementSource source, List<Comment> comments) {
|
||||
super(null, source, comments);
|
||||
super(source, comments);
|
||||
this.asmBody = asmBody;
|
||||
this.referenced = referenced;
|
||||
this.declaredClobber = declaredClobber;
|
||||
|
@ -7,6 +7,7 @@ import dk.camelot64.kickc.model.values.LValue;
|
||||
import dk.camelot64.kickc.model.values.RValue;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Single Static Assignment Form Statement.
|
||||
@ -28,27 +29,15 @@ public class StatementAssignment extends StatementBase implements StatementLValu
|
||||
private boolean initialAssignment;
|
||||
|
||||
public StatementAssignment(LValue lValue, RValue rValue2, boolean initialAssignment, StatementSource source, List<Comment> comments) {
|
||||
this(lValue, null, null, rValue2, initialAssignment, null, source, comments);
|
||||
this(lValue, null, null, rValue2, initialAssignment, source, comments);
|
||||
}
|
||||
|
||||
public StatementAssignment(LValue lValue, Operator operator, RValue rValue2, boolean initialAssignment, StatementSource source, List<Comment> comments) {
|
||||
this(lValue, null, operator, rValue2, initialAssignment, null, source, comments);
|
||||
this(lValue, null, operator, rValue2, initialAssignment, source, comments);
|
||||
}
|
||||
|
||||
public StatementAssignment(LValue lValue, RValue rValue1, Operator operator, RValue rValue2, boolean initialAssignment, StatementSource source, List<Comment> comments) {
|
||||
this(lValue, rValue1, operator, rValue2, initialAssignment, null, source, comments);
|
||||
}
|
||||
|
||||
public StatementAssignment(
|
||||
LValue lValue,
|
||||
RValue rValue1,
|
||||
Operator operator,
|
||||
RValue rValue2,
|
||||
boolean initialAssignment,
|
||||
Integer index,
|
||||
StatementSource source,
|
||||
List<Comment> comments) {
|
||||
super(index, source, comments);
|
||||
super(source, comments);
|
||||
this.lValue = lValue;
|
||||
this.rValue1 = rValue1;
|
||||
this.operator = operator;
|
||||
@ -56,7 +45,6 @@ public class StatementAssignment extends StatementBase implements StatementLValu
|
||||
this.initialAssignment = initialAssignment;
|
||||
}
|
||||
|
||||
|
||||
public LValue getlValue() {
|
||||
return lValue;
|
||||
}
|
||||
@ -114,22 +102,16 @@ public class StatementAssignment extends StatementBase implements StatementLValu
|
||||
if(this == o) return true;
|
||||
if(o == null || getClass() != o.getClass()) return false;
|
||||
if(!super.equals(o)) return false;
|
||||
|
||||
StatementAssignment that = (StatementAssignment) o;
|
||||
|
||||
if(!lValue.equals(that.lValue)) return false;
|
||||
if(rValue1 != null ? !rValue1.equals(that.rValue1) : that.rValue1 != null) return false;
|
||||
if(operator != null ? !operator.equals(that.operator) : that.operator != null) return false;
|
||||
return rValue2 != null ? rValue2.equals(that.rValue2) : that.rValue2 == null;
|
||||
return initialAssignment == that.initialAssignment &&
|
||||
Objects.equals(lValue, that.lValue) &&
|
||||
Objects.equals(rValue1, that.rValue1) &&
|
||||
Objects.equals(operator, that.operator) &&
|
||||
Objects.equals(rValue2, that.rValue2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = super.hashCode();
|
||||
result = 31 * result + lValue.hashCode();
|
||||
result = 31 * result + (rValue1 != null ? rValue1.hashCode() : 0);
|
||||
result = 31 * result + (operator != null ? operator.hashCode() : 0);
|
||||
result = 31 * result + (rValue2 != null ? rValue2.hashCode() : 0);
|
||||
return result;
|
||||
return Objects.hash(super.hashCode(), lValue, rValue1, operator, rValue2, initialAssignment);
|
||||
}
|
||||
}
|
||||
|
@ -16,8 +16,8 @@ public abstract class StatementBase implements Statement {
|
||||
/** Comments preceding the statement in the source code. */
|
||||
private List<Comment> comments;
|
||||
|
||||
public StatementBase(Integer index, StatementSource source, List<Comment> comments) {
|
||||
this.index = index;
|
||||
public StatementBase(StatementSource source, List<Comment> comments) {
|
||||
this.index = null;
|
||||
this.source = source;
|
||||
this.comments = comments;
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ public class StatementCall extends StatementBase implements StatementLValue, Sta
|
||||
private boolean initialAssignment;
|
||||
|
||||
public StatementCall(LValue lValue, String procedureName, List<RValue> parameters, StatementSource source, List<Comment> comments) {
|
||||
super(null, source, comments);
|
||||
super(source, comments);
|
||||
this.lValue = lValue;
|
||||
this.procedureName = procedureName;
|
||||
this.parameters = parameters;
|
||||
|
@ -20,7 +20,7 @@ public class StatementCallExecute extends StatementBase implements StatementCall
|
||||
private ProcedureRef procedure;
|
||||
|
||||
public StatementCallExecute(ProcedureRef procedure, StatementSource source, List<Comment> comments) {
|
||||
super(null, source, comments);
|
||||
super(source, comments);
|
||||
this.procedure = procedure;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ public class StatementCallFinalize extends StatementBase implements StatementLVa
|
||||
private boolean initialAssignment;
|
||||
|
||||
public StatementCallFinalize(LValue lValue, ProcedureRef procedure, StatementSource source, List<Comment> comments) {
|
||||
super(null, source, comments);
|
||||
super(source, comments);
|
||||
this.lValue = lValue;
|
||||
this.procedure = procedure;
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ package dk.camelot64.kickc.model.statements;
|
||||
import dk.camelot64.kickc.model.Comment;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.values.LValue;
|
||||
import dk.camelot64.kickc.model.values.ProcedureRef;
|
||||
import dk.camelot64.kickc.model.values.RValue;
|
||||
|
||||
import java.util.List;
|
||||
@ -24,7 +23,7 @@ public class StatementCallPointer extends StatementBase implements StatementLVal
|
||||
private boolean initialAssignment;
|
||||
|
||||
public StatementCallPointer(LValue lValue, RValue procedure, List<RValue> parameters, StatementSource source, List<Comment> comments) {
|
||||
super(null, source, comments);
|
||||
super(source, comments);
|
||||
this.lValue = lValue;
|
||||
this.procedure = procedure;
|
||||
this.parameters = parameters;
|
||||
|
@ -23,7 +23,7 @@ public class StatementCallPrepare extends StatementBase {
|
||||
private List<RValue> parameters;
|
||||
|
||||
public StatementCallPrepare(ProcedureRef procedure, List<RValue> parameters, StatementSource source, List<Comment> comments) {
|
||||
super(null, source, comments);
|
||||
super(source, comments);
|
||||
this.procedure = procedure;
|
||||
this.parameters = parameters;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ public class StatementConditionalJump extends StatementBase {
|
||||
private boolean wasUnrolled;
|
||||
|
||||
public StatementConditionalJump(RValue condition, LabelRef destination,StatementSource source, List<Comment> comments) {
|
||||
super(null, source, comments);
|
||||
super(source, comments);
|
||||
this.rValue1 = null;
|
||||
this.operator = null;
|
||||
this.rValue2 = condition;
|
||||
@ -41,7 +41,7 @@ public class StatementConditionalJump extends StatementBase {
|
||||
LabelRef destination,
|
||||
StatementSource source,
|
||||
List<Comment> comments) {
|
||||
super(null, source, comments);
|
||||
super(source, comments);
|
||||
this.rValue1 = rValue1;
|
||||
this.operator = operator;
|
||||
this.rValue2 = rValue2;
|
||||
|
@ -17,7 +17,7 @@ public class StatementJump extends StatementBase {
|
||||
private LabelRef destination;
|
||||
|
||||
public StatementJump(LabelRef destination, StatementSource source, List<Comment> comments) {
|
||||
super(null, source, comments);
|
||||
super(source, comments);
|
||||
this.destination = destination;
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,6 @@ import dk.camelot64.kickc.model.Comment;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.values.RValue;
|
||||
import dk.camelot64.kickc.model.values.SymbolRef;
|
||||
import dk.camelot64.kickc.model.values.SymbolVariableRef;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -32,13 +31,13 @@ public class StatementKickAsm extends StatementBase {
|
||||
private AsmClobber declaredClobber;
|
||||
|
||||
public StatementKickAsm(String kickAsmCode, StatementSource source, List<Comment> comments) {
|
||||
super(null, source, comments);
|
||||
super(source, comments);
|
||||
this.kickAsmCode = kickAsmCode;
|
||||
this.uses = new ArrayList<>();
|
||||
}
|
||||
|
||||
public StatementKickAsm(String kickAsmCode, RValue location, RValue bytes, RValue cycles, List<SymbolRef> uses, AsmClobber declaredClobber, StatementSource source, List<Comment> comments) {
|
||||
super(null, source, comments);
|
||||
super(source, comments);
|
||||
this.kickAsmCode = kickAsmCode;
|
||||
this.location = location;
|
||||
this.bytes = bytes;
|
||||
|
@ -4,7 +4,6 @@ import dk.camelot64.kickc.model.Comment;
|
||||
import dk.camelot64.kickc.model.values.LabelRef;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -15,7 +14,7 @@ public class StatementLabel extends StatementBase {
|
||||
private LabelRef label;
|
||||
|
||||
public StatementLabel(LabelRef label, StatementSource source, List<Comment> comments) {
|
||||
super(null, source, comments);
|
||||
super(source, comments);
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ public class StatementPhiBlock extends StatementBase {
|
||||
private List<PhiVariable> phiVariables;
|
||||
|
||||
public StatementPhiBlock(List<Comment> comments) {
|
||||
super(null, new StatementSource(RuleContext.EMPTY), comments);
|
||||
super(new StatementSource(RuleContext.EMPTY), comments);
|
||||
this.phiVariables = new ArrayList<>();
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,6 @@ import dk.camelot64.kickc.model.Comment;
|
||||
import dk.camelot64.kickc.model.values.ProcedureRef;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/** Procedure declaration in SSA */
|
||||
@ -15,7 +14,7 @@ public class StatementProcedureBegin extends StatementBase {
|
||||
private Strategy strategy;
|
||||
|
||||
public StatementProcedureBegin(ProcedureRef procedure,StatementSource source, List<Comment> comments) {
|
||||
super(null, source, comments);
|
||||
super(source, comments);
|
||||
this.procedure = procedure;
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@ public class StatementProcedureEnd extends StatementBase {
|
||||
private ProcedureRef procedure;
|
||||
|
||||
public StatementProcedureEnd(ProcedureRef procedure, StatementSource source, List<Comment> comments) {
|
||||
super(null, source, comments);
|
||||
super(source, comments);
|
||||
this.procedure = procedure;
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ public class StatementReturn extends StatementBase {
|
||||
private RValue value;
|
||||
|
||||
public StatementReturn(RValue value, StatementSource source, List<Comment> comments) {
|
||||
super(null, source, comments);
|
||||
super(source, comments);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,31 @@
|
||||
package dk.camelot64.kickc.model.statements;
|
||||
|
||||
import dk.camelot64.kickc.model.Comment;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.values.ConstantValue;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/** Pulls some bytes of the stack. */
|
||||
public class StatementStackPull extends StatementBase {
|
||||
|
||||
private ConstantValue pullBytes;
|
||||
|
||||
public StatementStackPull(ConstantValue pullBytes, StatementSource source, List<Comment> comments) {
|
||||
super(source, comments);
|
||||
this.pullBytes = pullBytes;
|
||||
}
|
||||
|
||||
public ConstantValue getPullBytes() {
|
||||
return pullBytes;
|
||||
}
|
||||
|
||||
public void setPullBytes(ConstantValue pullBytes) {
|
||||
this.pullBytes = pullBytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(Program program, boolean aliveInfo) {
|
||||
return "stackpull("+pullBytes.toString(program)+")";
|
||||
}
|
||||
}
|
@ -10,7 +10,8 @@ import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeInference;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeStruct;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
import dk.camelot64.kickc.passes.unwinding.*;
|
||||
import dk.camelot64.kickc.passes.unwinding.ValueSource;
|
||||
import dk.camelot64.kickc.passes.unwinding.ValueSourceFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -90,16 +91,10 @@ public class Pass1UnwindStructValues extends Pass1Base {
|
||||
private boolean unwindCall(StatementCall call, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock) {
|
||||
// Unwind struct value return value
|
||||
boolean lvalUnwound = false;
|
||||
|
||||
final ValueSource lValueSource = ValueSourceFactory.getValueSource(call.getlValue(), getProgram(), getScope(), call, stmtIt, currentBlock);
|
||||
if(lValueSource != null && lValueSource.isUnwindable()) {
|
||||
ArrayList<RValue> unwoundMembers = new ArrayList<>();
|
||||
for(String memberName : lValueSource.getMemberNames(getScope())) {
|
||||
ValueSource memberUnwinding = lValueSource.getMemberUnwinding(memberName, getProgram(), getScope(), call, stmtIt, currentBlock);
|
||||
unwoundMembers.add(memberUnwinding.getSimpleValue(getScope()));
|
||||
}
|
||||
ValueList unwoundLValue = new ValueList(unwoundMembers);
|
||||
call.setlValue(unwoundLValue);
|
||||
final ValueSource valueSource = ValueSourceFactory.getValueSource(call.getlValue(), getProgram(), getScope(), call, stmtIt, currentBlock);
|
||||
RValue unwoundLValue = unwindValue(valueSource, call, stmtIt, currentBlock);
|
||||
if(unwoundLValue != null && !call.getlValue().equals(unwoundLValue)) {
|
||||
call.setlValue((LValue) unwoundLValue);
|
||||
getLog().append("Converted procedure call LValue to member unwinding " + call.toString(getProgram(), false));
|
||||
lvalUnwound = true;
|
||||
}
|
||||
@ -132,6 +127,31 @@ public class Pass1UnwindStructValues extends Pass1Base {
|
||||
return (anyParameterUnwound || lvalUnwound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unwind an LVa.lue to a ValueList if it is unwindable.
|
||||
* @param value The value to unwind
|
||||
* @param statement The current statement
|
||||
* @param stmtIt Statement iterator
|
||||
* @param currentBlock current block
|
||||
* @return The unwound ValueList. null if the value is not unwindable.
|
||||
*/
|
||||
private RValue unwindValue(ValueSource lValueSource, Statement statement, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock) {
|
||||
if(lValueSource==null) {
|
||||
return null;
|
||||
} else if(lValueSource.isSimple()) {
|
||||
return lValueSource.getSimpleValue(getScope());
|
||||
} else if(lValueSource.isUnwindable()) {
|
||||
ArrayList<RValue> unwoundMembers = new ArrayList<>();
|
||||
for(String memberName : lValueSource.getMemberNames(getScope())) {
|
||||
ValueSource memberUnwinding = lValueSource.getMemberUnwinding(memberName, getProgram(), getScope(), statement, stmtIt, currentBlock);
|
||||
unwoundMembers.add(unwindValue(memberUnwinding, statement, stmtIt, currentBlock));
|
||||
}
|
||||
return new ValueList(unwoundMembers);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unwind any return value that is a struct value into the member values
|
||||
*
|
||||
@ -139,22 +159,15 @@ public class Pass1UnwindStructValues extends Pass1Base {
|
||||
*/
|
||||
|
||||
private boolean unwindReturn(StatementReturn statementReturn, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock) {
|
||||
boolean modified = false;
|
||||
// Unwind struct value return value
|
||||
final ValueSource returnVarUnwinding = ValueSourceFactory.getValueSource(statementReturn.getValue(), getProgram(), getScope(), statementReturn, stmtIt, currentBlock);
|
||||
if(returnVarUnwinding != null && returnVarUnwinding.isUnwindable()) {
|
||||
ArrayList<RValue> unwoundMembers = new ArrayList<>();
|
||||
for(String memberName : returnVarUnwinding.getMemberNames(getScope())) {
|
||||
final ValueSource memberUnwinding = returnVarUnwinding.getMemberUnwinding(memberName, getProgram(), getScope(), statementReturn, stmtIt, currentBlock);
|
||||
unwoundMembers.add(memberUnwinding.getSimpleValue(getScope()));
|
||||
}
|
||||
ValueList unwoundReturnValue = new ValueList(unwoundMembers);
|
||||
statementReturn.setValue(unwoundReturnValue);
|
||||
boolean unwound = false;
|
||||
final ValueSource valueSource = ValueSourceFactory.getValueSource(statementReturn.getValue(), getProgram(), getScope(), statementReturn, stmtIt, currentBlock);
|
||||
RValue unwoundValue = unwindValue(valueSource, statementReturn, stmtIt, currentBlock);
|
||||
if(unwoundValue != null && !statementReturn.getValue().equals(unwoundValue)) {
|
||||
statementReturn.setValue(unwoundValue);
|
||||
getLog().append("Converted procedure struct return value to member unwinding " + statementReturn.toString(getProgram(), false));
|
||||
modified = true;
|
||||
|
||||
unwound = true;
|
||||
}
|
||||
return modified;
|
||||
return unwound;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -10,7 +10,7 @@ import dk.camelot64.kickc.model.operators.Operator;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementAssignment;
|
||||
import dk.camelot64.kickc.model.statements.StatementConditionalJump;
|
||||
import dk.camelot64.kickc.model.statements.StatementInfos;
|
||||
import dk.camelot64.kickc.model.StatementInfos;
|
||||
import dk.camelot64.kickc.model.symbols.Scope;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.values.RValue;
|
||||
|
@ -889,94 +889,16 @@ public class Pass4CodeGeneration {
|
||||
asm.getCurrentChunk().setFragment("jsr");
|
||||
asm.addInstruction("jsr", AsmAddressingMode.ABS, call.getProcedure().getFullName(), false);
|
||||
}
|
||||
} else if(statement instanceof StatementCallFinalize) {
|
||||
StatementCallFinalize call = (StatementCallFinalize) statement;
|
||||
Procedure procedure = getScope().getProcedure(call.getProcedure());
|
||||
if(Procedure.CallingConvention.STACK_CALL.equals(procedure.getCallingConvention())) {
|
||||
long stackFrameByteSize = CallingConventionStack.getStackFrameByteSize(procedure);
|
||||
long returnByteSize = procedure.getReturnType() == null ? 0 : procedure.getReturnType().getSizeBytes();
|
||||
long stackCleanBytes = (call.getlValue() == null) ? stackFrameByteSize : (stackFrameByteSize - returnByteSize);
|
||||
if(stackCleanBytes > 0) {
|
||||
// Clean up the stack
|
||||
String pullSignature = "_stackpullbyte_" + stackCleanBytes;
|
||||
AsmFragmentInstanceSpec pullFragmentInstanceSpec = new AsmFragmentInstanceSpec(program, pullSignature, new LinkedHashMap<>(), block.getScope());
|
||||
generateAsm(asm, pullFragmentInstanceSpec);
|
||||
}
|
||||
// Pull result from the stack
|
||||
if(call.getlValue() != null) {
|
||||
if(stackCleanBytes > 0)
|
||||
asm.startChunk(block.getScope(), statement.getIndex(), statement.toString(program, verboseAliveInfo));
|
||||
boolean isValueListStruct = (call.getlValue() instanceof ValueList) && (procedure.getReturnType() instanceof SymbolTypeStruct);
|
||||
if(!isValueListStruct) {
|
||||
// Simple return value - fetch from stack
|
||||
SymbolType returnType = procedure.getReturnType();
|
||||
AsmFragmentInstanceSpecFactory asmFragmentInstanceSpecFactory = new AsmFragmentInstanceSpecFactory(call.getlValue(), new StackPullValue(returnType), program, block.getScope());
|
||||
ensureEncoding(asm, asmFragmentInstanceSpecFactory);
|
||||
generateAsm(asm, asmFragmentInstanceSpecFactory.getAsmFragmentInstanceSpec());
|
||||
} else {
|
||||
// Struct value list return value - fetch each member from stack
|
||||
final List<RValue> lValues = ((ValueList) call.getlValue()).getList();
|
||||
final StructDefinition structDefinition = ((SymbolTypeStruct) procedure.getReturnType()).getStructDefinition(getScope());
|
||||
final List<Variable> memberVars = new ArrayList<>(structDefinition.getAllVars(false));
|
||||
for(int i = 0; i < memberVars.size(); i++) {
|
||||
LValue lValue = (LValue) lValues.get(i);
|
||||
Variable memberDef = memberVars.get(i);
|
||||
final SymbolType memberType = memberDef.getType();
|
||||
if(i > 0)
|
||||
asm.startChunk(block.getScope(), statement.getIndex(), statement.toString(program, verboseAliveInfo));
|
||||
AsmFragmentInstanceSpecFactory asmFragmentInstanceSpecFactory = new AsmFragmentInstanceSpecFactory(lValue, new StackPullValue(memberType), program, block.getScope());
|
||||
ensureEncoding(asm, asmFragmentInstanceSpecFactory);
|
||||
generateAsm(asm, asmFragmentInstanceSpecFactory.getAsmFragmentInstanceSpec());
|
||||
asm.getCurrentChunk().setSubStatementIdx(i);
|
||||
asm.getCurrentChunk().setSubStatementId(memberDef.toString(program));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if(statement instanceof StatementStackPull) {
|
||||
String pullSignature = "_stackpullbyte_" + AsmFormat.getAsmConstant(program, ((StatementStackPull) statement).getPullBytes(), 99, block.getScope());
|
||||
AsmFragmentInstanceSpec pullFragmentInstanceSpec = new AsmFragmentInstanceSpec(program, pullSignature, new LinkedHashMap<>(), block.getScope());
|
||||
generateAsm(asm, pullFragmentInstanceSpec);
|
||||
} else if(statement instanceof StatementReturn) {
|
||||
Procedure procedure = null;
|
||||
ScopeRef scope = block.getScope();
|
||||
if(!scope.equals(ScopeRef.ROOT)) {
|
||||
procedure = getScope().getProcedure(scope.getFullName());
|
||||
}
|
||||
|
||||
if(procedure != null && Procedure.CallingConvention.STACK_CALL.equals(procedure.getCallingConvention())) {
|
||||
StatementReturn returnStatement = (StatementReturn) statement;
|
||||
if(returnStatement.getValue() != null) {
|
||||
// Store return value on stack
|
||||
asm.startChunk(block.getScope(), statement.getIndex(), statement.toString(program, verboseAliveInfo));
|
||||
SymbolType returnType = procedure.getReturnType();
|
||||
boolean isValueListStruct = (returnStatement.getValue() instanceof ValueList) && (returnType instanceof SymbolTypeStruct);
|
||||
if(!isValueListStruct) {
|
||||
// A simple return type - put it on the stack
|
||||
ConstantRef returnOffsetConstant = CallingConventionStack.getReturnOffsetConstant(procedure);
|
||||
AsmFragmentInstanceSpecFactory asmFragmentInstanceSpecFactory = new AsmFragmentInstanceSpecFactory(new StackIdxValue(returnOffsetConstant, returnType), returnStatement.getValue(), program, block.getScope());
|
||||
ensureEncoding(asm, asmFragmentInstanceSpecFactory);
|
||||
generateAsm(asm, asmFragmentInstanceSpecFactory.getAsmFragmentInstanceSpec());
|
||||
} else {
|
||||
// A struct return value in a value list - Store each value on the stack
|
||||
final List<RValue> returnValues = ((ValueList) returnStatement.getValue()).getList();
|
||||
final StructDefinition structDefinition = ((SymbolTypeStruct) returnType).getStructDefinition(getScope());
|
||||
final List<Variable> memberVars = new ArrayList<>(structDefinition.getAllVars(false));
|
||||
for(int i = 0; i < memberVars.size(); i++) {
|
||||
RValue returnValue = returnValues.get(i);
|
||||
Variable memberDef = memberVars.get(i);
|
||||
final SymbolType memberType = memberDef.getType();
|
||||
ConstantRef returnOffsetConstant = CallingConventionStack.getReturnOffsetConstant(procedure);
|
||||
ConstantRef structMemberOffsetConstant = SizeOfConstants.getStructMemberOffsetConstant(getScope(), structDefinition, memberDef.getLocalName());
|
||||
ConstantBinary memberReturnOffsetConstant = new ConstantBinary(returnOffsetConstant, Operators.PLUS, structMemberOffsetConstant);
|
||||
if(i > 0)
|
||||
asm.startChunk(block.getScope(), statement.getIndex(), statement.toString(program, verboseAliveInfo));
|
||||
AsmFragmentInstanceSpecFactory asmFragmentInstanceSpecFactory = new AsmFragmentInstanceSpecFactory(new StackIdxValue(memberReturnOffsetConstant, memberType), returnValue, program, block.getScope());
|
||||
ensureEncoding(asm, asmFragmentInstanceSpecFactory);
|
||||
generateAsm(asm, asmFragmentInstanceSpecFactory.getAsmFragmentInstanceSpec());
|
||||
asm.getCurrentChunk().setSubStatementIdx(i);
|
||||
asm.getCurrentChunk().setSubStatementId(memberDef.toString(program));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(procedure == null || procedure.getInterruptType() == null) {
|
||||
asm.addInstruction("rts", AsmAddressingMode.NON, null, false);
|
||||
} else {
|
||||
|
@ -1,18 +1,23 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.CallingConventionStack;
|
||||
import dk.camelot64.kickc.model.Comment;
|
||||
import dk.camelot64.kickc.model.ControlFlowBlock;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
|
||||
import dk.camelot64.kickc.model.operators.Operators;
|
||||
import dk.camelot64.kickc.model.statements.*;
|
||||
import dk.camelot64.kickc.model.symbols.*;
|
||||
import dk.camelot64.kickc.model.symbols.Procedure;
|
||||
import dk.camelot64.kickc.model.symbols.Scope;
|
||||
import dk.camelot64.kickc.model.symbols.StructDefinition;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeInference;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeStruct;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
import dk.camelot64.kickc.passes.utils.SizeOfConstants;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
/** Handle calling convention {@link Procedure.CallingConvention#STACK_CALL} by converting the making control flow graph and symbols calling convention specific. */
|
||||
public class PassNCallingConventionStack extends Pass2SsaOptimization {
|
||||
@ -68,8 +73,8 @@ public class PassNCallingConventionStack extends Pass2SsaOptimization {
|
||||
}
|
||||
}
|
||||
|
||||
// Convert param(xxx) to stackidx(PARAM_X) = xxx
|
||||
if(offsetConstants.size() > 0) {
|
||||
// Convert ParamValue to StackIdxValue
|
||||
ProgramValueIterator.execute(getGraph(), (programValue, currentStmt, stmtIt, currentBlock) -> {
|
||||
if(programValue.get() instanceof ParamValue) {
|
||||
// Convert ParamValues to calling-convention specific param-value
|
||||
@ -84,7 +89,122 @@ public class PassNCallingConventionStack extends Pass2SsaOptimization {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Convert procedure return xxx to stackidx(RETURN) = xxx;
|
||||
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
|
||||
ListIterator<Statement> stmtIt = block.getStatements().listIterator();
|
||||
while(stmtIt.hasNext()) {
|
||||
Statement statement = stmtIt.next();
|
||||
if(statement instanceof StatementReturn) {
|
||||
final Scope blockScope = getScope().getScope(block.getScope());
|
||||
if(blockScope instanceof Procedure) {
|
||||
Procedure procedure = (Procedure) blockScope;
|
||||
final SymbolType returnType = procedure.getReturnType();
|
||||
if(!SymbolType.VOID.equals(returnType) && Procedure.CallingConvention.STACK_CALL.equals(procedure.getCallingConvention())) {
|
||||
ConstantRef returnOffsetConstant = CallingConventionStack.getReturnOffsetConstant(procedure);
|
||||
final RValue value = ((StatementReturn) statement).getValue();
|
||||
stmtIt.previous();
|
||||
generateStackReturnValues(value, returnType, returnOffsetConstant, statement.getSource(), statement.getComments(), stmtIt);
|
||||
stmtIt.next();
|
||||
((StatementReturn) statement).setValue(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convert xxx = callfinalize to xxx = stackpull(type);
|
||||
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
|
||||
ListIterator<Statement> stmtIt = block.getStatements().listIterator();
|
||||
while(stmtIt.hasNext()) {
|
||||
Statement statement = stmtIt.next();
|
||||
if(statement instanceof StatementCallFinalize) {
|
||||
final StatementCallFinalize call = (StatementCallFinalize) statement;
|
||||
Procedure procedure = getScope().getProcedure(call.getProcedure());
|
||||
final SymbolType returnType = procedure.getReturnType();
|
||||
if(Procedure.CallingConvention.STACK_CALL.equals(procedure.getCallingConvention())) {
|
||||
long stackFrameByteSize = CallingConventionStack.getStackFrameByteSize(procedure);
|
||||
long returnByteSize = procedure.getReturnType() == null ? 0 : procedure.getReturnType().getSizeBytes();
|
||||
long stackCleanBytes = (call.getlValue() == null) ? stackFrameByteSize : (stackFrameByteSize - returnByteSize);
|
||||
stmtIt.previous();
|
||||
final StatementSource source = call.getSource();
|
||||
final List<Comment> comments = call.getComments();
|
||||
if(stackCleanBytes > 0) {
|
||||
// Clean up the stack
|
||||
stmtIt.add(new StatementStackPull( new ConstantInteger(stackCleanBytes), source, comments));
|
||||
//String pullSignature = "_stackpullbyte_" + stackCleanBytes;
|
||||
}
|
||||
final RValue value = call.getlValue();
|
||||
if(value!=null)
|
||||
generateStackPullValues(value, returnType, statement.getSource(), statement.getComments(), stmtIt);
|
||||
stmtIt.next();
|
||||
stmtIt.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Put a return value onto the stack by generating stackidx(RETURN) = xxx assignments
|
||||
*
|
||||
* @param value The value to return
|
||||
* @param returnType The type of the value
|
||||
* @param stackReturnOffset The offset onto the stack to place the value at
|
||||
* @param source The source line
|
||||
* @param comments The comments
|
||||
* @param stmtIt The statment iterator used to add statements to.
|
||||
*/
|
||||
private void generateStackReturnValues(RValue value, SymbolType returnType, ConstantValue stackReturnOffset, StatementSource source, List<Comment> comments, ListIterator<Statement> stmtIt) {
|
||||
if(!(value instanceof ValueList) || !(returnType instanceof SymbolTypeStruct)) {
|
||||
// A simple value to put on the stack
|
||||
final StatementAssignment stackReturn = new StatementAssignment(new StackIdxValue(stackReturnOffset, returnType), value, false, source, comments);
|
||||
stmtIt.add(stackReturn);
|
||||
getLog().append("Calling convention " + Procedure.CallingConvention.STACK_CALL + " adding stack return " + stackReturn);
|
||||
} else {
|
||||
// A struct to put on the stack
|
||||
final List<RValue> memberValues = ((ValueList) value).getList();
|
||||
final StructDefinition structDefinition = ((SymbolTypeStruct) returnType).getStructDefinition(getScope());
|
||||
final List<Variable> memberVars = new ArrayList<>(structDefinition.getAllVars(false));
|
||||
for(int i = 0; i < memberVars.size(); i++) {
|
||||
final Variable memberVar = memberVars.get(i);
|
||||
final RValue memberValue = memberValues.get(i);
|
||||
ConstantRef structMemberOffsetConstant = SizeOfConstants.getStructMemberOffsetConstant(getScope(), structDefinition, memberVar.getLocalName());
|
||||
ConstantBinary memberReturnOffsetConstant = new ConstantBinary(stackReturnOffset, Operators.PLUS, structMemberOffsetConstant);
|
||||
generateStackReturnValues(memberValue, memberVar.getType(), memberReturnOffsetConstant, source, comments, stmtIt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate stack pull xxx = stackpull(type) assignments
|
||||
*
|
||||
* @param value The value to return
|
||||
* @param symbolType The type of the value
|
||||
* @param source The source line
|
||||
* @param comments The comments
|
||||
* @param stmtIt The statment iterator used to add statements to.
|
||||
*/
|
||||
private void generateStackPullValues(RValue value, SymbolType symbolType, StatementSource source, List<Comment> comments, ListIterator<Statement> stmtIt) {
|
||||
if(!(value instanceof ValueList) || !(symbolType instanceof SymbolTypeStruct)) {
|
||||
// A simple value to put on the stack
|
||||
final StatementAssignment stackPull = new StatementAssignment((LValue) value, new StackPullValue(symbolType), false, source, comments);
|
||||
stmtIt.add(stackPull);
|
||||
getLog().append("Calling convention " + Procedure.CallingConvention.STACK_CALL + " adding stack pull " + stackPull);
|
||||
} else {
|
||||
// A struct to put on the stack
|
||||
final List<RValue> memberValues = ((ValueList) value).getList();
|
||||
final StructDefinition structDefinition = ((SymbolTypeStruct) symbolType).getStructDefinition(getScope());
|
||||
final List<Variable> memberVars = new ArrayList<>(structDefinition.getAllVars(false));
|
||||
for(int i = 0; i < memberVars.size(); i++) {
|
||||
final Variable memberVar = memberVars.get(i);
|
||||
final RValue memberValue = memberValues.get(i);
|
||||
generateStackPullValues(memberValue, memberVar.getType(), source, comments, stmtIt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ package dk.camelot64.kickc.passes.calcs;
|
||||
import dk.camelot64.kickc.model.ControlFlowBlock;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementInfos;
|
||||
import dk.camelot64.kickc.model.StatementInfos;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
|
@ -61,8 +61,8 @@ public class ValueSourceFactory {
|
||||
return structValueSource.getMemberUnwinding(((StructMemberRef) value).getMemberName(), program, programScope, currentStmt, stmtIt, currentBlock);
|
||||
}
|
||||
if(valueType instanceof SymbolTypeStruct && value instanceof ParamValue) {
|
||||
final StructDefinition structDefinition = ((SymbolTypeStruct) valueType).getStructDefinition(programScope);
|
||||
return new ValueSourceParamList((ParamValue) value, structDefinition);
|
||||
final ValueSource subValueSource = getValueSource(((ParamValue) value).getParameter(), program, programScope, currentStmt, stmtIt, currentBlock);
|
||||
return new ValueSourceParamValue(subValueSource);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -1,65 +0,0 @@
|
||||
package dk.camelot64.kickc.passes.unwinding;
|
||||
|
||||
import dk.camelot64.kickc.model.ControlFlowBlock;
|
||||
import dk.camelot64.kickc.model.InternalError;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.symbols.ArraySpec;
|
||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||
import dk.camelot64.kickc.model.symbols.StructDefinition;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.values.LValue;
|
||||
import dk.camelot64.kickc.model.values.ParamValue;
|
||||
import dk.camelot64.kickc.model.values.RValue;
|
||||
|
||||
import java.util.ListIterator;
|
||||
|
||||
/** A parameter value list. */
|
||||
public class ValueSourceParamList extends ValueSourceBase {
|
||||
|
||||
private final StructDefinition structDefinition;
|
||||
private final ParamValue paramValue;
|
||||
|
||||
public ValueSourceParamList(ParamValue paramValue, StructDefinition structDefinition) {
|
||||
this.paramValue = paramValue;
|
||||
this.structDefinition = structDefinition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SymbolType getSymbolType() {
|
||||
return structDefinition.getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArraySpec getArraySpec() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isStructClassic() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RValue getSimpleValue(ProgramScope programScope) {
|
||||
throw new InternalError("Not a simple value");
|
||||
}
|
||||
|
||||
@Override
|
||||
public LValue getBulkLValue(ProgramScope scope) {
|
||||
throw new InternalError("Not a bulk value");
|
||||
}
|
||||
|
||||
@Override
|
||||
public RValue getBulkRValue(ProgramScope scope) {
|
||||
throw new InternalError("Not a bulk value");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueSource getMemberUnwinding(String memberName, Program program, ProgramScope programScope, Statement currentStmt, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock) {
|
||||
final ValueSource paramValueSource = ValueSourceFactory.getValueSource(paramValue.getParameter(), program, programScope, currentStmt, stmtIt, currentBlock);
|
||||
final ValueSource memberUnwinding = paramValueSource.getMemberUnwinding(memberName, program, programScope, currentStmt, stmtIt, currentBlock);
|
||||
return new ValueSourceParamValue(memberUnwinding);
|
||||
}
|
||||
|
||||
}
|
@ -14,7 +14,7 @@ import dk.camelot64.kickc.model.values.VariableRef;
|
||||
|
||||
import java.util.ListIterator;
|
||||
|
||||
/** An unwound parameter value. */
|
||||
/** A parameter value list. */
|
||||
public class ValueSourceParamValue extends ValueSourceBase {
|
||||
|
||||
private final ValueSource valueSource;
|
||||
@ -30,7 +30,7 @@ public class ValueSourceParamValue extends ValueSourceBase {
|
||||
|
||||
@Override
|
||||
public ArraySpec getArraySpec() {
|
||||
return valueSource.getArraySpec();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -55,7 +55,8 @@ public class ValueSourceParamValue extends ValueSourceBase {
|
||||
|
||||
@Override
|
||||
public ValueSource getMemberUnwinding(String memberName, Program program, ProgramScope programScope, Statement currentStmt, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock) {
|
||||
throw new InternalError("Not unwindable");
|
||||
final ValueSource memberUnwinding = valueSource.getMemberUnwinding(memberName, program, programScope, currentStmt, stmtIt, currentBlock);
|
||||
return new ValueSourceParamValue(memberUnwinding);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -279,6 +279,11 @@ public class TestPrograms {
|
||||
compileAndCompare("declared-memory-var-0");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcedureCallingConventionStack11() throws IOException, URISyntaxException {
|
||||
compileAndCompare("procedure-callingconvention-stack-11");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcedureCallingConventionStack10() throws IOException, URISyntaxException {
|
||||
compileAndCompare("procedure-callingconvention-stack-10");
|
||||
|
44
src/test/kc/procedure-callingconvention-stack-11.kc
Normal file
44
src/test/kc/procedure-callingconvention-stack-11.kc
Normal file
@ -0,0 +1,44 @@
|
||||
// Test a procedure with calling convention stack
|
||||
// Returning and passing struct of struct values
|
||||
|
||||
#pragma calling(__stackcall)
|
||||
#pragma var_model(ma_zp)
|
||||
|
||||
const char* SCREEN = 0x0400;
|
||||
char idx = 0;
|
||||
|
||||
struct Point {
|
||||
char x;
|
||||
char y;
|
||||
};
|
||||
|
||||
struct Vector {
|
||||
struct Point p1;
|
||||
struct Point p2;
|
||||
};
|
||||
|
||||
|
||||
void main(void) {
|
||||
for(char i=0;i<5;i++) {
|
||||
struct Vector v = get(i);
|
||||
print(v);
|
||||
}
|
||||
}
|
||||
|
||||
struct Vector get(char i) {
|
||||
struct Vector v = { {i, i/2}, {i+1, i*2} };
|
||||
return v;
|
||||
}
|
||||
|
||||
void print(struct Vector v) {
|
||||
SCREEN[idx++] = v.p1.x;
|
||||
SCREEN[idx++] = v.p1.y;
|
||||
SCREEN[idx++] = v.p2.x;
|
||||
SCREEN[idx++] = v.p2.y;
|
||||
SCREEN[idx++] = ' ';
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -12,19 +12,21 @@
|
||||
main: scope:[main] from @1
|
||||
[4] callprepare plus (byte) '0' (byte) 7
|
||||
[5] callexecute plus
|
||||
[6] (byte~) main::$0 ← callfinalize plus
|
||||
[7] *((const byte*) SCREEN) ← (byte~) main::$0
|
||||
stackpull((number) 1)
|
||||
[7] (byte~) main::$0 ← stackpull(byte)
|
||||
[8] *((const byte*) SCREEN) ← (byte~) main::$0
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[8] return
|
||||
[9] return
|
||||
to:@return
|
||||
|
||||
__stackcall (byte()) plus((byte) plus::a , (byte) plus::b)
|
||||
plus: scope:[plus] from
|
||||
[9] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A)
|
||||
[10] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B)
|
||||
[11] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0
|
||||
[10] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A)
|
||||
[11] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B)
|
||||
[12] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0
|
||||
to:plus::@return
|
||||
plus::@return: scope:[plus] from plus
|
||||
[12] return (byte) plus::return#0
|
||||
[13] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0
|
||||
[14] return
|
||||
to:@return
|
||||
|
@ -3,6 +3,8 @@ Culled Empty Block (label) plus::@1
|
||||
Calling convention STACK_CALL adding prepare/execute/finalize for (byte~) main::$0 ← call plus (byte) '0' (number) 7
|
||||
Calling convention STACK_CALL replacing param((byte) plus::a) with stackidx(byte,(const byte) plus::OFFSET_STACK_A)
|
||||
Calling convention STACK_CALL replacing param((byte) plus::b) with stackidx(byte,(const byte) plus::OFFSET_STACK_B)
|
||||
Calling convention STACK_CALL adding stack return stackidx(byte,plus::OFFSET_STACK_RETURN) ← plus::return
|
||||
Calling convention STACK_CALL adding stack pull main::$0 ← stackpull(byte)
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
@begin: scope:[] from
|
||||
@ -12,7 +14,8 @@ CONTROL FLOW GRAPH SSA
|
||||
main: scope:[main] from @2
|
||||
callprepare plus (byte) '0' (number) 7
|
||||
callexecute plus
|
||||
(byte~) main::$0 ← callfinalize plus
|
||||
stackpull((number) 1)
|
||||
(byte~) main::$0 ← stackpull(byte)
|
||||
*((const byte*) SCREEN + (number) 0) ← (byte~) main::$0
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
@ -28,7 +31,8 @@ plus: scope:[plus] from
|
||||
to:plus::@return
|
||||
plus::@return: scope:[plus] from plus
|
||||
(byte) plus::return#1 ← phi( plus/(byte) plus::return#0 )
|
||||
return (byte) plus::return#1
|
||||
stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#1
|
||||
return
|
||||
to:@return
|
||||
@2: scope:[] from @begin
|
||||
call main
|
||||
@ -73,10 +77,8 @@ Finalized unsigned number type (byte) 0
|
||||
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||
Alias (byte) plus::return#0 = (byte~) plus::$0 (byte) plus::return#1
|
||||
Successful SSA optimization Pass2AliasElimination
|
||||
Simplifying expression containing zero SCREEN in [3] *((const byte*) SCREEN + (byte) 0) ← (byte~) main::$0
|
||||
Simplifying expression containing zero SCREEN in [4] *((const byte*) SCREEN + (byte) 0) ← (byte~) main::$0
|
||||
Successful SSA optimization PassNSimplifyExpressionWithZero
|
||||
Eliminating unused constant (const byte) plus::OFFSET_STACK_RETURN
|
||||
Successful SSA optimization PassNEliminateUnusedVars
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @2
|
||||
Adding NOP phi() at start of @3
|
||||
@ -108,34 +110,36 @@ FINAL CONTROL FLOW GRAPH
|
||||
main: scope:[main] from @1
|
||||
[4] callprepare plus (byte) '0' (byte) 7
|
||||
[5] callexecute plus
|
||||
[6] (byte~) main::$0 ← callfinalize plus
|
||||
[7] *((const byte*) SCREEN) ← (byte~) main::$0
|
||||
stackpull((number) 1)
|
||||
[7] (byte~) main::$0 ← stackpull(byte)
|
||||
[8] *((const byte*) SCREEN) ← (byte~) main::$0
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[8] return
|
||||
[9] return
|
||||
to:@return
|
||||
|
||||
__stackcall (byte()) plus((byte) plus::a , (byte) plus::b)
|
||||
plus: scope:[plus] from
|
||||
[9] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A)
|
||||
[10] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B)
|
||||
[11] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0
|
||||
[10] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A)
|
||||
[11] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B)
|
||||
[12] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0
|
||||
to:plus::@return
|
||||
plus::@return: scope:[plus] from plus
|
||||
[12] return (byte) plus::return#0
|
||||
[13] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0
|
||||
[14] return
|
||||
to:@return
|
||||
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
(void()) main()
|
||||
(byte~) main::$0 2.0
|
||||
(byte~) main::$0 4.0
|
||||
__stackcall (byte()) plus((byte) plus::a , (byte) plus::b)
|
||||
(byte) plus::a
|
||||
(byte) plus::a#0 2.0
|
||||
(byte) plus::b
|
||||
(byte) plus::b#0 4.0
|
||||
(byte) plus::return
|
||||
(byte) plus::return#0 2.0
|
||||
(byte) plus::return#0 4.0
|
||||
|
||||
Initial phi equivalence classes
|
||||
Added variable main::$0 to live range equivalence class [ main::$0 ]
|
||||
@ -188,18 +192,18 @@ main: {
|
||||
pha
|
||||
// [5] callexecute plus -- jsr
|
||||
jsr plus
|
||||
// [6] (byte~) main::$0 ← callfinalize plus -- _stackpullbyte_1
|
||||
// stackpull((number) 1) -- _stackpullbyte_1
|
||||
pla
|
||||
// [6] (byte~) main::$0 ← callfinalize plus -- vbuz1=_stackpullbyte_
|
||||
// [7] (byte~) main::$0 ← stackpull(byte) -- vbuz1=_stackpullbyte_
|
||||
pla
|
||||
sta.z __0
|
||||
// [7] *((const byte*) SCREEN) ← (byte~) main::$0 -- _deref_pbuc1=vbuz1
|
||||
// [8] *((const byte*) SCREEN) ← (byte~) main::$0 -- _deref_pbuc1=vbuz1
|
||||
lda.z __0
|
||||
sta SCREEN
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [8] return
|
||||
// [9] return
|
||||
rts
|
||||
}
|
||||
// plus
|
||||
@ -207,18 +211,19 @@ main: {
|
||||
plus: {
|
||||
.const OFFSET_STACK_A = 1
|
||||
.const OFFSET_STACK_B = 0
|
||||
.const OFFSET_STACK_RETURN = 1
|
||||
.label a = 3
|
||||
.label b = 4
|
||||
.label return = 5
|
||||
// [9] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1
|
||||
// [10] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_A,x
|
||||
sta.z a
|
||||
// [10] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuz1=_stackidxbyte_vbuc1
|
||||
// [11] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuz1=_stackidxbyte_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_B,x
|
||||
sta.z b
|
||||
// [11] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuz1=vbuz2_plus_vbuz3
|
||||
// [12] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuz1=vbuz2_plus_vbuz3
|
||||
lda.z a
|
||||
clc
|
||||
adc.z b
|
||||
@ -226,41 +231,43 @@ plus: {
|
||||
jmp __breturn
|
||||
// plus::@return
|
||||
__breturn:
|
||||
// [12] return (byte) plus::return#0
|
||||
// [12] return (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuz1
|
||||
// [13] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuz1
|
||||
lda.z return
|
||||
tsx
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN,x
|
||||
// [14] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Statement [4] callprepare plus (byte) '0' (byte) 7 [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
Statement [6] (byte~) main::$0 ← callfinalize plus [ main::$0 ] ( main:2 [ main::$0 ] ) always clobbers reg byte a
|
||||
Statement [9] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:5 [ plus::a#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement [10] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:5 [ plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement stackpull((number) 1) always clobbers reg byte a
|
||||
Statement [7] (byte~) main::$0 ← stackpull(byte) [ main::$0 ] ( main:2 [ main::$0 ] ) always clobbers reg byte a
|
||||
Statement [10] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:5 [ plus::a#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement [11] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:5 [ plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x
|
||||
Removing always clobbered register reg byte a as potential for zp[1]:3 [ plus::a#0 ]
|
||||
Removing always clobbered register reg byte x as potential for zp[1]:3 [ plus::a#0 ]
|
||||
Statement [11] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 [ plus::return#0 ] ( main:2::plus:5 [ plus::return#0 ] ) always clobbers reg byte a
|
||||
Statement [12] return (byte) plus::return#0 [ ] ( main:2::plus:5 [ ] ) always clobbers reg byte x
|
||||
Statement [12] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 [ plus::return#0 ] ( main:2::plus:5 [ plus::return#0 ] ) always clobbers reg byte a
|
||||
Statement [13] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 [ ] ( main:2::plus:5 [ ] ) always clobbers reg byte x
|
||||
Statement [4] callprepare plus (byte) '0' (byte) 7 [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
Statement [6] (byte~) main::$0 ← callfinalize plus [ main::$0 ] ( main:2 [ main::$0 ] ) always clobbers reg byte a
|
||||
Statement [9] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:5 [ plus::a#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement [10] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:5 [ plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement [11] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 [ plus::return#0 ] ( main:2::plus:5 [ plus::return#0 ] ) always clobbers reg byte a
|
||||
Statement [12] return (byte) plus::return#0 [ ] ( main:2::plus:5 [ ] ) always clobbers reg byte x
|
||||
Statement stackpull((number) 1) always clobbers reg byte a
|
||||
Statement [7] (byte~) main::$0 ← stackpull(byte) [ main::$0 ] ( main:2 [ main::$0 ] ) always clobbers reg byte a
|
||||
Statement [10] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:5 [ plus::a#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement [11] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:5 [ plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement [12] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 [ plus::return#0 ] ( main:2::plus:5 [ plus::return#0 ] ) always clobbers reg byte a
|
||||
Statement [13] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 [ ] ( main:2::plus:5 [ ] ) always clobbers reg byte x
|
||||
Potential registers zp[1]:2 [ main::$0 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:3 [ plus::a#0 ] : zp[1]:3 , reg byte y ,
|
||||
Potential registers zp[1]:4 [ plus::b#0 ] : zp[1]:4 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:5 [ plus::return#0 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y ,
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [plus] 4: zp[1]:4 [ plus::b#0 ] 2: zp[1]:3 [ plus::a#0 ] 2: zp[1]:5 [ plus::return#0 ]
|
||||
Uplift Scope [main] 2: zp[1]:2 [ main::$0 ]
|
||||
Uplift Scope [plus] 4: zp[1]:4 [ plus::b#0 ] 4: zp[1]:5 [ plus::return#0 ] 2: zp[1]:3 [ plus::a#0 ]
|
||||
Uplift Scope [main] 4: zp[1]:2 [ main::$0 ]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [plus] best 91 combination reg byte a [ plus::b#0 ] zp[1]:3 [ plus::a#0 ] reg byte a [ plus::return#0 ]
|
||||
Uplifting [plus] best 91 combination reg byte a [ plus::b#0 ] reg byte a [ plus::return#0 ] zp[1]:3 [ plus::a#0 ]
|
||||
Uplifting [main] best 85 combination reg byte a [ main::$0 ]
|
||||
Uplifting [] best 85 combination
|
||||
Attempting to uplift remaining variables inzp[1]:3 [ plus::a#0 ]
|
||||
@ -301,16 +308,16 @@ main: {
|
||||
pha
|
||||
// [5] callexecute plus -- jsr
|
||||
jsr plus
|
||||
// [6] (byte~) main::$0 ← callfinalize plus -- _stackpullbyte_1
|
||||
// stackpull((number) 1) -- _stackpullbyte_1
|
||||
pla
|
||||
// [6] (byte~) main::$0 ← callfinalize plus -- vbuaa=_stackpullbyte_
|
||||
// [7] (byte~) main::$0 ← stackpull(byte) -- vbuaa=_stackpullbyte_
|
||||
pla
|
||||
// [7] *((const byte*) SCREEN) ← (byte~) main::$0 -- _deref_pbuc1=vbuaa
|
||||
// [8] *((const byte*) SCREEN) ← (byte~) main::$0 -- _deref_pbuc1=vbuaa
|
||||
sta SCREEN
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [8] return
|
||||
// [9] return
|
||||
rts
|
||||
}
|
||||
// plus
|
||||
@ -320,23 +327,23 @@ plus: {
|
||||
.const OFFSET_STACK_B = 0
|
||||
.const OFFSET_STACK_RETURN = 1
|
||||
.label a = 2
|
||||
// [9] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1
|
||||
// [10] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_A,x
|
||||
sta.z a
|
||||
// [10] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuaa=_stackidxbyte_vbuc1
|
||||
// [11] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuaa=_stackidxbyte_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_B,x
|
||||
// [11] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuaa=vbuz1_plus_vbuaa
|
||||
// [12] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuaa=vbuz1_plus_vbuaa
|
||||
clc
|
||||
adc.z a
|
||||
jmp __breturn
|
||||
// plus::@return
|
||||
__breturn:
|
||||
// [12] return (byte) plus::return#0
|
||||
// [12] return (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuaa
|
||||
// [13] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuaa
|
||||
tsx
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN,x
|
||||
// [14] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
@ -368,7 +375,7 @@ FINAL SYMBOL TABLE
|
||||
(const byte*) SCREEN = (byte*) 1024
|
||||
(const word) STACK_BASE = (word) $103
|
||||
(void()) main()
|
||||
(byte~) main::$0 reg byte a 2.0
|
||||
(byte~) main::$0 reg byte a 4.0
|
||||
(label) main::@return
|
||||
__stackcall (byte()) plus((byte) plus::a , (byte) plus::b)
|
||||
(label) plus::@return
|
||||
@ -380,7 +387,7 @@ __stackcall (byte()) plus((byte) plus::a , (byte) plus::b)
|
||||
(byte) plus::b
|
||||
(byte) plus::b#0 reg byte a 4.0
|
||||
(byte) plus::return
|
||||
(byte) plus::return#0 reg byte a 2.0
|
||||
(byte) plus::return#0 reg byte a 4.0
|
||||
|
||||
reg byte a [ main::$0 ]
|
||||
zp[1]:2 [ plus::a#0 ]
|
||||
@ -417,16 +424,16 @@ main: {
|
||||
pha
|
||||
// [5] callexecute plus -- jsr
|
||||
jsr plus
|
||||
// [6] (byte~) main::$0 ← callfinalize plus -- _stackpullbyte_1
|
||||
// stackpull((number) 1) -- _stackpullbyte_1
|
||||
pla
|
||||
// [6] (byte~) main::$0 ← callfinalize plus -- vbuaa=_stackpullbyte_
|
||||
// [7] (byte~) main::$0 ← stackpull(byte) -- vbuaa=_stackpullbyte_
|
||||
pla
|
||||
// SCREEN[0] = plus('0', 7)
|
||||
// [7] *((const byte*) SCREEN) ← (byte~) main::$0 -- _deref_pbuc1=vbuaa
|
||||
// [8] *((const byte*) SCREEN) ← (byte~) main::$0 -- _deref_pbuc1=vbuaa
|
||||
sta SCREEN
|
||||
// main::@return
|
||||
// }
|
||||
// [8] return
|
||||
// [9] return
|
||||
rts
|
||||
}
|
||||
// plus
|
||||
@ -436,23 +443,23 @@ plus: {
|
||||
.const OFFSET_STACK_B = 0
|
||||
.const OFFSET_STACK_RETURN = 1
|
||||
.label a = 2
|
||||
// [9] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1
|
||||
// [10] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_A,x
|
||||
sta.z a
|
||||
// [10] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuaa=_stackidxbyte_vbuc1
|
||||
// [11] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuaa=_stackidxbyte_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_B,x
|
||||
// return a+b;
|
||||
// [11] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuaa=vbuz1_plus_vbuaa
|
||||
// [12] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuaa=vbuz1_plus_vbuaa
|
||||
clc
|
||||
adc.z a
|
||||
// plus::@return
|
||||
// }
|
||||
// [12] return (byte) plus::return#0
|
||||
// [12] return (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuaa
|
||||
// [13] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuaa
|
||||
tsx
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN,x
|
||||
// [14] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
@ -4,7 +4,7 @@
|
||||
(const byte*) SCREEN = (byte*) 1024
|
||||
(const word) STACK_BASE = (word) $103
|
||||
(void()) main()
|
||||
(byte~) main::$0 reg byte a 2.0
|
||||
(byte~) main::$0 reg byte a 4.0
|
||||
(label) main::@return
|
||||
__stackcall (byte()) plus((byte) plus::a , (byte) plus::b)
|
||||
(label) plus::@return
|
||||
@ -16,7 +16,7 @@ __stackcall (byte()) plus((byte) plus::a , (byte) plus::b)
|
||||
(byte) plus::b
|
||||
(byte) plus::b#0 reg byte a 4.0
|
||||
(byte) plus::return
|
||||
(byte) plus::return#0 reg byte a 2.0
|
||||
(byte) plus::return#0 reg byte a 4.0
|
||||
|
||||
reg byte a [ main::$0 ]
|
||||
zp[1]:2 [ plus::a#0 ]
|
||||
|
@ -12,19 +12,21 @@
|
||||
main: scope:[main] from @1
|
||||
[4] callprepare plus (byte) '0' (byte) 7
|
||||
[5] callexecute plus
|
||||
[6] (byte~) main::$0 ← callfinalize plus
|
||||
[7] *((const byte*) SCREEN) ← (byte~) main::$0
|
||||
stackpull((number) 1)
|
||||
[7] (byte~) main::$0 ← stackpull(byte)
|
||||
[8] *((const byte*) SCREEN) ← (byte~) main::$0
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[8] return
|
||||
[9] return
|
||||
to:@return
|
||||
|
||||
__stackcall (byte()) plus((byte) plus::a , (byte) plus::b)
|
||||
plus: scope:[plus] from
|
||||
[9] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A)
|
||||
[10] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B)
|
||||
[11] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0
|
||||
[10] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A)
|
||||
[11] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B)
|
||||
[12] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0
|
||||
to:plus::@return
|
||||
plus::@return: scope:[plus] from plus
|
||||
[12] return (byte) plus::return#0
|
||||
[13] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0
|
||||
[14] return
|
||||
to:@return
|
||||
|
@ -3,6 +3,8 @@ Culled Empty Block (label) plus::@1
|
||||
Calling convention STACK_CALL adding prepare/execute/finalize for (byte~) main::$0 ← call plus (byte) '0' (number) 7
|
||||
Calling convention STACK_CALL replacing param((byte) plus::a) with stackidx(byte,(const byte) plus::OFFSET_STACK_A)
|
||||
Calling convention STACK_CALL replacing param((byte) plus::b) with stackidx(byte,(const byte) plus::OFFSET_STACK_B)
|
||||
Calling convention STACK_CALL adding stack return stackidx(byte,plus::OFFSET_STACK_RETURN) ← plus::return
|
||||
Calling convention STACK_CALL adding stack pull main::$0 ← stackpull(byte)
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
@begin: scope:[] from
|
||||
@ -12,7 +14,8 @@ CONTROL FLOW GRAPH SSA
|
||||
main: scope:[main] from @2
|
||||
callprepare plus (byte) '0' (number) 7
|
||||
callexecute plus
|
||||
(byte~) main::$0 ← callfinalize plus
|
||||
stackpull((number) 1)
|
||||
(byte~) main::$0 ← stackpull(byte)
|
||||
*((const byte*) SCREEN + (number) 0) ← (byte~) main::$0
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
@ -28,7 +31,8 @@ plus: scope:[plus] from
|
||||
to:plus::@return
|
||||
plus::@return: scope:[plus] from plus
|
||||
(byte) plus::return#1 ← phi( plus/(byte) plus::return#0 )
|
||||
return (byte) plus::return#1
|
||||
stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#1
|
||||
return
|
||||
to:@return
|
||||
@2: scope:[] from @begin
|
||||
call main
|
||||
@ -73,10 +77,8 @@ Finalized unsigned number type (byte) 0
|
||||
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||
Alias (byte) plus::return#0 = (byte~) plus::$0 (byte) plus::return#1
|
||||
Successful SSA optimization Pass2AliasElimination
|
||||
Simplifying expression containing zero SCREEN in [3] *((const byte*) SCREEN + (byte) 0) ← (byte~) main::$0
|
||||
Simplifying expression containing zero SCREEN in [4] *((const byte*) SCREEN + (byte) 0) ← (byte~) main::$0
|
||||
Successful SSA optimization PassNSimplifyExpressionWithZero
|
||||
Eliminating unused constant (const byte) plus::OFFSET_STACK_RETURN
|
||||
Successful SSA optimization PassNEliminateUnusedVars
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @2
|
||||
Adding NOP phi() at start of @3
|
||||
@ -108,34 +110,36 @@ FINAL CONTROL FLOW GRAPH
|
||||
main: scope:[main] from @1
|
||||
[4] callprepare plus (byte) '0' (byte) 7
|
||||
[5] callexecute plus
|
||||
[6] (byte~) main::$0 ← callfinalize plus
|
||||
[7] *((const byte*) SCREEN) ← (byte~) main::$0
|
||||
stackpull((number) 1)
|
||||
[7] (byte~) main::$0 ← stackpull(byte)
|
||||
[8] *((const byte*) SCREEN) ← (byte~) main::$0
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[8] return
|
||||
[9] return
|
||||
to:@return
|
||||
|
||||
__stackcall (byte()) plus((byte) plus::a , (byte) plus::b)
|
||||
plus: scope:[plus] from
|
||||
[9] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A)
|
||||
[10] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B)
|
||||
[11] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0
|
||||
[10] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A)
|
||||
[11] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B)
|
||||
[12] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0
|
||||
to:plus::@return
|
||||
plus::@return: scope:[plus] from plus
|
||||
[12] return (byte) plus::return#0
|
||||
[13] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0
|
||||
[14] return
|
||||
to:@return
|
||||
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
(void()) main()
|
||||
(byte~) main::$0 2.0
|
||||
(byte~) main::$0 4.0
|
||||
__stackcall (byte()) plus((byte) plus::a , (byte) plus::b)
|
||||
(byte) plus::a
|
||||
(byte) plus::a#0 2.0
|
||||
(byte) plus::b
|
||||
(byte) plus::b#0 4.0
|
||||
(byte) plus::return
|
||||
(byte) plus::return#0 2.0
|
||||
(byte) plus::return#0 4.0
|
||||
|
||||
Initial phi equivalence classes
|
||||
Added variable main::$0 to live range equivalence class [ main::$0 ]
|
||||
@ -188,18 +192,18 @@ main: {
|
||||
pha
|
||||
// [5] callexecute plus -- jsr
|
||||
jsr plus
|
||||
// [6] (byte~) main::$0 ← callfinalize plus -- _stackpullbyte_1
|
||||
// stackpull((number) 1) -- _stackpullbyte_1
|
||||
pla
|
||||
// [6] (byte~) main::$0 ← callfinalize plus -- vbuz1=_stackpullbyte_
|
||||
// [7] (byte~) main::$0 ← stackpull(byte) -- vbuz1=_stackpullbyte_
|
||||
pla
|
||||
sta.z __0
|
||||
// [7] *((const byte*) SCREEN) ← (byte~) main::$0 -- _deref_pbuc1=vbuz1
|
||||
// [8] *((const byte*) SCREEN) ← (byte~) main::$0 -- _deref_pbuc1=vbuz1
|
||||
lda.z __0
|
||||
sta SCREEN
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [8] return
|
||||
// [9] return
|
||||
rts
|
||||
}
|
||||
// plus
|
||||
@ -207,18 +211,19 @@ main: {
|
||||
plus: {
|
||||
.const OFFSET_STACK_A = 1
|
||||
.const OFFSET_STACK_B = 0
|
||||
.const OFFSET_STACK_RETURN = 1
|
||||
.label a = 3
|
||||
.label b = 4
|
||||
.label return = 5
|
||||
// [9] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1
|
||||
// [10] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_A,x
|
||||
sta.z a
|
||||
// [10] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuz1=_stackidxbyte_vbuc1
|
||||
// [11] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuz1=_stackidxbyte_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_B,x
|
||||
sta.z b
|
||||
// [11] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuz1=vbuz2_plus_vbuz3
|
||||
// [12] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuz1=vbuz2_plus_vbuz3
|
||||
lda.z a
|
||||
clc
|
||||
adc.z b
|
||||
@ -226,41 +231,43 @@ plus: {
|
||||
jmp __breturn
|
||||
// plus::@return
|
||||
__breturn:
|
||||
// [12] return (byte) plus::return#0
|
||||
// [12] return (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuz1
|
||||
// [13] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuz1
|
||||
lda.z return
|
||||
tsx
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN,x
|
||||
// [14] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Statement [4] callprepare plus (byte) '0' (byte) 7 [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
Statement [6] (byte~) main::$0 ← callfinalize plus [ main::$0 ] ( main:2 [ main::$0 ] ) always clobbers reg byte a
|
||||
Statement [9] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:5 [ plus::a#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement [10] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:5 [ plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement stackpull((number) 1) always clobbers reg byte a
|
||||
Statement [7] (byte~) main::$0 ← stackpull(byte) [ main::$0 ] ( main:2 [ main::$0 ] ) always clobbers reg byte a
|
||||
Statement [10] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:5 [ plus::a#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement [11] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:5 [ plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x
|
||||
Removing always clobbered register reg byte a as potential for zp[1]:3 [ plus::a#0 ]
|
||||
Removing always clobbered register reg byte x as potential for zp[1]:3 [ plus::a#0 ]
|
||||
Statement [11] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 [ plus::return#0 ] ( main:2::plus:5 [ plus::return#0 ] ) always clobbers reg byte a
|
||||
Statement [12] return (byte) plus::return#0 [ ] ( main:2::plus:5 [ ] ) always clobbers reg byte x
|
||||
Statement [12] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 [ plus::return#0 ] ( main:2::plus:5 [ plus::return#0 ] ) always clobbers reg byte a
|
||||
Statement [13] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 [ ] ( main:2::plus:5 [ ] ) always clobbers reg byte x
|
||||
Statement [4] callprepare plus (byte) '0' (byte) 7 [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
Statement [6] (byte~) main::$0 ← callfinalize plus [ main::$0 ] ( main:2 [ main::$0 ] ) always clobbers reg byte a
|
||||
Statement [9] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:5 [ plus::a#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement [10] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:5 [ plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement [11] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 [ plus::return#0 ] ( main:2::plus:5 [ plus::return#0 ] ) always clobbers reg byte a
|
||||
Statement [12] return (byte) plus::return#0 [ ] ( main:2::plus:5 [ ] ) always clobbers reg byte x
|
||||
Statement stackpull((number) 1) always clobbers reg byte a
|
||||
Statement [7] (byte~) main::$0 ← stackpull(byte) [ main::$0 ] ( main:2 [ main::$0 ] ) always clobbers reg byte a
|
||||
Statement [10] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:5 [ plus::a#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement [11] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:5 [ plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement [12] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 [ plus::return#0 ] ( main:2::plus:5 [ plus::return#0 ] ) always clobbers reg byte a
|
||||
Statement [13] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 [ ] ( main:2::plus:5 [ ] ) always clobbers reg byte x
|
||||
Potential registers zp[1]:2 [ main::$0 ] : zp[1]:2 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:3 [ plus::a#0 ] : zp[1]:3 , reg byte y ,
|
||||
Potential registers zp[1]:4 [ plus::b#0 ] : zp[1]:4 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:5 [ plus::return#0 ] : zp[1]:5 , reg byte a , reg byte x , reg byte y ,
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [plus] 4: zp[1]:4 [ plus::b#0 ] 2: zp[1]:3 [ plus::a#0 ] 2: zp[1]:5 [ plus::return#0 ]
|
||||
Uplift Scope [main] 2: zp[1]:2 [ main::$0 ]
|
||||
Uplift Scope [plus] 4: zp[1]:4 [ plus::b#0 ] 4: zp[1]:5 [ plus::return#0 ] 2: zp[1]:3 [ plus::a#0 ]
|
||||
Uplift Scope [main] 4: zp[1]:2 [ main::$0 ]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [plus] best 91 combination reg byte a [ plus::b#0 ] zp[1]:3 [ plus::a#0 ] reg byte a [ plus::return#0 ]
|
||||
Uplifting [plus] best 91 combination reg byte a [ plus::b#0 ] reg byte a [ plus::return#0 ] zp[1]:3 [ plus::a#0 ]
|
||||
Uplifting [main] best 85 combination reg byte a [ main::$0 ]
|
||||
Uplifting [] best 85 combination
|
||||
Attempting to uplift remaining variables inzp[1]:3 [ plus::a#0 ]
|
||||
@ -301,16 +308,16 @@ main: {
|
||||
pha
|
||||
// [5] callexecute plus -- jsr
|
||||
jsr plus
|
||||
// [6] (byte~) main::$0 ← callfinalize plus -- _stackpullbyte_1
|
||||
// stackpull((number) 1) -- _stackpullbyte_1
|
||||
pla
|
||||
// [6] (byte~) main::$0 ← callfinalize plus -- vbuaa=_stackpullbyte_
|
||||
// [7] (byte~) main::$0 ← stackpull(byte) -- vbuaa=_stackpullbyte_
|
||||
pla
|
||||
// [7] *((const byte*) SCREEN) ← (byte~) main::$0 -- _deref_pbuc1=vbuaa
|
||||
// [8] *((const byte*) SCREEN) ← (byte~) main::$0 -- _deref_pbuc1=vbuaa
|
||||
sta SCREEN
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [8] return
|
||||
// [9] return
|
||||
rts
|
||||
}
|
||||
// plus
|
||||
@ -320,23 +327,23 @@ plus: {
|
||||
.const OFFSET_STACK_B = 0
|
||||
.const OFFSET_STACK_RETURN = 1
|
||||
.label a = 2
|
||||
// [9] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1
|
||||
// [10] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_A,x
|
||||
sta.z a
|
||||
// [10] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuaa=_stackidxbyte_vbuc1
|
||||
// [11] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuaa=_stackidxbyte_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_B,x
|
||||
// [11] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuaa=vbuz1_plus_vbuaa
|
||||
// [12] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuaa=vbuz1_plus_vbuaa
|
||||
clc
|
||||
adc.z a
|
||||
jmp __breturn
|
||||
// plus::@return
|
||||
__breturn:
|
||||
// [12] return (byte) plus::return#0
|
||||
// [12] return (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuaa
|
||||
// [13] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuaa
|
||||
tsx
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN,x
|
||||
// [14] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
@ -368,7 +375,7 @@ FINAL SYMBOL TABLE
|
||||
(const byte*) SCREEN = (byte*) 1024
|
||||
(const word) STACK_BASE = (word) $103
|
||||
(void()) main()
|
||||
(byte~) main::$0 reg byte a 2.0
|
||||
(byte~) main::$0 reg byte a 4.0
|
||||
(label) main::@return
|
||||
__stackcall (byte()) plus((byte) plus::a , (byte) plus::b)
|
||||
(label) plus::@return
|
||||
@ -380,7 +387,7 @@ __stackcall (byte()) plus((byte) plus::a , (byte) plus::b)
|
||||
(byte) plus::b
|
||||
(byte) plus::b#0 reg byte a 4.0
|
||||
(byte) plus::return
|
||||
(byte) plus::return#0 reg byte a 2.0
|
||||
(byte) plus::return#0 reg byte a 4.0
|
||||
|
||||
reg byte a [ main::$0 ]
|
||||
zp[1]:2 [ plus::a#0 ]
|
||||
@ -417,16 +424,16 @@ main: {
|
||||
pha
|
||||
// [5] callexecute plus -- jsr
|
||||
jsr plus
|
||||
// [6] (byte~) main::$0 ← callfinalize plus -- _stackpullbyte_1
|
||||
// stackpull((number) 1) -- _stackpullbyte_1
|
||||
pla
|
||||
// [6] (byte~) main::$0 ← callfinalize plus -- vbuaa=_stackpullbyte_
|
||||
// [7] (byte~) main::$0 ← stackpull(byte) -- vbuaa=_stackpullbyte_
|
||||
pla
|
||||
// SCREEN[0] = plus('0', 7)
|
||||
// [7] *((const byte*) SCREEN) ← (byte~) main::$0 -- _deref_pbuc1=vbuaa
|
||||
// [8] *((const byte*) SCREEN) ← (byte~) main::$0 -- _deref_pbuc1=vbuaa
|
||||
sta SCREEN
|
||||
// main::@return
|
||||
// }
|
||||
// [8] return
|
||||
// [9] return
|
||||
rts
|
||||
}
|
||||
// plus
|
||||
@ -436,23 +443,23 @@ plus: {
|
||||
.const OFFSET_STACK_B = 0
|
||||
.const OFFSET_STACK_RETURN = 1
|
||||
.label a = 2
|
||||
// [9] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1
|
||||
// [10] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_A,x
|
||||
sta.z a
|
||||
// [10] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuaa=_stackidxbyte_vbuc1
|
||||
// [11] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuaa=_stackidxbyte_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_B,x
|
||||
// return a+b;
|
||||
// [11] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuaa=vbuz1_plus_vbuaa
|
||||
// [12] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuaa=vbuz1_plus_vbuaa
|
||||
clc
|
||||
adc.z a
|
||||
// plus::@return
|
||||
// }
|
||||
// [12] return (byte) plus::return#0
|
||||
// [12] return (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuaa
|
||||
// [13] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuaa
|
||||
tsx
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN,x
|
||||
// [14] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
@ -4,7 +4,7 @@
|
||||
(const byte*) SCREEN = (byte*) 1024
|
||||
(const word) STACK_BASE = (word) $103
|
||||
(void()) main()
|
||||
(byte~) main::$0 reg byte a 2.0
|
||||
(byte~) main::$0 reg byte a 4.0
|
||||
(label) main::@return
|
||||
__stackcall (byte()) plus((byte) plus::a , (byte) plus::b)
|
||||
(label) plus::@return
|
||||
@ -16,7 +16,7 @@ __stackcall (byte()) plus((byte) plus::a , (byte) plus::b)
|
||||
(byte) plus::b
|
||||
(byte) plus::b#0 reg byte a 4.0
|
||||
(byte) plus::return
|
||||
(byte) plus::return#0 reg byte a 2.0
|
||||
(byte) plus::return#0 reg byte a 4.0
|
||||
|
||||
reg byte a [ main::$0 ]
|
||||
zp[1]:2 [ plus::a#0 ]
|
||||
|
@ -6,7 +6,6 @@
|
||||
.label SCREEN = $400
|
||||
.const OFFSET_STRUCT_POINT_Y = 1
|
||||
.const STACK_BASE = $103
|
||||
.const OFFSET_STRUCT_POINT_X = 0
|
||||
.label idx = 2
|
||||
__bbegin:
|
||||
// idx = 0
|
||||
@ -43,8 +42,7 @@ print: {
|
||||
// get(byte register(X) i)
|
||||
get: {
|
||||
.const OFFSET_STACK_I = 0
|
||||
.const OFFSET_STACK_RETURN = 0
|
||||
.label p = 8
|
||||
.label p = 6
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_I,x
|
||||
tax
|
||||
@ -55,21 +53,19 @@ get: {
|
||||
stx.z p
|
||||
sta p+OFFSET_STRUCT_POINT_Y
|
||||
// return p;
|
||||
txa
|
||||
ldy p+OFFSET_STRUCT_POINT_Y
|
||||
tay
|
||||
// }
|
||||
txa
|
||||
tsx
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN+OFFSET_STRUCT_POINT_X,x
|
||||
sta STACK_BASE+0,x
|
||||
tya
|
||||
tsx
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN+OFFSET_STRUCT_POINT_Y,x
|
||||
sta STACK_BASE+OFFSET_STRUCT_POINT_Y,x
|
||||
rts
|
||||
}
|
||||
main: {
|
||||
.label i = 3
|
||||
.label p = 6
|
||||
.label __1_x = 4
|
||||
.label __1_y = 5
|
||||
.label p = 4
|
||||
// i=0
|
||||
lda #0
|
||||
sta.z i
|
||||
@ -87,16 +83,13 @@ main: {
|
||||
pha
|
||||
jsr get
|
||||
pla
|
||||
sta.z __1_x
|
||||
tax
|
||||
pla
|
||||
sta.z __1_y
|
||||
// p = get(i)
|
||||
lda.z __1_x
|
||||
sta.z p
|
||||
lda.z __1_y
|
||||
stx.z p
|
||||
sta p+OFFSET_STRUCT_POINT_Y
|
||||
// print(p)
|
||||
lda.z p
|
||||
txa
|
||||
pha
|
||||
lda p+OFFSET_STRUCT_POINT_Y
|
||||
pha
|
||||
|
@ -4,55 +4,57 @@
|
||||
@1: scope:[] from @begin
|
||||
[1] callprepare main
|
||||
[2] callexecute main
|
||||
[3] callfinalize main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[4] phi()
|
||||
[3] phi()
|
||||
|
||||
__stackcall (void()) print((byte) print::p_x , (byte) print::p_y)
|
||||
print: scope:[print] from
|
||||
[5] (byte) print::p_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_X)
|
||||
[6] (byte) print::p_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_Y)
|
||||
[7] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_x#0
|
||||
[8] (byte) idx ← ++ (byte) idx
|
||||
[9] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_y#0
|
||||
[10] (byte) idx ← ++ (byte) idx
|
||||
[4] (byte) print::p_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_X)
|
||||
[5] (byte) print::p_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_Y)
|
||||
[6] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_x#0
|
||||
[7] (byte) idx ← ++ (byte) idx
|
||||
[8] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_y#0
|
||||
[9] (byte) idx ← ++ (byte) idx
|
||||
to:print::@return
|
||||
print::@return: scope:[print] from print
|
||||
[11] return
|
||||
[10] return
|
||||
to:@return
|
||||
|
||||
__stackcall (struct Point()) get((byte) get::i)
|
||||
get: scope:[get] from
|
||||
[12] (byte) get::i#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I)
|
||||
[13] (byte~) get::$0 ← (byte) get::i#0 >> (byte) 1
|
||||
[14] *((byte*)&(struct Point) get::p) ← (byte) get::i#0
|
||||
[15] *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) get::$0
|
||||
[16] (byte) get::return_x#0 ← *((byte*)&(struct Point) get::p)
|
||||
[17] (byte) get::return_y#0 ← *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_Y)
|
||||
[11] (byte) get::i#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I)
|
||||
[12] (byte~) get::$0 ← (byte) get::i#0 >> (byte) 1
|
||||
[13] *((byte*)&(struct Point) get::p) ← (byte) get::i#0
|
||||
[14] *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) get::$0
|
||||
[15] (byte) get::return_x#0 ← *((byte*)&(struct Point) get::p)
|
||||
[16] (byte) get::return_y#0 ← *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_Y)
|
||||
to:get::@return
|
||||
get::@return: scope:[get] from get
|
||||
[18] return { (byte) get::return_x#0, (byte) get::return_y#0 }
|
||||
[17] stackidx(byte,(byte) 0) ← (byte) get::return_x#0
|
||||
[18] stackidx(byte,(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_y#0
|
||||
[19] return
|
||||
to:@return
|
||||
|
||||
__stackcall (void()) main()
|
||||
main: scope:[main] from
|
||||
[19] (byte) main::i ← (byte) 0
|
||||
[20] (byte) main::i ← (byte) 0
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@2
|
||||
[20] if((byte) main::i<(byte) 5) goto main::@2
|
||||
[21] if((byte) main::i<(byte) 5) goto main::@2
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[21] return
|
||||
[22] return
|
||||
to:@return
|
||||
main::@2: scope:[main] from main::@1
|
||||
[22] callprepare get (byte) main::i
|
||||
[23] callexecute get
|
||||
[24] { (byte~) main::$1_x, (byte~) main::$1_y } ← callfinalize get
|
||||
[25] *((byte*)&(struct Point) main::p) ← (byte~) main::$1_x
|
||||
[26] *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_y
|
||||
[27] callprepare print *((byte*)&(struct Point) main::p) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y)
|
||||
[28] callexecute print
|
||||
[29] callfinalize print
|
||||
[30] (byte) main::i ← ++ (byte) main::i
|
||||
[23] callprepare get (byte) main::i
|
||||
[24] callexecute get
|
||||
[25] (byte~) main::$1_x ← stackpull(byte)
|
||||
[26] (byte~) main::$1_y ← stackpull(byte)
|
||||
[27] *((byte*)&(struct Point) main::p) ← (byte~) main::$1_x
|
||||
[28] *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_y
|
||||
[29] callprepare print *((byte*)&(struct Point) main::p) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y)
|
||||
[30] callexecute print
|
||||
stackpull((number) 2)
|
||||
[32] (byte) main::i ← ++ (byte) main::i
|
||||
to:main::@1
|
||||
|
@ -39,6 +39,10 @@ Calling convention STACK_CALL adding prepare/execute/finalize for call main
|
||||
Calling convention STACK_CALL replacing param((byte) get::i) with stackidx(byte,(const byte) get::OFFSET_STACK_I)
|
||||
Calling convention STACK_CALL replacing param((byte) print::p_x) with stackidx(byte,(const byte) print::OFFSET_STACK_P_X)
|
||||
Calling convention STACK_CALL replacing param((byte) print::p_y) with stackidx(byte,(const byte) print::OFFSET_STACK_P_Y)
|
||||
Calling convention STACK_CALL adding stack return stackidx(byte,get::OFFSET_STACK_RETURN+OFFSET_STRUCT_POINT_X) ← get::return_x
|
||||
Calling convention STACK_CALL adding stack return stackidx(byte,get::OFFSET_STACK_RETURN+OFFSET_STRUCT_POINT_Y) ← get::return_y
|
||||
Calling convention STACK_CALL adding stack pull main::$1_x ← stackpull(byte)
|
||||
Calling convention STACK_CALL adding stack pull main::$1_y ← stackpull(byte)
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
@begin: scope:[] from
|
||||
@ -56,13 +60,14 @@ main::@1: scope:[main] from main main::@2
|
||||
main::@2: scope:[main] from main::@1
|
||||
callprepare get (byte) main::i
|
||||
callexecute get
|
||||
{ (byte~) main::$1_x, (byte~) main::$1_y } ← callfinalize get
|
||||
(byte~) main::$1_x ← stackpull(byte)
|
||||
(byte~) main::$1_y ← stackpull(byte)
|
||||
*((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_X) ← (byte~) main::$1_x
|
||||
*((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_y
|
||||
(struct Point) main::p ← struct-unwound {*((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y)}
|
||||
callprepare print *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_X) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y)
|
||||
callexecute print
|
||||
callfinalize print
|
||||
stackpull((number) 2)
|
||||
(byte) main::i ← ++ (byte) main::i
|
||||
to:main::@1
|
||||
main::@return: scope:[main] from main::@1
|
||||
@ -83,7 +88,9 @@ get: scope:[get] from
|
||||
get::@return: scope:[get] from get
|
||||
(byte) get::return_y#1 ← phi( get/(byte) get::return_y#0 )
|
||||
(byte) get::return_x#1 ← phi( get/(byte) get::return_x#0 )
|
||||
return { (byte) get::return_x#1, (byte) get::return_y#1 }
|
||||
stackidx(byte,(const byte) get::OFFSET_STACK_RETURN+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) get::return_x#1
|
||||
stackidx(byte,(const byte) get::OFFSET_STACK_RETURN+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_y#1
|
||||
return
|
||||
to:@return
|
||||
|
||||
__stackcall (void()) print((byte) print::p_x , (byte) print::p_y)
|
||||
@ -101,7 +108,6 @@ print::@return: scope:[print] from print
|
||||
@3: scope:[] from @begin
|
||||
callprepare main
|
||||
callexecute main
|
||||
callfinalize main
|
||||
to:@end
|
||||
@end: scope:[] from @3
|
||||
|
||||
@ -167,23 +173,26 @@ Alias (byte) get::return_y#0 = (byte) get::return_y#1
|
||||
Successful SSA optimization Pass2AliasElimination
|
||||
Simple Condition (bool~) main::$0 [3] if((byte) main::i<(byte) 5) goto main::@2
|
||||
Successful SSA optimization Pass2ConditionalJumpSimplification
|
||||
Removing C-classic struct-unwound assignment [9] (struct Point) main::p ← struct-unwound {*((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y)}
|
||||
Removing C-classic struct-unwound assignment [19] (struct Point) get::p ← struct-unwound {*((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_Y)}
|
||||
Simplifying expression containing zero (byte*)&main::p in [7] *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_X) ← (byte~) main::$1_x
|
||||
Simplifying expression containing zero (byte*)&main::p in [10] callprepare print *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_X) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y)
|
||||
Simplifying expression containing zero (byte*)&get::p in [17] *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) get::i#0
|
||||
Simplifying expression containing zero (byte*)&get::p in [20] (byte) get::return_x#0 ← *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_X)
|
||||
Removing C-classic struct-unwound assignment [10] (struct Point) main::p ← struct-unwound {*((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y)}
|
||||
Removing C-classic struct-unwound assignment [20] (struct Point) get::p ← struct-unwound {*((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_X), *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_Y)}
|
||||
Simplifying constant evaluating to zero (const byte) get::OFFSET_STACK_RETURN+(const byte) OFFSET_STRUCT_POINT_X in [24] stackidx(byte,(const byte) get::OFFSET_STACK_RETURN+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) get::return_x#0
|
||||
Successful SSA optimization PassNSimplifyConstantZero
|
||||
Simplifying expression containing zero (byte*)&main::p in [8] *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_X) ← (byte~) main::$1_x
|
||||
Simplifying expression containing zero (byte*)&main::p in [11] callprepare print *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_X) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y)
|
||||
Simplifying expression containing zero (byte*)&get::p in [18] *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_X) ← (byte) get::i#0
|
||||
Simplifying expression containing zero (byte*)&get::p in [21] (byte) get::return_x#0 ← *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_X)
|
||||
Simplifying expression containing zero OFFSET_STRUCT_POINT_Y in [25] stackidx(byte,(const byte) get::OFFSET_STACK_RETURN+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_y#0
|
||||
Successful SSA optimization PassNSimplifyExpressionWithZero
|
||||
Eliminating unused variable (struct Point) get::return#0 and assignment [19] (struct Point) get::return#0 ← struct-unwound {(byte) get::return_x#0, (byte) get::return_y#0}
|
||||
Eliminating unused variable (struct Point) get::return#0 and assignment [20] (struct Point) get::return#0 ← struct-unwound {(byte) get::return_x#0, (byte) get::return_y#0}
|
||||
Eliminating unused constant (const byte) get::OFFSET_STACK_RETURN
|
||||
Eliminating unused constant (const byte) OFFSET_STRUCT_POINT_X
|
||||
Successful SSA optimization PassNEliminateUnusedVars
|
||||
Rewriting division to use shift [14] (byte~) get::$0 ← (byte) get::i#0 / (byte) 2
|
||||
Rewriting division to use shift [15] (byte~) get::$0 ← (byte) get::i#0 / (byte) 2
|
||||
Successful SSA optimization Pass2MultiplyToShiftRewriting
|
||||
Adding NOP phi() at start of @end
|
||||
CALL GRAPH
|
||||
Calls in [] to main:2
|
||||
Calls in [main] to get:23 print:28
|
||||
Calls in [main] to get:24 print:30
|
||||
|
||||
Created 0 initial phi equivalence classes
|
||||
Coalesced down to 0 phi equivalence classes
|
||||
@ -197,57 +206,59 @@ FINAL CONTROL FLOW GRAPH
|
||||
@1: scope:[] from @begin
|
||||
[1] callprepare main
|
||||
[2] callexecute main
|
||||
[3] callfinalize main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[4] phi()
|
||||
[3] phi()
|
||||
|
||||
__stackcall (void()) print((byte) print::p_x , (byte) print::p_y)
|
||||
print: scope:[print] from
|
||||
[5] (byte) print::p_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_X)
|
||||
[6] (byte) print::p_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_Y)
|
||||
[7] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_x#0
|
||||
[8] (byte) idx ← ++ (byte) idx
|
||||
[9] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_y#0
|
||||
[10] (byte) idx ← ++ (byte) idx
|
||||
[4] (byte) print::p_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_X)
|
||||
[5] (byte) print::p_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_Y)
|
||||
[6] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_x#0
|
||||
[7] (byte) idx ← ++ (byte) idx
|
||||
[8] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_y#0
|
||||
[9] (byte) idx ← ++ (byte) idx
|
||||
to:print::@return
|
||||
print::@return: scope:[print] from print
|
||||
[11] return
|
||||
[10] return
|
||||
to:@return
|
||||
|
||||
__stackcall (struct Point()) get((byte) get::i)
|
||||
get: scope:[get] from
|
||||
[12] (byte) get::i#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I)
|
||||
[13] (byte~) get::$0 ← (byte) get::i#0 >> (byte) 1
|
||||
[14] *((byte*)&(struct Point) get::p) ← (byte) get::i#0
|
||||
[15] *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) get::$0
|
||||
[16] (byte) get::return_x#0 ← *((byte*)&(struct Point) get::p)
|
||||
[17] (byte) get::return_y#0 ← *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_Y)
|
||||
[11] (byte) get::i#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I)
|
||||
[12] (byte~) get::$0 ← (byte) get::i#0 >> (byte) 1
|
||||
[13] *((byte*)&(struct Point) get::p) ← (byte) get::i#0
|
||||
[14] *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) get::$0
|
||||
[15] (byte) get::return_x#0 ← *((byte*)&(struct Point) get::p)
|
||||
[16] (byte) get::return_y#0 ← *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_Y)
|
||||
to:get::@return
|
||||
get::@return: scope:[get] from get
|
||||
[18] return { (byte) get::return_x#0, (byte) get::return_y#0 }
|
||||
[17] stackidx(byte,(byte) 0) ← (byte) get::return_x#0
|
||||
[18] stackidx(byte,(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_y#0
|
||||
[19] return
|
||||
to:@return
|
||||
|
||||
__stackcall (void()) main()
|
||||
main: scope:[main] from
|
||||
[19] (byte) main::i ← (byte) 0
|
||||
[20] (byte) main::i ← (byte) 0
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@2
|
||||
[20] if((byte) main::i<(byte) 5) goto main::@2
|
||||
[21] if((byte) main::i<(byte) 5) goto main::@2
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[21] return
|
||||
[22] return
|
||||
to:@return
|
||||
main::@2: scope:[main] from main::@1
|
||||
[22] callprepare get (byte) main::i
|
||||
[23] callexecute get
|
||||
[24] { (byte~) main::$1_x, (byte~) main::$1_y } ← callfinalize get
|
||||
[25] *((byte*)&(struct Point) main::p) ← (byte~) main::$1_x
|
||||
[26] *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_y
|
||||
[27] callprepare print *((byte*)&(struct Point) main::p) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y)
|
||||
[28] callexecute print
|
||||
[29] callfinalize print
|
||||
[30] (byte) main::i ← ++ (byte) main::i
|
||||
[23] callprepare get (byte) main::i
|
||||
[24] callexecute get
|
||||
[25] (byte~) main::$1_x ← stackpull(byte)
|
||||
[26] (byte~) main::$1_y ← stackpull(byte)
|
||||
[27] *((byte*)&(struct Point) main::p) ← (byte~) main::$1_x
|
||||
[28] *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_y
|
||||
[29] callprepare print *((byte*)&(struct Point) main::p) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y)
|
||||
[30] callexecute print
|
||||
stackpull((number) 2)
|
||||
[32] (byte) main::i ← ++ (byte) main::i
|
||||
to:main::@1
|
||||
|
||||
null depth in calling loop Loop head: main::@1 tails: main::@2 blocks: main::@2 main::@1 in scope print
|
||||
@ -263,14 +274,14 @@ __stackcall (struct Point()) get((byte) get::i)
|
||||
(struct Point) get::p loadstore
|
||||
(struct Point) get::return
|
||||
(byte) get::return_x
|
||||
(byte) get::return_x#0 1.0
|
||||
(byte) get::return_x#0 2.0
|
||||
(byte) get::return_y
|
||||
(byte) get::return_y#0 2.0
|
||||
(byte) idx loadstore 0.7
|
||||
(byte) idx loadstore 0.6666666666666666
|
||||
__stackcall (void()) main()
|
||||
(byte~) main::$1_x 0.8461538461538461
|
||||
(byte~) main::$1_y 0.8461538461538461
|
||||
(byte) main::i loadstore 3.1818181818181817
|
||||
(byte~) main::$1_x 11.0
|
||||
(byte~) main::$1_y 11.0
|
||||
(byte) main::i loadstore 2.9166666666666665
|
||||
(struct Point) main::p loadstore
|
||||
__stackcall (void()) print((byte) print::p_x , (byte) print::p_y)
|
||||
(byte) print::p_x
|
||||
@ -342,8 +353,7 @@ __b1:
|
||||
// [1] callprepare main
|
||||
// [2] callexecute main -- jsr
|
||||
jsr main
|
||||
// [3] callfinalize main
|
||||
// [4] phi from @1 to @end [phi:@1->@end]
|
||||
// [3] phi from @1 to @end [phi:@1->@end]
|
||||
__bend_from___b1:
|
||||
jmp __bend
|
||||
// @end
|
||||
@ -355,30 +365,30 @@ print: {
|
||||
.const OFFSET_STACK_P_Y = 0
|
||||
.label p_x = 3
|
||||
.label p_y = 4
|
||||
// [5] (byte) print::p_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_X) -- vbuz1=_stackidxbyte_vbuc1
|
||||
// [4] (byte) print::p_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_X) -- vbuz1=_stackidxbyte_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_P_X,x
|
||||
sta.z p_x
|
||||
// [6] (byte) print::p_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_Y) -- vbuz1=_stackidxbyte_vbuc1
|
||||
// [5] (byte) print::p_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_Y) -- vbuz1=_stackidxbyte_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_P_Y,x
|
||||
sta.z p_y
|
||||
// [7] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_x#0 -- pbuc1_derefidx_vbuz1=vbuz2
|
||||
// [6] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_x#0 -- pbuc1_derefidx_vbuz1=vbuz2
|
||||
lda.z p_x
|
||||
ldy.z idx
|
||||
sta SCREEN,y
|
||||
// [8] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1
|
||||
// [7] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1
|
||||
inc.z idx
|
||||
// [9] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_y#0 -- pbuc1_derefidx_vbuz1=vbuz2
|
||||
// [8] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_y#0 -- pbuc1_derefidx_vbuz1=vbuz2
|
||||
lda.z p_y
|
||||
ldy.z idx
|
||||
sta SCREEN,y
|
||||
// [10] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1
|
||||
// [9] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1
|
||||
inc.z idx
|
||||
jmp __breturn
|
||||
// print::@return
|
||||
__breturn:
|
||||
// [11] return
|
||||
// [10] return
|
||||
rts
|
||||
}
|
||||
// get
|
||||
@ -390,38 +400,38 @@ get: {
|
||||
.label i = 5
|
||||
.label return_x = 7
|
||||
.label return_y = 8
|
||||
// [12] (byte) get::i#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I) -- vbuz1=_stackidxbyte_vbuc1
|
||||
// [11] (byte) get::i#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I) -- vbuz1=_stackidxbyte_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_I,x
|
||||
sta.z i
|
||||
// [13] (byte~) get::$0 ← (byte) get::i#0 >> (byte) 1 -- vbuz1=vbuz2_ror_1
|
||||
// [12] (byte~) get::$0 ← (byte) get::i#0 >> (byte) 1 -- vbuz1=vbuz2_ror_1
|
||||
lda.z i
|
||||
lsr
|
||||
sta.z __0
|
||||
// [14] *((byte*)&(struct Point) get::p) ← (byte) get::i#0 -- _deref_pbuc1=vbuz1
|
||||
// [13] *((byte*)&(struct Point) get::p) ← (byte) get::i#0 -- _deref_pbuc1=vbuz1
|
||||
lda.z i
|
||||
sta.z p
|
||||
// [15] *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) get::$0 -- _deref_pbuc1=vbuz1
|
||||
// [14] *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) get::$0 -- _deref_pbuc1=vbuz1
|
||||
lda.z __0
|
||||
sta p+OFFSET_STRUCT_POINT_Y
|
||||
// [16] (byte) get::return_x#0 ← *((byte*)&(struct Point) get::p) -- vbuz1=_deref_pbuc1
|
||||
// [15] (byte) get::return_x#0 ← *((byte*)&(struct Point) get::p) -- vbuz1=_deref_pbuc1
|
||||
lda.z p
|
||||
sta.z return_x
|
||||
// [17] (byte) get::return_y#0 ← *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_Y) -- vbuz1=_deref_pbuc1
|
||||
// [16] (byte) get::return_y#0 ← *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_Y) -- vbuz1=_deref_pbuc1
|
||||
lda p+OFFSET_STRUCT_POINT_Y
|
||||
sta.z return_y
|
||||
jmp __breturn
|
||||
// get::@return
|
||||
__breturn:
|
||||
// [18] return { (byte) get::return_x#0, (byte) get::return_y#0 }
|
||||
// [18] return { (byte) get::return_x#0, (byte) get::return_y#0 } [(byte) Point::x#0] -- _stackidxbyte_vbuc1=vbuz1
|
||||
// [17] stackidx(byte,(byte) 0) ← (byte) get::return_x#0 -- _stackidxbyte_vbuc1=vbuz1
|
||||
lda.z return_x
|
||||
tsx
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN+OFFSET_STRUCT_POINT_X,x
|
||||
// [18] return { (byte) get::return_x#0, (byte) get::return_y#0 } [(byte) Point::y#1] -- _stackidxbyte_vbuc1=vbuz1
|
||||
sta STACK_BASE+0,x
|
||||
// [18] stackidx(byte,(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_y#0 -- _stackidxbyte_vbuc1=vbuz1
|
||||
lda.z return_y
|
||||
tsx
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN+OFFSET_STRUCT_POINT_Y,x
|
||||
sta STACK_BASE+OFFSET_STRUCT_POINT_Y,x
|
||||
// [19] return
|
||||
rts
|
||||
}
|
||||
// main
|
||||
@ -430,142 +440,134 @@ main: {
|
||||
.label p = $c
|
||||
.label __1_x = $a
|
||||
.label __1_y = $b
|
||||
// [19] (byte) main::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
// [20] (byte) main::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z i
|
||||
jmp __b1
|
||||
// main::@1
|
||||
__b1:
|
||||
// [20] if((byte) main::i<(byte) 5) goto main::@2 -- vbuz1_lt_vbuc1_then_la1
|
||||
// [21] if((byte) main::i<(byte) 5) goto main::@2 -- vbuz1_lt_vbuc1_then_la1
|
||||
lda.z i
|
||||
cmp #5
|
||||
bcc __b2
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [21] return
|
||||
// [22] return
|
||||
rts
|
||||
// main::@2
|
||||
__b2:
|
||||
// [22] callprepare get (byte) main::i [(byte) get::i#0] -- _stackpushbyte_=vbuz1
|
||||
// [23] callprepare get (byte) main::i [(byte) get::i#0] -- _stackpushbyte_=vbuz1
|
||||
lda.z i
|
||||
pha
|
||||
// [22] callprepare get (byte) main::i -- _stackpushbyte_1
|
||||
// [23] callprepare get (byte) main::i -- _stackpushbyte_1
|
||||
pha
|
||||
// [23] callexecute get -- jsr
|
||||
// [24] callexecute get -- jsr
|
||||
jsr get
|
||||
// [24] { (byte~) main::$1_x, (byte~) main::$1_y } ← callfinalize get [(byte) Point::x#0] -- vbuz1=_stackpullbyte_
|
||||
// [25] (byte~) main::$1_x ← stackpull(byte) -- vbuz1=_stackpullbyte_
|
||||
pla
|
||||
sta.z __1_x
|
||||
// [24] { (byte~) main::$1_x, (byte~) main::$1_y } ← callfinalize get [(byte) Point::y#1] -- vbuz1=_stackpullbyte_
|
||||
// [26] (byte~) main::$1_y ← stackpull(byte) -- vbuz1=_stackpullbyte_
|
||||
pla
|
||||
sta.z __1_y
|
||||
// [25] *((byte*)&(struct Point) main::p) ← (byte~) main::$1_x -- _deref_pbuc1=vbuz1
|
||||
// [27] *((byte*)&(struct Point) main::p) ← (byte~) main::$1_x -- _deref_pbuc1=vbuz1
|
||||
lda.z __1_x
|
||||
sta.z p
|
||||
// [26] *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_y -- _deref_pbuc1=vbuz1
|
||||
// [28] *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_y -- _deref_pbuc1=vbuz1
|
||||
lda.z __1_y
|
||||
sta p+OFFSET_STRUCT_POINT_Y
|
||||
// [27] callprepare print *((byte*)&(struct Point) main::p) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) [(byte) print::p_x#0] -- _stackpushbyte_=_deref_pbuc1
|
||||
// [29] callprepare print *((byte*)&(struct Point) main::p) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) [(byte) print::p_x#0] -- _stackpushbyte_=_deref_pbuc1
|
||||
lda.z p
|
||||
pha
|
||||
// [27] callprepare print *((byte*)&(struct Point) main::p) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) [(byte) print::p_y#1] -- _stackpushbyte_=_deref_pbuc1
|
||||
// [29] callprepare print *((byte*)&(struct Point) main::p) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) [(byte) print::p_y#1] -- _stackpushbyte_=_deref_pbuc1
|
||||
lda p+OFFSET_STRUCT_POINT_Y
|
||||
pha
|
||||
// [28] callexecute print -- jsr
|
||||
// [30] callexecute print -- jsr
|
||||
jsr print
|
||||
// [29] callfinalize print -- _stackpullbyte_2
|
||||
// stackpull((number) 2) -- _stackpullbyte_2
|
||||
pla
|
||||
pla
|
||||
// [30] (byte) main::i ← ++ (byte) main::i -- vbuz1=_inc_vbuz1
|
||||
// [32] (byte) main::i ← ++ (byte) main::i -- vbuz1=_inc_vbuz1
|
||||
inc.z i
|
||||
jmp __b1
|
||||
}
|
||||
// File Data
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Statement [0] (byte) idx ← (byte) 0 [ idx get::p main::$1_x main::$1_y main::p ] ( [ idx get::p main::$1_x main::$1_y main::p ] ) always clobbers reg byte a
|
||||
Removing always clobbered register reg byte a as potential for zp[1]:10 [ main::$1_x ]
|
||||
Removing always clobbered register reg byte a as potential for zp[1]:11 [ main::$1_y ]
|
||||
Statement [5] (byte) print::p_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_X) [ idx print::p_x#0 ] ( main:2::print:28 [ get::p main::i main::$1_x main::$1_y main::p idx print::p_x#0 ] ) always clobbers reg byte a reg byte x
|
||||
Removing always clobbered register reg byte x as potential for zp[1]:10 [ main::$1_x ]
|
||||
Removing always clobbered register reg byte x as potential for zp[1]:11 [ main::$1_y ]
|
||||
Statement [6] (byte) print::p_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_Y) [ idx print::p_x#0 print::p_y#0 ] ( main:2::print:28 [ get::p main::i main::$1_x main::$1_y main::p idx print::p_x#0 print::p_y#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement [0] (byte) idx ← (byte) 0 [ idx get::p main::p ] ( [ idx get::p main::p ] ) always clobbers reg byte a
|
||||
Statement [4] (byte) print::p_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_X) [ idx print::p_x#0 ] ( main:2::print:30 [ get::p main::i main::p idx print::p_x#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement [5] (byte) print::p_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_Y) [ idx print::p_x#0 print::p_y#0 ] ( main:2::print:30 [ get::p main::i main::p idx print::p_x#0 print::p_y#0 ] ) always clobbers reg byte a reg byte x
|
||||
Removing always clobbered register reg byte a as potential for zp[1]:3 [ print::p_x#0 ]
|
||||
Removing always clobbered register reg byte x as potential for zp[1]:3 [ print::p_x#0 ]
|
||||
Statement [7] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_x#0 [ idx print::p_y#0 ] ( main:2::print:28 [ get::p main::i main::$1_x main::$1_y main::p idx print::p_y#0 ] ) always clobbers reg byte a reg byte y
|
||||
Removing always clobbered register reg byte y as potential for zp[1]:10 [ main::$1_x ]
|
||||
Removing always clobbered register reg byte y as potential for zp[1]:11 [ main::$1_y ]
|
||||
Statement [6] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_x#0 [ idx print::p_y#0 ] ( main:2::print:30 [ get::p main::i main::p idx print::p_y#0 ] ) always clobbers reg byte a reg byte y
|
||||
Removing always clobbered register reg byte a as potential for zp[1]:4 [ print::p_y#0 ]
|
||||
Removing always clobbered register reg byte y as potential for zp[1]:4 [ print::p_y#0 ]
|
||||
Statement [9] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_y#0 [ idx ] ( main:2::print:28 [ get::p main::i main::$1_x main::$1_y main::p idx ] ) always clobbers reg byte a reg byte y
|
||||
Statement [12] (byte) get::i#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I) [ get::i#0 get::p ] ( main:2::get:23 [ idx main::i main::$1_x main::$1_y main::p get::i#0 get::p ] ) always clobbers reg byte a reg byte x
|
||||
Statement [13] (byte~) get::$0 ← (byte) get::i#0 >> (byte) 1 [ get::i#0 get::$0 get::p ] ( main:2::get:23 [ idx main::i main::$1_x main::$1_y main::p get::i#0 get::$0 get::p ] ) always clobbers reg byte a
|
||||
Statement [8] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_y#0 [ idx ] ( main:2::print:30 [ get::p main::i main::p idx ] ) always clobbers reg byte a reg byte y
|
||||
Statement [11] (byte) get::i#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I) [ get::i#0 get::p ] ( main:2::get:24 [ idx main::i main::p get::i#0 get::p ] ) always clobbers reg byte a reg byte x
|
||||
Statement [12] (byte~) get::$0 ← (byte) get::i#0 >> (byte) 1 [ get::i#0 get::$0 get::p ] ( main:2::get:24 [ idx main::i main::p get::i#0 get::$0 get::p ] ) always clobbers reg byte a
|
||||
Removing always clobbered register reg byte a as potential for zp[1]:5 [ get::i#0 ]
|
||||
Statement [18] return { (byte) get::return_x#0, (byte) get::return_y#0 } [ get::p ] ( main:2::get:23 [ idx main::i main::$1_x main::$1_y main::p get::p ] ) always clobbers reg byte x
|
||||
Statement [19] (byte) main::i ← (byte) 0 [ idx get::p main::i main::$1_x main::$1_y main::p ] ( main:2 [ idx get::p main::i main::$1_x main::$1_y main::p ] ) always clobbers reg byte a
|
||||
Statement [20] if((byte) main::i<(byte) 5) goto main::@2 [ idx get::p main::i main::$1_x main::$1_y main::p ] ( main:2 [ idx get::p main::i main::$1_x main::$1_y main::p ] ) always clobbers reg byte a
|
||||
Statement [22] callprepare get (byte) main::i [ idx get::p main::i main::$1_x main::$1_y main::p ] ( main:2 [ idx get::p main::i main::$1_x main::$1_y main::p ] ) always clobbers reg byte a
|
||||
Statement [24] { (byte~) main::$1_x, (byte~) main::$1_y } ← callfinalize get [ idx get::p main::i main::$1_x main::$1_y main::p ] ( main:2 [ idx get::p main::i main::$1_x main::$1_y main::p ] ) always clobbers reg byte a
|
||||
Statement [25] *((byte*)&(struct Point) main::p) ← (byte~) main::$1_x [ idx get::p main::i main::$1_x main::$1_y main::p ] ( main:2 [ idx get::p main::i main::$1_x main::$1_y main::p ] ) always clobbers reg byte a
|
||||
Statement [26] *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_y [ idx get::p main::i main::$1_x main::$1_y main::p ] ( main:2 [ idx get::p main::i main::$1_x main::$1_y main::p ] ) always clobbers reg byte a
|
||||
Statement [27] callprepare print *((byte*)&(struct Point) main::p) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) [ idx get::p main::i main::$1_x main::$1_y main::p ] ( main:2 [ idx get::p main::i main::$1_x main::$1_y main::p ] ) always clobbers reg byte a
|
||||
Statement [29] callfinalize print [ idx get::p main::i main::$1_x main::$1_y main::p ] ( main:2 [ idx get::p main::i main::$1_x main::$1_y main::p ] ) always clobbers reg byte a
|
||||
Statement [0] (byte) idx ← (byte) 0 [ idx get::p main::$1_x main::$1_y main::p ] ( [ idx get::p main::$1_x main::$1_y main::p ] ) always clobbers reg byte a
|
||||
Statement [5] (byte) print::p_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_X) [ idx print::p_x#0 ] ( main:2::print:28 [ get::p main::i main::$1_x main::$1_y main::p idx print::p_x#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement [6] (byte) print::p_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_Y) [ idx print::p_x#0 print::p_y#0 ] ( main:2::print:28 [ get::p main::i main::$1_x main::$1_y main::p idx print::p_x#0 print::p_y#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement [7] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_x#0 [ idx print::p_y#0 ] ( main:2::print:28 [ get::p main::i main::$1_x main::$1_y main::p idx print::p_y#0 ] ) always clobbers reg byte a reg byte y
|
||||
Statement [9] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_y#0 [ idx ] ( main:2::print:28 [ get::p main::i main::$1_x main::$1_y main::p idx ] ) always clobbers reg byte a reg byte y
|
||||
Statement [12] (byte) get::i#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I) [ get::i#0 get::p ] ( main:2::get:23 [ idx main::i main::$1_x main::$1_y main::p get::i#0 get::p ] ) always clobbers reg byte a reg byte x
|
||||
Statement [13] (byte~) get::$0 ← (byte) get::i#0 >> (byte) 1 [ get::i#0 get::$0 get::p ] ( main:2::get:23 [ idx main::i main::$1_x main::$1_y main::p get::i#0 get::$0 get::p ] ) always clobbers reg byte a
|
||||
Statement [18] return { (byte) get::return_x#0, (byte) get::return_y#0 } [ get::p ] ( main:2::get:23 [ idx main::i main::$1_x main::$1_y main::p get::p ] ) always clobbers reg byte x
|
||||
Statement [19] (byte) main::i ← (byte) 0 [ idx get::p main::i main::$1_x main::$1_y main::p ] ( main:2 [ idx get::p main::i main::$1_x main::$1_y main::p ] ) always clobbers reg byte a
|
||||
Statement [20] if((byte) main::i<(byte) 5) goto main::@2 [ idx get::p main::i main::$1_x main::$1_y main::p ] ( main:2 [ idx get::p main::i main::$1_x main::$1_y main::p ] ) always clobbers reg byte a
|
||||
Statement [22] callprepare get (byte) main::i [ idx get::p main::i main::$1_x main::$1_y main::p ] ( main:2 [ idx get::p main::i main::$1_x main::$1_y main::p ] ) always clobbers reg byte a
|
||||
Statement [24] { (byte~) main::$1_x, (byte~) main::$1_y } ← callfinalize get [ idx get::p main::i main::$1_x main::$1_y main::p ] ( main:2 [ idx get::p main::i main::$1_x main::$1_y main::p ] ) always clobbers reg byte a
|
||||
Statement [25] *((byte*)&(struct Point) main::p) ← (byte~) main::$1_x [ idx get::p main::i main::$1_x main::$1_y main::p ] ( main:2 [ idx get::p main::i main::$1_x main::$1_y main::p ] ) always clobbers reg byte a
|
||||
Statement [26] *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_y [ idx get::p main::i main::$1_x main::$1_y main::p ] ( main:2 [ idx get::p main::i main::$1_x main::$1_y main::p ] ) always clobbers reg byte a
|
||||
Statement [27] callprepare print *((byte*)&(struct Point) main::p) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) [ idx get::p main::i main::$1_x main::$1_y main::p ] ( main:2 [ idx get::p main::i main::$1_x main::$1_y main::p ] ) always clobbers reg byte a
|
||||
Statement [29] callfinalize print [ idx get::p main::i main::$1_x main::$1_y main::p ] ( main:2 [ idx get::p main::i main::$1_x main::$1_y main::p ] ) always clobbers reg byte a
|
||||
Statement [17] stackidx(byte,(byte) 0) ← (byte) get::return_x#0 [ get::p get::return_y#0 ] ( main:2::get:24 [ idx main::i main::p get::p get::return_y#0 ] ) always clobbers reg byte x
|
||||
Removing always clobbered register reg byte x as potential for zp[1]:8 [ get::return_y#0 ]
|
||||
Statement [18] stackidx(byte,(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_y#0 [ get::p ] ( main:2::get:24 [ idx main::i main::p get::p ] ) always clobbers reg byte x
|
||||
Statement [20] (byte) main::i ← (byte) 0 [ idx get::p main::i main::p ] ( main:2 [ idx get::p main::i main::p ] ) always clobbers reg byte a
|
||||
Statement [21] if((byte) main::i<(byte) 5) goto main::@2 [ idx get::p main::i main::p ] ( main:2 [ idx get::p main::i main::p ] ) always clobbers reg byte a
|
||||
Statement [23] callprepare get (byte) main::i [ idx get::p main::i main::p ] ( main:2 [ idx get::p main::i main::p ] ) always clobbers reg byte a
|
||||
Statement [25] (byte~) main::$1_x ← stackpull(byte) [ idx get::p main::i main::$1_x main::p ] ( main:2 [ idx get::p main::i main::$1_x main::p ] ) always clobbers reg byte a
|
||||
Statement [26] (byte~) main::$1_y ← stackpull(byte) [ idx get::p main::i main::$1_x main::$1_y main::p ] ( main:2 [ idx get::p main::i main::$1_x main::$1_y main::p ] ) always clobbers reg byte a
|
||||
Removing always clobbered register reg byte a as potential for zp[1]:10 [ main::$1_x ]
|
||||
Statement [29] callprepare print *((byte*)&(struct Point) main::p) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) [ idx get::p main::i main::p ] ( main:2 [ idx get::p main::i main::p ] ) always clobbers reg byte a
|
||||
Statement stackpull((number) 2) always clobbers reg byte a
|
||||
Statement [0] (byte) idx ← (byte) 0 [ idx get::p main::p ] ( [ idx get::p main::p ] ) always clobbers reg byte a
|
||||
Statement [4] (byte) print::p_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_X) [ idx print::p_x#0 ] ( main:2::print:30 [ get::p main::i main::p idx print::p_x#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement [5] (byte) print::p_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_Y) [ idx print::p_x#0 print::p_y#0 ] ( main:2::print:30 [ get::p main::i main::p idx print::p_x#0 print::p_y#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement [6] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_x#0 [ idx print::p_y#0 ] ( main:2::print:30 [ get::p main::i main::p idx print::p_y#0 ] ) always clobbers reg byte a reg byte y
|
||||
Statement [8] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_y#0 [ idx ] ( main:2::print:30 [ get::p main::i main::p idx ] ) always clobbers reg byte a reg byte y
|
||||
Statement [11] (byte) get::i#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I) [ get::i#0 get::p ] ( main:2::get:24 [ idx main::i main::p get::i#0 get::p ] ) always clobbers reg byte a reg byte x
|
||||
Statement [12] (byte~) get::$0 ← (byte) get::i#0 >> (byte) 1 [ get::i#0 get::$0 get::p ] ( main:2::get:24 [ idx main::i main::p get::i#0 get::$0 get::p ] ) always clobbers reg byte a
|
||||
Statement [17] stackidx(byte,(byte) 0) ← (byte) get::return_x#0 [ get::p get::return_y#0 ] ( main:2::get:24 [ idx main::i main::p get::p get::return_y#0 ] ) always clobbers reg byte x
|
||||
Statement [18] stackidx(byte,(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_y#0 [ get::p ] ( main:2::get:24 [ idx main::i main::p get::p ] ) always clobbers reg byte x
|
||||
Statement [20] (byte) main::i ← (byte) 0 [ idx get::p main::i main::p ] ( main:2 [ idx get::p main::i main::p ] ) always clobbers reg byte a
|
||||
Statement [21] if((byte) main::i<(byte) 5) goto main::@2 [ idx get::p main::i main::p ] ( main:2 [ idx get::p main::i main::p ] ) always clobbers reg byte a
|
||||
Statement [23] callprepare get (byte) main::i [ idx get::p main::i main::p ] ( main:2 [ idx get::p main::i main::p ] ) always clobbers reg byte a
|
||||
Statement [25] (byte~) main::$1_x ← stackpull(byte) [ idx get::p main::i main::$1_x main::p ] ( main:2 [ idx get::p main::i main::$1_x main::p ] ) always clobbers reg byte a
|
||||
Statement [26] (byte~) main::$1_y ← stackpull(byte) [ idx get::p main::i main::$1_x main::$1_y main::p ] ( main:2 [ idx get::p main::i main::$1_x main::$1_y main::p ] ) always clobbers reg byte a
|
||||
Statement [29] callprepare print *((byte*)&(struct Point) main::p) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) [ idx get::p main::i main::p ] ( main:2 [ idx get::p main::i main::p ] ) always clobbers reg byte a
|
||||
Statement stackpull((number) 2) always clobbers reg byte a
|
||||
Potential registers zp[1]:2 [ idx ] : zp[1]:2 ,
|
||||
Potential registers zp[1]:3 [ print::p_x#0 ] : zp[1]:3 , reg byte y ,
|
||||
Potential registers zp[1]:4 [ print::p_y#0 ] : zp[1]:4 , reg byte x ,
|
||||
Potential registers zp[1]:5 [ get::i#0 ] : zp[1]:5 , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:6 [ get::$0 ] : zp[1]:6 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:7 [ get::return_x#0 ] : zp[1]:7 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:8 [ get::return_y#0 ] : zp[1]:8 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:8 [ get::return_y#0 ] : zp[1]:8 , reg byte a , reg byte y ,
|
||||
Potential registers zp[1]:9 [ main::i ] : zp[1]:9 ,
|
||||
Potential registers zp[1]:10 [ main::$1_x ] : zp[1]:10 ,
|
||||
Potential registers zp[1]:11 [ main::$1_y ] : zp[1]:11 ,
|
||||
Potential registers zp[1]:10 [ main::$1_x ] : zp[1]:10 , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:11 [ main::$1_y ] : zp[1]:11 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp[2]:12 [ main::p ] : zp[2]:12 ,
|
||||
Potential registers zp[2]:14 [ get::p ] : zp[2]:14 ,
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [get] 3: zp[1]:5 [ get::i#0 ] 2: zp[1]:6 [ get::$0 ] 2: zp[1]:8 [ get::return_y#0 ] 1: zp[1]:7 [ get::return_x#0 ] 0: zp[2]:14 [ get::p ]
|
||||
Uplift Scope [main] 3.18: zp[1]:9 [ main::i ] 0.85: zp[1]:10 [ main::$1_x ] 0.85: zp[1]:11 [ main::$1_y ] 0: zp[2]:12 [ main::p ]
|
||||
Uplift Scope [main] 11: zp[1]:10 [ main::$1_x ] 11: zp[1]:11 [ main::$1_y ] 2.92: zp[1]:9 [ main::i ] 0: zp[2]:12 [ main::p ]
|
||||
Uplift Scope [get] 3: zp[1]:5 [ get::i#0 ] 2: zp[1]:6 [ get::$0 ] 2: zp[1]:7 [ get::return_x#0 ] 2: zp[1]:8 [ get::return_y#0 ] 0: zp[2]:14 [ get::p ]
|
||||
Uplift Scope [print] 2: zp[1]:3 [ print::p_x#0 ] 1.33: zp[1]:4 [ print::p_y#0 ]
|
||||
Uplift Scope [] 0.7: zp[1]:2 [ idx ]
|
||||
Uplift Scope [] 0.67: zp[1]:2 [ idx ]
|
||||
Uplift Scope [Point]
|
||||
|
||||
Uplifting [get] best 1016 combination reg byte x [ get::i#0 ] reg byte a [ get::$0 ] reg byte y [ get::return_y#0 ] reg byte a [ get::return_x#0 ] zp[2]:14 [ get::p ]
|
||||
Limited combination testing to 100 combinations of 192 possible.
|
||||
Uplifting [main] best 1016 combination zp[1]:9 [ main::i ] zp[1]:10 [ main::$1_x ] zp[1]:11 [ main::$1_y ] zp[2]:12 [ main::p ]
|
||||
Uplifting [print] best 1012 combination reg byte y [ print::p_x#0 ] reg byte x [ print::p_y#0 ]
|
||||
Uplifting [] best 1012 combination zp[1]:2 [ idx ]
|
||||
Uplifting [Point] best 1012 combination
|
||||
Uplifting [main] best 937 combination reg byte x [ main::$1_x ] reg byte a [ main::$1_y ] zp[1]:9 [ main::i ] zp[2]:12 [ main::p ]
|
||||
Uplifting [get] best 922 combination reg byte x [ get::i#0 ] reg byte a [ get::$0 ] reg byte x [ get::return_x#0 ] zp[1]:8 [ get::return_y#0 ] zp[2]:14 [ get::p ]
|
||||
Limited combination testing to 100 combinations of 144 possible.
|
||||
Uplifting [print] best 918 combination reg byte y [ print::p_x#0 ] reg byte x [ print::p_y#0 ]
|
||||
Uplifting [] best 918 combination zp[1]:2 [ idx ]
|
||||
Uplifting [Point] best 918 combination
|
||||
Attempting to uplift remaining variables inzp[1]:9 [ main::i ]
|
||||
Uplifting [main] best 1012 combination zp[1]:9 [ main::i ]
|
||||
Attempting to uplift remaining variables inzp[1]:10 [ main::$1_x ]
|
||||
Uplifting [main] best 1012 combination zp[1]:10 [ main::$1_x ]
|
||||
Attempting to uplift remaining variables inzp[1]:11 [ main::$1_y ]
|
||||
Uplifting [main] best 1012 combination zp[1]:11 [ main::$1_y ]
|
||||
Uplifting [main] best 918 combination zp[1]:9 [ main::i ]
|
||||
Attempting to uplift remaining variables inzp[1]:8 [ get::return_y#0 ]
|
||||
Uplifting [get] best 914 combination reg byte y [ get::return_y#0 ]
|
||||
Attempting to uplift remaining variables inzp[1]:2 [ idx ]
|
||||
Uplifting [] best 1012 combination zp[1]:2 [ idx ]
|
||||
Uplifting [] best 914 combination zp[1]:2 [ idx ]
|
||||
Allocated (was zp[1]:9) zp[1]:3 [ main::i ]
|
||||
Allocated (was zp[1]:10) zp[1]:4 [ main::$1_x ]
|
||||
Allocated (was zp[1]:11) zp[1]:5 [ main::$1_y ]
|
||||
Allocated (was zp[2]:12) zp[2]:6 [ main::p ]
|
||||
Allocated (was zp[2]:14) zp[2]:8 [ get::p ]
|
||||
Allocated (was zp[2]:12) zp[2]:4 [ main::p ]
|
||||
Allocated (was zp[2]:14) zp[2]:6 [ get::p ]
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
// File Comments
|
||||
@ -579,7 +581,6 @@ ASSEMBLER BEFORE OPTIMIZATION
|
||||
.label SCREEN = $400
|
||||
.const OFFSET_STRUCT_POINT_Y = 1
|
||||
.const STACK_BASE = $103
|
||||
.const OFFSET_STRUCT_POINT_X = 0
|
||||
.label idx = 2
|
||||
// @begin
|
||||
__bbegin:
|
||||
@ -592,8 +593,7 @@ __b1:
|
||||
// [1] callprepare main
|
||||
// [2] callexecute main -- jsr
|
||||
jsr main
|
||||
// [3] callfinalize main
|
||||
// [4] phi from @1 to @end [phi:@1->@end]
|
||||
// [3] phi from @1 to @end [phi:@1->@end]
|
||||
__bend_from___b1:
|
||||
jmp __bend
|
||||
// @end
|
||||
@ -603,120 +603,115 @@ __bend:
|
||||
print: {
|
||||
.const OFFSET_STACK_P_X = 1
|
||||
.const OFFSET_STACK_P_Y = 0
|
||||
// [5] (byte) print::p_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_X) -- vbuyy=_stackidxbyte_vbuc1
|
||||
// [4] (byte) print::p_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_X) -- vbuyy=_stackidxbyte_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_P_X,x
|
||||
tay
|
||||
// [6] (byte) print::p_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_Y) -- vbuxx=_stackidxbyte_vbuc1
|
||||
// [5] (byte) print::p_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_Y) -- vbuxx=_stackidxbyte_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_P_Y,x
|
||||
tax
|
||||
// [7] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_x#0 -- pbuc1_derefidx_vbuz1=vbuyy
|
||||
// [6] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_x#0 -- pbuc1_derefidx_vbuz1=vbuyy
|
||||
tya
|
||||
ldy.z idx
|
||||
sta SCREEN,y
|
||||
// [8] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1
|
||||
// [7] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1
|
||||
inc.z idx
|
||||
// [9] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_y#0 -- pbuc1_derefidx_vbuz1=vbuxx
|
||||
// [8] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_y#0 -- pbuc1_derefidx_vbuz1=vbuxx
|
||||
ldy.z idx
|
||||
txa
|
||||
sta SCREEN,y
|
||||
// [10] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1
|
||||
// [9] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1
|
||||
inc.z idx
|
||||
jmp __breturn
|
||||
// print::@return
|
||||
__breturn:
|
||||
// [11] return
|
||||
// [10] return
|
||||
rts
|
||||
}
|
||||
// get
|
||||
// get(byte register(X) i)
|
||||
get: {
|
||||
.const OFFSET_STACK_I = 0
|
||||
.const OFFSET_STACK_RETURN = 0
|
||||
.label p = 8
|
||||
// [12] (byte) get::i#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I) -- vbuxx=_stackidxbyte_vbuc1
|
||||
.label p = 6
|
||||
// [11] (byte) get::i#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I) -- vbuxx=_stackidxbyte_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_I,x
|
||||
tax
|
||||
// [13] (byte~) get::$0 ← (byte) get::i#0 >> (byte) 1 -- vbuaa=vbuxx_ror_1
|
||||
// [12] (byte~) get::$0 ← (byte) get::i#0 >> (byte) 1 -- vbuaa=vbuxx_ror_1
|
||||
txa
|
||||
lsr
|
||||
// [14] *((byte*)&(struct Point) get::p) ← (byte) get::i#0 -- _deref_pbuc1=vbuxx
|
||||
// [13] *((byte*)&(struct Point) get::p) ← (byte) get::i#0 -- _deref_pbuc1=vbuxx
|
||||
stx.z p
|
||||
// [15] *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) get::$0 -- _deref_pbuc1=vbuaa
|
||||
// [14] *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) get::$0 -- _deref_pbuc1=vbuaa
|
||||
sta p+OFFSET_STRUCT_POINT_Y
|
||||
// [16] (byte) get::return_x#0 ← *((byte*)&(struct Point) get::p) -- vbuaa=_deref_pbuc1
|
||||
lda.z p
|
||||
// [17] (byte) get::return_y#0 ← *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_Y) -- vbuyy=_deref_pbuc1
|
||||
// [15] (byte) get::return_x#0 ← *((byte*)&(struct Point) get::p) -- vbuxx=_deref_pbuc1
|
||||
ldx.z p
|
||||
// [16] (byte) get::return_y#0 ← *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_Y) -- vbuyy=_deref_pbuc1
|
||||
ldy p+OFFSET_STRUCT_POINT_Y
|
||||
jmp __breturn
|
||||
// get::@return
|
||||
__breturn:
|
||||
// [18] return { (byte) get::return_x#0, (byte) get::return_y#0 }
|
||||
// [18] return { (byte) get::return_x#0, (byte) get::return_y#0 } [(byte) Point::x#0] -- _stackidxbyte_vbuc1=vbuaa
|
||||
// [17] stackidx(byte,(byte) 0) ← (byte) get::return_x#0 -- _stackidxbyte_vbuc1=vbuxx
|
||||
txa
|
||||
tsx
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN+OFFSET_STRUCT_POINT_X,x
|
||||
// [18] return { (byte) get::return_x#0, (byte) get::return_y#0 } [(byte) Point::y#1] -- _stackidxbyte_vbuc1=vbuyy
|
||||
sta STACK_BASE+0,x
|
||||
// [18] stackidx(byte,(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_y#0 -- _stackidxbyte_vbuc1=vbuyy
|
||||
tya
|
||||
tsx
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN+OFFSET_STRUCT_POINT_Y,x
|
||||
sta STACK_BASE+OFFSET_STRUCT_POINT_Y,x
|
||||
// [19] return
|
||||
rts
|
||||
}
|
||||
// main
|
||||
main: {
|
||||
.label i = 3
|
||||
.label p = 6
|
||||
.label __1_x = 4
|
||||
.label __1_y = 5
|
||||
// [19] (byte) main::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
.label p = 4
|
||||
// [20] (byte) main::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z i
|
||||
jmp __b1
|
||||
// main::@1
|
||||
__b1:
|
||||
// [20] if((byte) main::i<(byte) 5) goto main::@2 -- vbuz1_lt_vbuc1_then_la1
|
||||
// [21] if((byte) main::i<(byte) 5) goto main::@2 -- vbuz1_lt_vbuc1_then_la1
|
||||
lda.z i
|
||||
cmp #5
|
||||
bcc __b2
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [21] return
|
||||
// [22] return
|
||||
rts
|
||||
// main::@2
|
||||
__b2:
|
||||
// [22] callprepare get (byte) main::i [(byte) get::i#0] -- _stackpushbyte_=vbuz1
|
||||
// [23] callprepare get (byte) main::i [(byte) get::i#0] -- _stackpushbyte_=vbuz1
|
||||
lda.z i
|
||||
pha
|
||||
// [22] callprepare get (byte) main::i -- _stackpushbyte_1
|
||||
// [23] callprepare get (byte) main::i -- _stackpushbyte_1
|
||||
pha
|
||||
// [23] callexecute get -- jsr
|
||||
// [24] callexecute get -- jsr
|
||||
jsr get
|
||||
// [24] { (byte~) main::$1_x, (byte~) main::$1_y } ← callfinalize get [(byte) Point::x#0] -- vbuz1=_stackpullbyte_
|
||||
// [25] (byte~) main::$1_x ← stackpull(byte) -- vbuxx=_stackpullbyte_
|
||||
pla
|
||||
sta.z __1_x
|
||||
// [24] { (byte~) main::$1_x, (byte~) main::$1_y } ← callfinalize get [(byte) Point::y#1] -- vbuz1=_stackpullbyte_
|
||||
tax
|
||||
// [26] (byte~) main::$1_y ← stackpull(byte) -- vbuaa=_stackpullbyte_
|
||||
pla
|
||||
sta.z __1_y
|
||||
// [25] *((byte*)&(struct Point) main::p) ← (byte~) main::$1_x -- _deref_pbuc1=vbuz1
|
||||
lda.z __1_x
|
||||
sta.z p
|
||||
// [26] *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_y -- _deref_pbuc1=vbuz1
|
||||
lda.z __1_y
|
||||
// [27] *((byte*)&(struct Point) main::p) ← (byte~) main::$1_x -- _deref_pbuc1=vbuxx
|
||||
stx.z p
|
||||
// [28] *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_y -- _deref_pbuc1=vbuaa
|
||||
sta p+OFFSET_STRUCT_POINT_Y
|
||||
// [27] callprepare print *((byte*)&(struct Point) main::p) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) [(byte) print::p_x#0] -- _stackpushbyte_=_deref_pbuc1
|
||||
// [29] callprepare print *((byte*)&(struct Point) main::p) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) [(byte) print::p_x#0] -- _stackpushbyte_=_deref_pbuc1
|
||||
lda.z p
|
||||
pha
|
||||
// [27] callprepare print *((byte*)&(struct Point) main::p) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) [(byte) print::p_y#1] -- _stackpushbyte_=_deref_pbuc1
|
||||
// [29] callprepare print *((byte*)&(struct Point) main::p) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) [(byte) print::p_y#1] -- _stackpushbyte_=_deref_pbuc1
|
||||
lda p+OFFSET_STRUCT_POINT_Y
|
||||
pha
|
||||
// [28] callexecute print -- jsr
|
||||
// [30] callexecute print -- jsr
|
||||
jsr print
|
||||
// [29] callfinalize print -- _stackpullbyte_2
|
||||
// stackpull((number) 2) -- _stackpullbyte_2
|
||||
pla
|
||||
pla
|
||||
// [30] (byte) main::i ← ++ (byte) main::i -- vbuz1=_inc_vbuz1
|
||||
// [32] (byte) main::i ← ++ (byte) main::i -- vbuz1=_inc_vbuz1
|
||||
inc.z i
|
||||
jmp __b1
|
||||
}
|
||||
@ -730,7 +725,10 @@ Removing instruction jmp __breturn
|
||||
Removing instruction jmp __b1
|
||||
Removing instruction jmp __breturn
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Removing instruction ldx.z p
|
||||
Replacing instruction ldy p+OFFSET_STRUCT_POINT_Y with TAY
|
||||
Replacing instruction lda.z p with TXA
|
||||
Succesful ASM optimization Pass5UnnecesaryLoadElimination
|
||||
Removing instruction __bend_from___b1:
|
||||
Succesful ASM optimization Pass5RedundantLabelElimination
|
||||
Removing instruction __b1:
|
||||
@ -746,7 +744,6 @@ FINAL SYMBOL TABLE
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const byte) OFFSET_STRUCT_POINT_X = (byte) 0
|
||||
(const byte) OFFSET_STRUCT_POINT_Y = (byte) 1
|
||||
(byte) Point::x loadstore
|
||||
(byte) Point::y loadstore
|
||||
@ -756,24 +753,23 @@ __stackcall (struct Point()) get((byte) get::i)
|
||||
(byte~) get::$0 reg byte a 2.0
|
||||
(label) get::@return
|
||||
(const byte) get::OFFSET_STACK_I = (byte) 0
|
||||
(const byte) get::OFFSET_STACK_RETURN = (byte) 0
|
||||
(byte) get::i
|
||||
(byte) get::i#0 reg byte x 3.0
|
||||
(struct Point) get::p loadstore zp[2]:8
|
||||
(struct Point) get::p loadstore zp[2]:6
|
||||
(struct Point) get::return
|
||||
(byte) get::return_x
|
||||
(byte) get::return_x#0 reg byte a 1.0
|
||||
(byte) get::return_x#0 reg byte x 2.0
|
||||
(byte) get::return_y
|
||||
(byte) get::return_y#0 reg byte y 2.0
|
||||
(byte) idx loadstore zp[1]:2 0.7
|
||||
(byte) idx loadstore zp[1]:2 0.6666666666666666
|
||||
__stackcall (void()) main()
|
||||
(byte~) main::$1_x zp[1]:4 0.8461538461538461
|
||||
(byte~) main::$1_y zp[1]:5 0.8461538461538461
|
||||
(byte~) main::$1_x reg byte x 11.0
|
||||
(byte~) main::$1_y reg byte a 11.0
|
||||
(label) main::@1
|
||||
(label) main::@2
|
||||
(label) main::@return
|
||||
(byte) main::i loadstore zp[1]:3 3.1818181818181817
|
||||
(struct Point) main::p loadstore zp[2]:6
|
||||
(byte) main::i loadstore zp[1]:3 2.9166666666666665
|
||||
(struct Point) main::p loadstore zp[2]:4
|
||||
__stackcall (void()) print((byte) print::p_x , (byte) print::p_y)
|
||||
(label) print::@return
|
||||
(const byte) print::OFFSET_STACK_P_X = (byte) 1
|
||||
@ -788,17 +784,17 @@ reg byte y [ print::p_x#0 ]
|
||||
reg byte x [ print::p_y#0 ]
|
||||
reg byte x [ get::i#0 ]
|
||||
reg byte a [ get::$0 ]
|
||||
reg byte a [ get::return_x#0 ]
|
||||
reg byte x [ get::return_x#0 ]
|
||||
reg byte y [ get::return_y#0 ]
|
||||
zp[1]:3 [ main::i ]
|
||||
zp[1]:4 [ main::$1_x ]
|
||||
zp[1]:5 [ main::$1_y ]
|
||||
zp[2]:6 [ main::p ]
|
||||
zp[2]:8 [ get::p ]
|
||||
reg byte x [ main::$1_x ]
|
||||
reg byte a [ main::$1_y ]
|
||||
zp[2]:4 [ main::p ]
|
||||
zp[2]:6 [ get::p ]
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 972
|
||||
Score: 860
|
||||
|
||||
// File Comments
|
||||
// Test a procedure with calling convention stack
|
||||
@ -811,7 +807,6 @@ Score: 972
|
||||
.label SCREEN = $400
|
||||
.const OFFSET_STRUCT_POINT_Y = 1
|
||||
.const STACK_BASE = $103
|
||||
.const OFFSET_STRUCT_POINT_X = 0
|
||||
.label idx = 2
|
||||
// @begin
|
||||
__bbegin:
|
||||
@ -824,8 +819,7 @@ __bbegin:
|
||||
// [2] callexecute main -- jsr
|
||||
jsr main
|
||||
rts
|
||||
// [3] callfinalize main
|
||||
// [4] phi from @1 to @end [phi:@1->@end]
|
||||
// [3] phi from @1 to @end [phi:@1->@end]
|
||||
// @end
|
||||
// print
|
||||
// print(byte register(Y) p_x, byte register(X) p_y)
|
||||
@ -833,129 +827,123 @@ print: {
|
||||
.const OFFSET_STACK_P_X = 1
|
||||
.const OFFSET_STACK_P_Y = 0
|
||||
// }
|
||||
// [5] (byte) print::p_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_X) -- vbuyy=_stackidxbyte_vbuc1
|
||||
// [4] (byte) print::p_x#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_X) -- vbuyy=_stackidxbyte_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_P_X,x
|
||||
tay
|
||||
// [6] (byte) print::p_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_Y) -- vbuxx=_stackidxbyte_vbuc1
|
||||
// [5] (byte) print::p_y#0 ← stackidx(byte,(const byte) print::OFFSET_STACK_P_Y) -- vbuxx=_stackidxbyte_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_P_Y,x
|
||||
tax
|
||||
// SCREEN[idx++] = p.x
|
||||
// [7] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_x#0 -- pbuc1_derefidx_vbuz1=vbuyy
|
||||
// [6] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_x#0 -- pbuc1_derefidx_vbuz1=vbuyy
|
||||
tya
|
||||
ldy.z idx
|
||||
sta SCREEN,y
|
||||
// SCREEN[idx++] = p.x;
|
||||
// [8] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1
|
||||
// [7] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1
|
||||
inc.z idx
|
||||
// SCREEN[idx++] = p.y
|
||||
// [9] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_y#0 -- pbuc1_derefidx_vbuz1=vbuxx
|
||||
// [8] *((const byte*) SCREEN + (byte) idx) ← (byte) print::p_y#0 -- pbuc1_derefidx_vbuz1=vbuxx
|
||||
ldy.z idx
|
||||
txa
|
||||
sta SCREEN,y
|
||||
// SCREEN[idx++] = p.y;
|
||||
// [10] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1
|
||||
// [9] (byte) idx ← ++ (byte) idx -- vbuz1=_inc_vbuz1
|
||||
inc.z idx
|
||||
// print::@return
|
||||
// }
|
||||
// [11] return
|
||||
// [10] return
|
||||
rts
|
||||
}
|
||||
// get
|
||||
// get(byte register(X) i)
|
||||
get: {
|
||||
.const OFFSET_STACK_I = 0
|
||||
.const OFFSET_STACK_RETURN = 0
|
||||
.label p = 8
|
||||
// [12] (byte) get::i#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I) -- vbuxx=_stackidxbyte_vbuc1
|
||||
.label p = 6
|
||||
// [11] (byte) get::i#0 ← stackidx(byte,(const byte) get::OFFSET_STACK_I) -- vbuxx=_stackidxbyte_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_I,x
|
||||
tax
|
||||
// i/2
|
||||
// [13] (byte~) get::$0 ← (byte) get::i#0 >> (byte) 1 -- vbuaa=vbuxx_ror_1
|
||||
// [12] (byte~) get::$0 ← (byte) get::i#0 >> (byte) 1 -- vbuaa=vbuxx_ror_1
|
||||
txa
|
||||
lsr
|
||||
// p = { i, i/2 }
|
||||
// [14] *((byte*)&(struct Point) get::p) ← (byte) get::i#0 -- _deref_pbuc1=vbuxx
|
||||
// [13] *((byte*)&(struct Point) get::p) ← (byte) get::i#0 -- _deref_pbuc1=vbuxx
|
||||
stx.z p
|
||||
// [15] *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) get::$0 -- _deref_pbuc1=vbuaa
|
||||
// [14] *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) get::$0 -- _deref_pbuc1=vbuaa
|
||||
sta p+OFFSET_STRUCT_POINT_Y
|
||||
// return p;
|
||||
// [16] (byte) get::return_x#0 ← *((byte*)&(struct Point) get::p) -- vbuaa=_deref_pbuc1
|
||||
txa
|
||||
// [17] (byte) get::return_y#0 ← *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_Y) -- vbuyy=_deref_pbuc1
|
||||
ldy p+OFFSET_STRUCT_POINT_Y
|
||||
// [15] (byte) get::return_x#0 ← *((byte*)&(struct Point) get::p) -- vbuxx=_deref_pbuc1
|
||||
// [16] (byte) get::return_y#0 ← *((byte*)&(struct Point) get::p+(const byte) OFFSET_STRUCT_POINT_Y) -- vbuyy=_deref_pbuc1
|
||||
tay
|
||||
// get::@return
|
||||
// }
|
||||
// [18] return { (byte) get::return_x#0, (byte) get::return_y#0 }
|
||||
// [18] return { (byte) get::return_x#0, (byte) get::return_y#0 } [(byte) Point::x#0] -- _stackidxbyte_vbuc1=vbuaa
|
||||
// [17] stackidx(byte,(byte) 0) ← (byte) get::return_x#0 -- _stackidxbyte_vbuc1=vbuxx
|
||||
txa
|
||||
tsx
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN+OFFSET_STRUCT_POINT_X,x
|
||||
// [18] return { (byte) get::return_x#0, (byte) get::return_y#0 } [(byte) Point::y#1] -- _stackidxbyte_vbuc1=vbuyy
|
||||
sta STACK_BASE+0,x
|
||||
// [18] stackidx(byte,(const byte) OFFSET_STRUCT_POINT_Y) ← (byte) get::return_y#0 -- _stackidxbyte_vbuc1=vbuyy
|
||||
tya
|
||||
tsx
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN+OFFSET_STRUCT_POINT_Y,x
|
||||
sta STACK_BASE+OFFSET_STRUCT_POINT_Y,x
|
||||
// [19] return
|
||||
rts
|
||||
}
|
||||
// main
|
||||
main: {
|
||||
.label i = 3
|
||||
.label p = 6
|
||||
.label __1_x = 4
|
||||
.label __1_y = 5
|
||||
.label p = 4
|
||||
// i=0
|
||||
// [19] (byte) main::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
// [20] (byte) main::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z i
|
||||
// main::@1
|
||||
__b1:
|
||||
// for(char i=0;i<5;i++)
|
||||
// [20] if((byte) main::i<(byte) 5) goto main::@2 -- vbuz1_lt_vbuc1_then_la1
|
||||
// [21] if((byte) main::i<(byte) 5) goto main::@2 -- vbuz1_lt_vbuc1_then_la1
|
||||
lda.z i
|
||||
cmp #5
|
||||
bcc __b2
|
||||
// main::@return
|
||||
// }
|
||||
// [21] return
|
||||
// [22] return
|
||||
rts
|
||||
// main::@2
|
||||
__b2:
|
||||
// get(i)
|
||||
// [22] callprepare get (byte) main::i [(byte) get::i#0] -- _stackpushbyte_=vbuz1
|
||||
// [23] callprepare get (byte) main::i [(byte) get::i#0] -- _stackpushbyte_=vbuz1
|
||||
lda.z i
|
||||
pha
|
||||
// [22] callprepare get (byte) main::i -- _stackpushbyte_1
|
||||
// [23] callprepare get (byte) main::i -- _stackpushbyte_1
|
||||
pha
|
||||
// [23] callexecute get -- jsr
|
||||
// [24] callexecute get -- jsr
|
||||
jsr get
|
||||
// [24] { (byte~) main::$1_x, (byte~) main::$1_y } ← callfinalize get [(byte) Point::x#0] -- vbuz1=_stackpullbyte_
|
||||
// [25] (byte~) main::$1_x ← stackpull(byte) -- vbuxx=_stackpullbyte_
|
||||
pla
|
||||
sta.z __1_x
|
||||
// [24] { (byte~) main::$1_x, (byte~) main::$1_y } ← callfinalize get [(byte) Point::y#1] -- vbuz1=_stackpullbyte_
|
||||
tax
|
||||
// [26] (byte~) main::$1_y ← stackpull(byte) -- vbuaa=_stackpullbyte_
|
||||
pla
|
||||
sta.z __1_y
|
||||
// p = get(i)
|
||||
// [25] *((byte*)&(struct Point) main::p) ← (byte~) main::$1_x -- _deref_pbuc1=vbuz1
|
||||
lda.z __1_x
|
||||
sta.z p
|
||||
// [26] *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_y -- _deref_pbuc1=vbuz1
|
||||
lda.z __1_y
|
||||
// [27] *((byte*)&(struct Point) main::p) ← (byte~) main::$1_x -- _deref_pbuc1=vbuxx
|
||||
stx.z p
|
||||
// [28] *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) ← (byte~) main::$1_y -- _deref_pbuc1=vbuaa
|
||||
sta p+OFFSET_STRUCT_POINT_Y
|
||||
// print(p)
|
||||
// [27] callprepare print *((byte*)&(struct Point) main::p) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) [(byte) print::p_x#0] -- _stackpushbyte_=_deref_pbuc1
|
||||
lda.z p
|
||||
// [29] callprepare print *((byte*)&(struct Point) main::p) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) [(byte) print::p_x#0] -- _stackpushbyte_=_deref_pbuc1
|
||||
txa
|
||||
pha
|
||||
// [27] callprepare print *((byte*)&(struct Point) main::p) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) [(byte) print::p_y#1] -- _stackpushbyte_=_deref_pbuc1
|
||||
// [29] callprepare print *((byte*)&(struct Point) main::p) *((byte*)&(struct Point) main::p+(const byte) OFFSET_STRUCT_POINT_Y) [(byte) print::p_y#1] -- _stackpushbyte_=_deref_pbuc1
|
||||
lda p+OFFSET_STRUCT_POINT_Y
|
||||
pha
|
||||
// [28] callexecute print -- jsr
|
||||
// [30] callexecute print -- jsr
|
||||
jsr print
|
||||
// [29] callfinalize print -- _stackpullbyte_2
|
||||
// stackpull((number) 2) -- _stackpullbyte_2
|
||||
pla
|
||||
pla
|
||||
// for(char i=0;i<5;i++)
|
||||
// [30] (byte) main::i ← ++ (byte) main::i -- vbuz1=_inc_vbuz1
|
||||
// [32] (byte) main::i ← ++ (byte) main::i -- vbuz1=_inc_vbuz1
|
||||
inc.z i
|
||||
jmp __b1
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(const byte) OFFSET_STRUCT_POINT_X = (byte) 0
|
||||
(const byte) OFFSET_STRUCT_POINT_Y = (byte) 1
|
||||
(byte) Point::x loadstore
|
||||
(byte) Point::y loadstore
|
||||
@ -11,24 +10,23 @@ __stackcall (struct Point()) get((byte) get::i)
|
||||
(byte~) get::$0 reg byte a 2.0
|
||||
(label) get::@return
|
||||
(const byte) get::OFFSET_STACK_I = (byte) 0
|
||||
(const byte) get::OFFSET_STACK_RETURN = (byte) 0
|
||||
(byte) get::i
|
||||
(byte) get::i#0 reg byte x 3.0
|
||||
(struct Point) get::p loadstore zp[2]:8
|
||||
(struct Point) get::p loadstore zp[2]:6
|
||||
(struct Point) get::return
|
||||
(byte) get::return_x
|
||||
(byte) get::return_x#0 reg byte a 1.0
|
||||
(byte) get::return_x#0 reg byte x 2.0
|
||||
(byte) get::return_y
|
||||
(byte) get::return_y#0 reg byte y 2.0
|
||||
(byte) idx loadstore zp[1]:2 0.7
|
||||
(byte) idx loadstore zp[1]:2 0.6666666666666666
|
||||
__stackcall (void()) main()
|
||||
(byte~) main::$1_x zp[1]:4 0.8461538461538461
|
||||
(byte~) main::$1_y zp[1]:5 0.8461538461538461
|
||||
(byte~) main::$1_x reg byte x 11.0
|
||||
(byte~) main::$1_y reg byte a 11.0
|
||||
(label) main::@1
|
||||
(label) main::@2
|
||||
(label) main::@return
|
||||
(byte) main::i loadstore zp[1]:3 3.1818181818181817
|
||||
(struct Point) main::p loadstore zp[2]:6
|
||||
(byte) main::i loadstore zp[1]:3 2.9166666666666665
|
||||
(struct Point) main::p loadstore zp[2]:4
|
||||
__stackcall (void()) print((byte) print::p_x , (byte) print::p_y)
|
||||
(label) print::@return
|
||||
(const byte) print::OFFSET_STACK_P_X = (byte) 1
|
||||
@ -43,10 +41,10 @@ reg byte y [ print::p_x#0 ]
|
||||
reg byte x [ print::p_y#0 ]
|
||||
reg byte x [ get::i#0 ]
|
||||
reg byte a [ get::$0 ]
|
||||
reg byte a [ get::return_x#0 ]
|
||||
reg byte x [ get::return_x#0 ]
|
||||
reg byte y [ get::return_y#0 ]
|
||||
zp[1]:3 [ main::i ]
|
||||
zp[1]:4 [ main::$1_x ]
|
||||
zp[1]:5 [ main::$1_y ]
|
||||
zp[2]:6 [ main::p ]
|
||||
zp[2]:8 [ get::p ]
|
||||
reg byte x [ main::$1_x ]
|
||||
reg byte a [ main::$1_y ]
|
||||
zp[2]:4 [ main::p ]
|
||||
zp[2]:6 [ get::p ]
|
||||
|
@ -12,19 +12,21 @@
|
||||
main: scope:[main] from @1
|
||||
[4] callprepare plus (word) $1234 (word) $2345
|
||||
[5] callexecute plus
|
||||
[6] (word~) main::$0 ← callfinalize plus
|
||||
[7] *((const word*) SCREEN) ← (word~) main::$0
|
||||
stackpull((number) 2)
|
||||
[7] (word~) main::$0 ← stackpull(word)
|
||||
[8] *((const word*) SCREEN) ← (word~) main::$0
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[8] return
|
||||
[9] return
|
||||
to:@return
|
||||
|
||||
__stackcall (word()) plus((word) plus::a , (word) plus::b)
|
||||
plus: scope:[plus] from
|
||||
[9] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A)
|
||||
[10] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B)
|
||||
[11] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0
|
||||
[10] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A)
|
||||
[11] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B)
|
||||
[12] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0
|
||||
to:plus::@return
|
||||
plus::@return: scope:[plus] from plus
|
||||
[12] return (word) plus::return#0
|
||||
[13] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0
|
||||
[14] return
|
||||
to:@return
|
||||
|
@ -4,6 +4,8 @@ Culled Empty Block (label) plus::@1
|
||||
Calling convention STACK_CALL adding prepare/execute/finalize for (word~) main::$0 ← call plus (number) $1234 (number) $2345
|
||||
Calling convention STACK_CALL replacing param((word) plus::a) with stackidx(word,(const byte) plus::OFFSET_STACK_A)
|
||||
Calling convention STACK_CALL replacing param((word) plus::b) with stackidx(word,(const byte) plus::OFFSET_STACK_B)
|
||||
Calling convention STACK_CALL adding stack return stackidx(word,plus::OFFSET_STACK_RETURN) ← plus::return
|
||||
Calling convention STACK_CALL adding stack pull main::$0 ← stackpull(word)
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
@begin: scope:[] from
|
||||
@ -13,7 +15,8 @@ CONTROL FLOW GRAPH SSA
|
||||
main: scope:[main] from @2
|
||||
callprepare plus (number) $1234 (number) $2345
|
||||
callexecute plus
|
||||
(word~) main::$0 ← callfinalize plus
|
||||
stackpull((number) 2)
|
||||
(word~) main::$0 ← stackpull(word)
|
||||
(number~) main::$1 ← (number) 0 * (const byte) SIZEOF_WORD
|
||||
*((const word*) SCREEN + (number~) main::$1) ← (word~) main::$0
|
||||
to:main::@return
|
||||
@ -30,7 +33,8 @@ plus: scope:[plus] from
|
||||
to:plus::@return
|
||||
plus::@return: scope:[plus] from plus
|
||||
(word) plus::return#1 ← phi( plus/(word) plus::return#0 )
|
||||
return (word) plus::return#1
|
||||
stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#1
|
||||
return
|
||||
to:@return
|
||||
@2: scope:[] from @begin
|
||||
call main
|
||||
@ -82,16 +86,15 @@ Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||
Inferred type updated to byte in (unumber~) main::$1 ← (byte) 0 * (const byte) SIZEOF_WORD
|
||||
Alias (word) plus::return#0 = (word~) plus::$0 (word) plus::return#1
|
||||
Successful SSA optimization Pass2AliasElimination
|
||||
Constant right-side identified [3] (byte~) main::$1 ← (byte) 0 * (const byte) SIZEOF_WORD
|
||||
Constant right-side identified [4] (byte~) main::$1 ← (byte) 0 * (const byte) SIZEOF_WORD
|
||||
Successful SSA optimization Pass2ConstantRValueConsolidation
|
||||
Constant (const byte) main::$1 = 0*SIZEOF_WORD
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Simplifying constant evaluating to zero (byte) 0*(const byte) SIZEOF_WORD in
|
||||
Successful SSA optimization PassNSimplifyConstantZero
|
||||
Simplifying expression containing zero SCREEN in [4] *((const word*) SCREEN + (const byte) main::$1) ← (word~) main::$0
|
||||
Simplifying expression containing zero SCREEN in [5] *((const word*) SCREEN + (const byte) main::$1) ← (word~) main::$0
|
||||
Successful SSA optimization PassNSimplifyExpressionWithZero
|
||||
Eliminating unused constant (const byte) main::$1
|
||||
Eliminating unused constant (const byte) plus::OFFSET_STACK_RETURN
|
||||
Eliminating unused constant (const byte) SIZEOF_WORD
|
||||
Successful SSA optimization PassNEliminateUnusedVars
|
||||
Adding NOP phi() at start of @begin
|
||||
@ -125,34 +128,36 @@ FINAL CONTROL FLOW GRAPH
|
||||
main: scope:[main] from @1
|
||||
[4] callprepare plus (word) $1234 (word) $2345
|
||||
[5] callexecute plus
|
||||
[6] (word~) main::$0 ← callfinalize plus
|
||||
[7] *((const word*) SCREEN) ← (word~) main::$0
|
||||
stackpull((number) 2)
|
||||
[7] (word~) main::$0 ← stackpull(word)
|
||||
[8] *((const word*) SCREEN) ← (word~) main::$0
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[8] return
|
||||
[9] return
|
||||
to:@return
|
||||
|
||||
__stackcall (word()) plus((word) plus::a , (word) plus::b)
|
||||
plus: scope:[plus] from
|
||||
[9] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A)
|
||||
[10] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B)
|
||||
[11] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0
|
||||
[10] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A)
|
||||
[11] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B)
|
||||
[12] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0
|
||||
to:plus::@return
|
||||
plus::@return: scope:[plus] from plus
|
||||
[12] return (word) plus::return#0
|
||||
[13] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0
|
||||
[14] return
|
||||
to:@return
|
||||
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
(void()) main()
|
||||
(word~) main::$0 2.0
|
||||
(word~) main::$0 4.0
|
||||
__stackcall (word()) plus((word) plus::a , (word) plus::b)
|
||||
(word) plus::a
|
||||
(word) plus::a#0 2.0
|
||||
(word) plus::b
|
||||
(word) plus::b#0 4.0
|
||||
(word) plus::return
|
||||
(word) plus::return#0 2.0
|
||||
(word) plus::return#0 4.0
|
||||
|
||||
Initial phi equivalence classes
|
||||
Added variable main::$0 to live range equivalence class [ main::$0 ]
|
||||
@ -209,15 +214,15 @@ main: {
|
||||
pha
|
||||
// [5] callexecute plus -- jsr
|
||||
jsr plus
|
||||
// [6] (word~) main::$0 ← callfinalize plus -- _stackpullbyte_2
|
||||
// stackpull((number) 2) -- _stackpullbyte_2
|
||||
pla
|
||||
pla
|
||||
// [6] (word~) main::$0 ← callfinalize plus -- vwuz1=_stackpullword_
|
||||
// [7] (word~) main::$0 ← stackpull(word) -- vwuz1=_stackpullword_
|
||||
pla
|
||||
sta.z __0
|
||||
pla
|
||||
sta.z __0+1
|
||||
// [7] *((const word*) SCREEN) ← (word~) main::$0 -- _deref_pwuc1=vwuz1
|
||||
// [8] *((const word*) SCREEN) ← (word~) main::$0 -- _deref_pwuc1=vwuz1
|
||||
lda.z __0
|
||||
sta SCREEN
|
||||
lda.z __0+1
|
||||
@ -225,7 +230,7 @@ main: {
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [8] return
|
||||
// [9] return
|
||||
rts
|
||||
}
|
||||
// plus
|
||||
@ -233,22 +238,23 @@ main: {
|
||||
plus: {
|
||||
.const OFFSET_STACK_A = 2
|
||||
.const OFFSET_STACK_B = 0
|
||||
.const OFFSET_STACK_RETURN = 2
|
||||
.label a = 4
|
||||
.label b = 6
|
||||
.label return = 8
|
||||
// [9] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) -- vwuz1=_stackidxword_vbuc1
|
||||
// [10] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) -- vwuz1=_stackidxword_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_A,x
|
||||
sta.z a
|
||||
lda STACK_BASE+OFFSET_STACK_A+1,x
|
||||
sta.z a+1
|
||||
// [10] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) -- vwuz1=_stackidxword_vbuc1
|
||||
// [11] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) -- vwuz1=_stackidxword_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_B,x
|
||||
sta.z b
|
||||
lda STACK_BASE+OFFSET_STACK_B+1,x
|
||||
sta.z b+1
|
||||
// [11] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 -- vwuz1=vwuz2_plus_vwuz3
|
||||
// [12] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 -- vwuz1=vwuz2_plus_vwuz3
|
||||
lda.z a
|
||||
clc
|
||||
adc.z b
|
||||
@ -259,36 +265,37 @@ plus: {
|
||||
jmp __breturn
|
||||
// plus::@return
|
||||
__breturn:
|
||||
// [12] return (word) plus::return#0
|
||||
// [12] return (word) plus::return#0 -- _stackidxword_vbuc1=vwuz1
|
||||
// [13] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0 -- _stackidxword_vbuc1=vwuz1
|
||||
tsx
|
||||
lda.z return
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN,x
|
||||
lda.z return+1
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN+1,x
|
||||
// [14] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Statement [4] callprepare plus (word) $1234 (word) $2345 [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
Statement [6] (word~) main::$0 ← callfinalize plus [ main::$0 ] ( main:2 [ main::$0 ] ) always clobbers reg byte a
|
||||
Statement [7] *((const word*) SCREEN) ← (word~) main::$0 [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
Statement [9] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:5 [ plus::a#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement [10] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:5 [ plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement [11] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 [ plus::return#0 ] ( main:2::plus:5 [ plus::return#0 ] ) always clobbers reg byte a
|
||||
Statement [12] return (word) plus::return#0 [ ] ( main:2::plus:5 [ ] ) always clobbers reg byte a reg byte x
|
||||
Statement stackpull((number) 2) always clobbers reg byte a
|
||||
Statement [7] (word~) main::$0 ← stackpull(word) [ main::$0 ] ( main:2 [ main::$0 ] ) always clobbers reg byte a
|
||||
Statement [8] *((const word*) SCREEN) ← (word~) main::$0 [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
Statement [10] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:5 [ plus::a#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement [11] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:5 [ plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement [12] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 [ plus::return#0 ] ( main:2::plus:5 [ plus::return#0 ] ) always clobbers reg byte a
|
||||
Statement [13] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0 [ ] ( main:2::plus:5 [ ] ) always clobbers reg byte a reg byte x
|
||||
Potential registers zp[2]:2 [ main::$0 ] : zp[2]:2 ,
|
||||
Potential registers zp[2]:4 [ plus::a#0 ] : zp[2]:4 ,
|
||||
Potential registers zp[2]:6 [ plus::b#0 ] : zp[2]:6 ,
|
||||
Potential registers zp[2]:8 [ plus::return#0 ] : zp[2]:8 ,
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [plus] 4: zp[2]:6 [ plus::b#0 ] 2: zp[2]:4 [ plus::a#0 ] 2: zp[2]:8 [ plus::return#0 ]
|
||||
Uplift Scope [main] 2: zp[2]:2 [ main::$0 ]
|
||||
Uplift Scope [plus] 4: zp[2]:6 [ plus::b#0 ] 4: zp[2]:8 [ plus::return#0 ] 2: zp[2]:4 [ plus::a#0 ]
|
||||
Uplift Scope [main] 4: zp[2]:2 [ main::$0 ]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [plus] best 164 combination zp[2]:6 [ plus::b#0 ] zp[2]:4 [ plus::a#0 ] zp[2]:8 [ plus::return#0 ]
|
||||
Uplifting [plus] best 164 combination zp[2]:6 [ plus::b#0 ] zp[2]:8 [ plus::return#0 ] zp[2]:4 [ plus::a#0 ]
|
||||
Uplifting [main] best 164 combination zp[2]:2 [ main::$0 ]
|
||||
Uplifting [] best 164 combination
|
||||
Coalescing zero page register [ zp[2]:4 [ plus::a#0 ] ] with [ zp[2]:8 [ plus::return#0 ] ] - score: 1
|
||||
@ -335,15 +342,15 @@ main: {
|
||||
pha
|
||||
// [5] callexecute plus -- jsr
|
||||
jsr plus
|
||||
// [6] (word~) main::$0 ← callfinalize plus -- _stackpullbyte_2
|
||||
// stackpull((number) 2) -- _stackpullbyte_2
|
||||
pla
|
||||
pla
|
||||
// [6] (word~) main::$0 ← callfinalize plus -- vwuz1=_stackpullword_
|
||||
// [7] (word~) main::$0 ← stackpull(word) -- vwuz1=_stackpullword_
|
||||
pla
|
||||
sta.z __0
|
||||
pla
|
||||
sta.z __0+1
|
||||
// [7] *((const word*) SCREEN) ← (word~) main::$0 -- _deref_pwuc1=vwuz1
|
||||
// [8] *((const word*) SCREEN) ← (word~) main::$0 -- _deref_pwuc1=vwuz1
|
||||
lda.z __0
|
||||
sta SCREEN
|
||||
lda.z __0+1
|
||||
@ -351,7 +358,7 @@ main: {
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [8] return
|
||||
// [9] return
|
||||
rts
|
||||
}
|
||||
// plus
|
||||
@ -363,19 +370,19 @@ plus: {
|
||||
.label a = 2
|
||||
.label b = 4
|
||||
.label return = 2
|
||||
// [9] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) -- vwuz1=_stackidxword_vbuc1
|
||||
// [10] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) -- vwuz1=_stackidxword_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_A,x
|
||||
sta.z a
|
||||
lda STACK_BASE+OFFSET_STACK_A+1,x
|
||||
sta.z a+1
|
||||
// [10] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) -- vwuz1=_stackidxword_vbuc1
|
||||
// [11] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) -- vwuz1=_stackidxword_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_B,x
|
||||
sta.z b
|
||||
lda STACK_BASE+OFFSET_STACK_B+1,x
|
||||
sta.z b+1
|
||||
// [11] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 -- vwuz1=vwuz1_plus_vwuz2
|
||||
// [12] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 -- vwuz1=vwuz1_plus_vwuz2
|
||||
lda.z return
|
||||
clc
|
||||
adc.z b
|
||||
@ -386,13 +393,13 @@ plus: {
|
||||
jmp __breturn
|
||||
// plus::@return
|
||||
__breturn:
|
||||
// [12] return (word) plus::return#0
|
||||
// [12] return (word) plus::return#0 -- _stackidxword_vbuc1=vwuz1
|
||||
// [13] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0 -- _stackidxword_vbuc1=vwuz1
|
||||
tsx
|
||||
lda.z return
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN,x
|
||||
lda.z return+1
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN+1,x
|
||||
// [14] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
@ -424,7 +431,7 @@ FINAL SYMBOL TABLE
|
||||
(const word*) SCREEN = (word*) 1024
|
||||
(const word) STACK_BASE = (word) $103
|
||||
(void()) main()
|
||||
(word~) main::$0 zp[2]:2 2.0
|
||||
(word~) main::$0 zp[2]:2 4.0
|
||||
(label) main::@return
|
||||
__stackcall (word()) plus((word) plus::a , (word) plus::b)
|
||||
(label) plus::@return
|
||||
@ -436,7 +443,7 @@ __stackcall (word()) plus((word) plus::a , (word) plus::b)
|
||||
(word) plus::b
|
||||
(word) plus::b#0 b zp[2]:4 4.0
|
||||
(word) plus::return
|
||||
(word) plus::return#0 return zp[2]:2 2.0
|
||||
(word) plus::return#0 return zp[2]:2 4.0
|
||||
|
||||
zp[2]:2 [ plus::a#0 plus::return#0 main::$0 ]
|
||||
zp[2]:4 [ plus::b#0 ]
|
||||
@ -476,23 +483,23 @@ main: {
|
||||
pha
|
||||
// [5] callexecute plus -- jsr
|
||||
jsr plus
|
||||
// [6] (word~) main::$0 ← callfinalize plus -- _stackpullbyte_2
|
||||
// stackpull((number) 2) -- _stackpullbyte_2
|
||||
pla
|
||||
pla
|
||||
// [6] (word~) main::$0 ← callfinalize plus -- vwuz1=_stackpullword_
|
||||
// [7] (word~) main::$0 ← stackpull(word) -- vwuz1=_stackpullword_
|
||||
pla
|
||||
sta.z __0
|
||||
pla
|
||||
sta.z __0+1
|
||||
// SCREEN[0] = plus(0x1234, 0x2345)
|
||||
// [7] *((const word*) SCREEN) ← (word~) main::$0 -- _deref_pwuc1=vwuz1
|
||||
// [8] *((const word*) SCREEN) ← (word~) main::$0 -- _deref_pwuc1=vwuz1
|
||||
lda.z __0
|
||||
sta SCREEN
|
||||
lda.z __0+1
|
||||
sta SCREEN+1
|
||||
// main::@return
|
||||
// }
|
||||
// [8] return
|
||||
// [9] return
|
||||
rts
|
||||
}
|
||||
// plus
|
||||
@ -504,20 +511,20 @@ plus: {
|
||||
.label a = 2
|
||||
.label b = 4
|
||||
.label return = 2
|
||||
// [9] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) -- vwuz1=_stackidxword_vbuc1
|
||||
// [10] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) -- vwuz1=_stackidxword_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_A,x
|
||||
sta.z a
|
||||
lda STACK_BASE+OFFSET_STACK_A+1,x
|
||||
sta.z a+1
|
||||
// [10] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) -- vwuz1=_stackidxword_vbuc1
|
||||
// [11] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) -- vwuz1=_stackidxword_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_B,x
|
||||
sta.z b
|
||||
lda STACK_BASE+OFFSET_STACK_B+1,x
|
||||
sta.z b+1
|
||||
// return a+b;
|
||||
// [11] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 -- vwuz1=vwuz1_plus_vwuz2
|
||||
// [12] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 -- vwuz1=vwuz1_plus_vwuz2
|
||||
lda.z return
|
||||
clc
|
||||
adc.z b
|
||||
@ -527,13 +534,13 @@ plus: {
|
||||
sta.z return+1
|
||||
// plus::@return
|
||||
// }
|
||||
// [12] return (word) plus::return#0
|
||||
// [12] return (word) plus::return#0 -- _stackidxword_vbuc1=vwuz1
|
||||
// [13] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0 -- _stackidxword_vbuc1=vwuz1
|
||||
tsx
|
||||
lda.z return
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN,x
|
||||
lda.z return+1
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN+1,x
|
||||
// [14] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
@ -4,7 +4,7 @@
|
||||
(const word*) SCREEN = (word*) 1024
|
||||
(const word) STACK_BASE = (word) $103
|
||||
(void()) main()
|
||||
(word~) main::$0 zp[2]:2 2.0
|
||||
(word~) main::$0 zp[2]:2 4.0
|
||||
(label) main::@return
|
||||
__stackcall (word()) plus((word) plus::a , (word) plus::b)
|
||||
(label) plus::@return
|
||||
@ -16,7 +16,7 @@ __stackcall (word()) plus((word) plus::a , (word) plus::b)
|
||||
(word) plus::b
|
||||
(word) plus::b#0 b zp[2]:4 4.0
|
||||
(word) plus::return
|
||||
(word) plus::return#0 return zp[2]:2 2.0
|
||||
(word) plus::return#0 return zp[2]:2 4.0
|
||||
|
||||
zp[2]:2 [ plus::a#0 plus::return#0 main::$0 ]
|
||||
zp[2]:4 [ plus::b#0 ]
|
||||
|
@ -12,19 +12,21 @@
|
||||
main: scope:[main] from @1
|
||||
[4] callprepare plus (byte) '0' (byte) 7
|
||||
[5] callexecute plus
|
||||
[6] (word~) main::$0 ← callfinalize plus
|
||||
[7] *((const word*) SCREEN) ← (word~) main::$0
|
||||
stackpull((number) 2)
|
||||
[7] (word~) main::$0 ← stackpull(word)
|
||||
[8] *((const word*) SCREEN) ← (word~) main::$0
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[8] return
|
||||
[9] return
|
||||
to:@return
|
||||
|
||||
__stackcall (word()) plus((word) plus::a , (word) plus::b)
|
||||
plus: scope:[plus] from
|
||||
[9] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A)
|
||||
[10] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B)
|
||||
[11] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0
|
||||
[10] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A)
|
||||
[11] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B)
|
||||
[12] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0
|
||||
to:plus::@return
|
||||
plus::@return: scope:[plus] from plus
|
||||
[12] return (word) plus::return#0
|
||||
[13] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0
|
||||
[14] return
|
||||
to:@return
|
||||
|
@ -4,6 +4,8 @@ Culled Empty Block (label) plus::@1
|
||||
Calling convention STACK_CALL adding prepare/execute/finalize for (word~) main::$0 ← call plus (byte) '0' (number) 7
|
||||
Calling convention STACK_CALL replacing param((word) plus::a) with stackidx(word,(const byte) plus::OFFSET_STACK_A)
|
||||
Calling convention STACK_CALL replacing param((word) plus::b) with stackidx(word,(const byte) plus::OFFSET_STACK_B)
|
||||
Calling convention STACK_CALL adding stack return stackidx(word,plus::OFFSET_STACK_RETURN) ← plus::return
|
||||
Calling convention STACK_CALL adding stack pull main::$0 ← stackpull(word)
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
@begin: scope:[] from
|
||||
@ -13,7 +15,8 @@ CONTROL FLOW GRAPH SSA
|
||||
main: scope:[main] from @2
|
||||
callprepare plus (byte) '0' (number) 7
|
||||
callexecute plus
|
||||
(word~) main::$0 ← callfinalize plus
|
||||
stackpull((number) 2)
|
||||
(word~) main::$0 ← stackpull(word)
|
||||
(number~) main::$1 ← (number) 0 * (const byte) SIZEOF_WORD
|
||||
*((const word*) SCREEN + (number~) main::$1) ← (word~) main::$0
|
||||
to:main::@return
|
||||
@ -30,7 +33,8 @@ plus: scope:[plus] from
|
||||
to:plus::@return
|
||||
plus::@return: scope:[plus] from plus
|
||||
(word) plus::return#1 ← phi( plus/(word) plus::return#0 )
|
||||
return (word) plus::return#1
|
||||
stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#1
|
||||
return
|
||||
to:@return
|
||||
@2: scope:[] from @begin
|
||||
call main
|
||||
@ -79,16 +83,15 @@ Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||
Inferred type updated to byte in (unumber~) main::$1 ← (byte) 0 * (const byte) SIZEOF_WORD
|
||||
Alias (word) plus::return#0 = (word~) plus::$0 (word) plus::return#1
|
||||
Successful SSA optimization Pass2AliasElimination
|
||||
Constant right-side identified [3] (byte~) main::$1 ← (byte) 0 * (const byte) SIZEOF_WORD
|
||||
Constant right-side identified [4] (byte~) main::$1 ← (byte) 0 * (const byte) SIZEOF_WORD
|
||||
Successful SSA optimization Pass2ConstantRValueConsolidation
|
||||
Constant (const byte) main::$1 = 0*SIZEOF_WORD
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Simplifying constant evaluating to zero (byte) 0*(const byte) SIZEOF_WORD in
|
||||
Successful SSA optimization PassNSimplifyConstantZero
|
||||
Simplifying expression containing zero SCREEN in [4] *((const word*) SCREEN + (const byte) main::$1) ← (word~) main::$0
|
||||
Simplifying expression containing zero SCREEN in [5] *((const word*) SCREEN + (const byte) main::$1) ← (word~) main::$0
|
||||
Successful SSA optimization PassNSimplifyExpressionWithZero
|
||||
Eliminating unused constant (const byte) main::$1
|
||||
Eliminating unused constant (const byte) plus::OFFSET_STACK_RETURN
|
||||
Eliminating unused constant (const byte) SIZEOF_WORD
|
||||
Successful SSA optimization PassNEliminateUnusedVars
|
||||
Adding NOP phi() at start of @begin
|
||||
@ -122,34 +125,36 @@ FINAL CONTROL FLOW GRAPH
|
||||
main: scope:[main] from @1
|
||||
[4] callprepare plus (byte) '0' (byte) 7
|
||||
[5] callexecute plus
|
||||
[6] (word~) main::$0 ← callfinalize plus
|
||||
[7] *((const word*) SCREEN) ← (word~) main::$0
|
||||
stackpull((number) 2)
|
||||
[7] (word~) main::$0 ← stackpull(word)
|
||||
[8] *((const word*) SCREEN) ← (word~) main::$0
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[8] return
|
||||
[9] return
|
||||
to:@return
|
||||
|
||||
__stackcall (word()) plus((word) plus::a , (word) plus::b)
|
||||
plus: scope:[plus] from
|
||||
[9] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A)
|
||||
[10] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B)
|
||||
[11] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0
|
||||
[10] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A)
|
||||
[11] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B)
|
||||
[12] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0
|
||||
to:plus::@return
|
||||
plus::@return: scope:[plus] from plus
|
||||
[12] return (word) plus::return#0
|
||||
[13] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0
|
||||
[14] return
|
||||
to:@return
|
||||
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
(void()) main()
|
||||
(word~) main::$0 2.0
|
||||
(word~) main::$0 4.0
|
||||
__stackcall (word()) plus((word) plus::a , (word) plus::b)
|
||||
(word) plus::a
|
||||
(word) plus::a#0 2.0
|
||||
(word) plus::b
|
||||
(word) plus::b#0 4.0
|
||||
(word) plus::return
|
||||
(word) plus::return#0 2.0
|
||||
(word) plus::return#0 4.0
|
||||
|
||||
Initial phi equivalence classes
|
||||
Added variable main::$0 to live range equivalence class [ main::$0 ]
|
||||
@ -209,15 +214,15 @@ main: {
|
||||
pha
|
||||
// [5] callexecute plus -- jsr
|
||||
jsr plus
|
||||
// [6] (word~) main::$0 ← callfinalize plus -- _stackpullbyte_2
|
||||
// stackpull((number) 2) -- _stackpullbyte_2
|
||||
pla
|
||||
pla
|
||||
// [6] (word~) main::$0 ← callfinalize plus -- vwuz1=_stackpullword_
|
||||
// [7] (word~) main::$0 ← stackpull(word) -- vwuz1=_stackpullword_
|
||||
pla
|
||||
sta.z __0
|
||||
pla
|
||||
sta.z __0+1
|
||||
// [7] *((const word*) SCREEN) ← (word~) main::$0 -- _deref_pwuc1=vwuz1
|
||||
// [8] *((const word*) SCREEN) ← (word~) main::$0 -- _deref_pwuc1=vwuz1
|
||||
lda.z __0
|
||||
sta SCREEN
|
||||
lda.z __0+1
|
||||
@ -225,7 +230,7 @@ main: {
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [8] return
|
||||
// [9] return
|
||||
rts
|
||||
}
|
||||
// plus
|
||||
@ -233,22 +238,23 @@ main: {
|
||||
plus: {
|
||||
.const OFFSET_STACK_A = 2
|
||||
.const OFFSET_STACK_B = 0
|
||||
.const OFFSET_STACK_RETURN = 2
|
||||
.label a = 4
|
||||
.label b = 6
|
||||
.label return = 8
|
||||
// [9] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) -- vwuz1=_stackidxword_vbuc1
|
||||
// [10] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) -- vwuz1=_stackidxword_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_A,x
|
||||
sta.z a
|
||||
lda STACK_BASE+OFFSET_STACK_A+1,x
|
||||
sta.z a+1
|
||||
// [10] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) -- vwuz1=_stackidxword_vbuc1
|
||||
// [11] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) -- vwuz1=_stackidxword_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_B,x
|
||||
sta.z b
|
||||
lda STACK_BASE+OFFSET_STACK_B+1,x
|
||||
sta.z b+1
|
||||
// [11] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 -- vwuz1=vwuz2_plus_vwuz3
|
||||
// [12] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 -- vwuz1=vwuz2_plus_vwuz3
|
||||
lda.z a
|
||||
clc
|
||||
adc.z b
|
||||
@ -259,36 +265,37 @@ plus: {
|
||||
jmp __breturn
|
||||
// plus::@return
|
||||
__breturn:
|
||||
// [12] return (word) plus::return#0
|
||||
// [12] return (word) plus::return#0 -- _stackidxword_vbuc1=vwuz1
|
||||
// [13] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0 -- _stackidxword_vbuc1=vwuz1
|
||||
tsx
|
||||
lda.z return
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN,x
|
||||
lda.z return+1
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN+1,x
|
||||
// [14] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Statement [4] callprepare plus (byte) '0' (byte) 7 [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
Statement [6] (word~) main::$0 ← callfinalize plus [ main::$0 ] ( main:2 [ main::$0 ] ) always clobbers reg byte a
|
||||
Statement [7] *((const word*) SCREEN) ← (word~) main::$0 [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
Statement [9] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:5 [ plus::a#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement [10] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:5 [ plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement [11] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 [ plus::return#0 ] ( main:2::plus:5 [ plus::return#0 ] ) always clobbers reg byte a
|
||||
Statement [12] return (word) plus::return#0 [ ] ( main:2::plus:5 [ ] ) always clobbers reg byte a reg byte x
|
||||
Statement stackpull((number) 2) always clobbers reg byte a
|
||||
Statement [7] (word~) main::$0 ← stackpull(word) [ main::$0 ] ( main:2 [ main::$0 ] ) always clobbers reg byte a
|
||||
Statement [8] *((const word*) SCREEN) ← (word~) main::$0 [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
Statement [10] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:5 [ plus::a#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement [11] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:5 [ plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement [12] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 [ plus::return#0 ] ( main:2::plus:5 [ plus::return#0 ] ) always clobbers reg byte a
|
||||
Statement [13] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0 [ ] ( main:2::plus:5 [ ] ) always clobbers reg byte a reg byte x
|
||||
Potential registers zp[2]:2 [ main::$0 ] : zp[2]:2 ,
|
||||
Potential registers zp[2]:4 [ plus::a#0 ] : zp[2]:4 ,
|
||||
Potential registers zp[2]:6 [ plus::b#0 ] : zp[2]:6 ,
|
||||
Potential registers zp[2]:8 [ plus::return#0 ] : zp[2]:8 ,
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [plus] 4: zp[2]:6 [ plus::b#0 ] 2: zp[2]:4 [ plus::a#0 ] 2: zp[2]:8 [ plus::return#0 ]
|
||||
Uplift Scope [main] 2: zp[2]:2 [ main::$0 ]
|
||||
Uplift Scope [plus] 4: zp[2]:6 [ plus::b#0 ] 4: zp[2]:8 [ plus::return#0 ] 2: zp[2]:4 [ plus::a#0 ]
|
||||
Uplift Scope [main] 4: zp[2]:2 [ main::$0 ]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [plus] best 164 combination zp[2]:6 [ plus::b#0 ] zp[2]:4 [ plus::a#0 ] zp[2]:8 [ plus::return#0 ]
|
||||
Uplifting [plus] best 164 combination zp[2]:6 [ plus::b#0 ] zp[2]:8 [ plus::return#0 ] zp[2]:4 [ plus::a#0 ]
|
||||
Uplifting [main] best 164 combination zp[2]:2 [ main::$0 ]
|
||||
Uplifting [] best 164 combination
|
||||
Coalescing zero page register [ zp[2]:4 [ plus::a#0 ] ] with [ zp[2]:8 [ plus::return#0 ] ] - score: 1
|
||||
@ -338,15 +345,15 @@ main: {
|
||||
pha
|
||||
// [5] callexecute plus -- jsr
|
||||
jsr plus
|
||||
// [6] (word~) main::$0 ← callfinalize plus -- _stackpullbyte_2
|
||||
// stackpull((number) 2) -- _stackpullbyte_2
|
||||
pla
|
||||
pla
|
||||
// [6] (word~) main::$0 ← callfinalize plus -- vwuz1=_stackpullword_
|
||||
// [7] (word~) main::$0 ← stackpull(word) -- vwuz1=_stackpullword_
|
||||
pla
|
||||
sta.z __0
|
||||
pla
|
||||
sta.z __0+1
|
||||
// [7] *((const word*) SCREEN) ← (word~) main::$0 -- _deref_pwuc1=vwuz1
|
||||
// [8] *((const word*) SCREEN) ← (word~) main::$0 -- _deref_pwuc1=vwuz1
|
||||
lda.z __0
|
||||
sta SCREEN
|
||||
lda.z __0+1
|
||||
@ -354,7 +361,7 @@ main: {
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [8] return
|
||||
// [9] return
|
||||
rts
|
||||
}
|
||||
// plus
|
||||
@ -366,19 +373,19 @@ plus: {
|
||||
.label a = 2
|
||||
.label b = 4
|
||||
.label return = 2
|
||||
// [9] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) -- vwuz1=_stackidxword_vbuc1
|
||||
// [10] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) -- vwuz1=_stackidxword_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_A,x
|
||||
sta.z a
|
||||
lda STACK_BASE+OFFSET_STACK_A+1,x
|
||||
sta.z a+1
|
||||
// [10] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) -- vwuz1=_stackidxword_vbuc1
|
||||
// [11] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) -- vwuz1=_stackidxword_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_B,x
|
||||
sta.z b
|
||||
lda STACK_BASE+OFFSET_STACK_B+1,x
|
||||
sta.z b+1
|
||||
// [11] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 -- vwuz1=vwuz1_plus_vwuz2
|
||||
// [12] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 -- vwuz1=vwuz1_plus_vwuz2
|
||||
lda.z return
|
||||
clc
|
||||
adc.z b
|
||||
@ -389,13 +396,13 @@ plus: {
|
||||
jmp __breturn
|
||||
// plus::@return
|
||||
__breturn:
|
||||
// [12] return (word) plus::return#0
|
||||
// [12] return (word) plus::return#0 -- _stackidxword_vbuc1=vwuz1
|
||||
// [13] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0 -- _stackidxword_vbuc1=vwuz1
|
||||
tsx
|
||||
lda.z return
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN,x
|
||||
lda.z return+1
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN+1,x
|
||||
// [14] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
@ -427,7 +434,7 @@ FINAL SYMBOL TABLE
|
||||
(const word*) SCREEN = (word*) 1024
|
||||
(const word) STACK_BASE = (word) $103
|
||||
(void()) main()
|
||||
(word~) main::$0 zp[2]:2 2.0
|
||||
(word~) main::$0 zp[2]:2 4.0
|
||||
(label) main::@return
|
||||
__stackcall (word()) plus((word) plus::a , (word) plus::b)
|
||||
(label) plus::@return
|
||||
@ -439,7 +446,7 @@ __stackcall (word()) plus((word) plus::a , (word) plus::b)
|
||||
(word) plus::b
|
||||
(word) plus::b#0 b zp[2]:4 4.0
|
||||
(word) plus::return
|
||||
(word) plus::return#0 return zp[2]:2 2.0
|
||||
(word) plus::return#0 return zp[2]:2 4.0
|
||||
|
||||
zp[2]:2 [ plus::a#0 plus::return#0 main::$0 ]
|
||||
zp[2]:4 [ plus::b#0 ]
|
||||
@ -482,23 +489,23 @@ main: {
|
||||
pha
|
||||
// [5] callexecute plus -- jsr
|
||||
jsr plus
|
||||
// [6] (word~) main::$0 ← callfinalize plus -- _stackpullbyte_2
|
||||
// stackpull((number) 2) -- _stackpullbyte_2
|
||||
pla
|
||||
pla
|
||||
// [6] (word~) main::$0 ← callfinalize plus -- vwuz1=_stackpullword_
|
||||
// [7] (word~) main::$0 ← stackpull(word) -- vwuz1=_stackpullword_
|
||||
pla
|
||||
sta.z __0
|
||||
pla
|
||||
sta.z __0+1
|
||||
// SCREEN[0] = plus('0', 7)
|
||||
// [7] *((const word*) SCREEN) ← (word~) main::$0 -- _deref_pwuc1=vwuz1
|
||||
// [8] *((const word*) SCREEN) ← (word~) main::$0 -- _deref_pwuc1=vwuz1
|
||||
lda.z __0
|
||||
sta SCREEN
|
||||
lda.z __0+1
|
||||
sta SCREEN+1
|
||||
// main::@return
|
||||
// }
|
||||
// [8] return
|
||||
// [9] return
|
||||
rts
|
||||
}
|
||||
// plus
|
||||
@ -510,20 +517,20 @@ plus: {
|
||||
.label a = 2
|
||||
.label b = 4
|
||||
.label return = 2
|
||||
// [9] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) -- vwuz1=_stackidxword_vbuc1
|
||||
// [10] (word) plus::a#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_A) -- vwuz1=_stackidxword_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_A,x
|
||||
sta.z a
|
||||
lda STACK_BASE+OFFSET_STACK_A+1,x
|
||||
sta.z a+1
|
||||
// [10] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) -- vwuz1=_stackidxword_vbuc1
|
||||
// [11] (word) plus::b#0 ← stackidx(word,(const byte) plus::OFFSET_STACK_B) -- vwuz1=_stackidxword_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_B,x
|
||||
sta.z b
|
||||
lda STACK_BASE+OFFSET_STACK_B+1,x
|
||||
sta.z b+1
|
||||
// return a+b;
|
||||
// [11] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 -- vwuz1=vwuz1_plus_vwuz2
|
||||
// [12] (word) plus::return#0 ← (word) plus::a#0 + (word) plus::b#0 -- vwuz1=vwuz1_plus_vwuz2
|
||||
lda.z return
|
||||
clc
|
||||
adc.z b
|
||||
@ -533,13 +540,13 @@ plus: {
|
||||
sta.z return+1
|
||||
// plus::@return
|
||||
// }
|
||||
// [12] return (word) plus::return#0
|
||||
// [12] return (word) plus::return#0 -- _stackidxword_vbuc1=vwuz1
|
||||
// [13] stackidx(word,(const byte) plus::OFFSET_STACK_RETURN) ← (word) plus::return#0 -- _stackidxword_vbuc1=vwuz1
|
||||
tsx
|
||||
lda.z return
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN,x
|
||||
lda.z return+1
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN+1,x
|
||||
// [14] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
@ -4,7 +4,7 @@
|
||||
(const word*) SCREEN = (word*) 1024
|
||||
(const word) STACK_BASE = (word) $103
|
||||
(void()) main()
|
||||
(word~) main::$0 zp[2]:2 2.0
|
||||
(word~) main::$0 zp[2]:2 4.0
|
||||
(label) main::@return
|
||||
__stackcall (word()) plus((word) plus::a , (word) plus::b)
|
||||
(label) plus::@return
|
||||
@ -16,7 +16,7 @@ __stackcall (word()) plus((word) plus::a , (word) plus::b)
|
||||
(word) plus::b
|
||||
(word) plus::b#0 b zp[2]:4 4.0
|
||||
(word) plus::return
|
||||
(word) plus::return#0 return zp[2]:2 2.0
|
||||
(word) plus::return#0 return zp[2]:2 4.0
|
||||
|
||||
zp[2]:2 [ plus::a#0 plus::return#0 main::$0 ]
|
||||
zp[2]:4 [ plus::b#0 ]
|
||||
|
@ -18,8 +18,8 @@ main: {
|
||||
txa
|
||||
pha
|
||||
jsr plus
|
||||
// w = plus('0', v)
|
||||
pla
|
||||
// w = plus('0', v)
|
||||
pla
|
||||
// w+a
|
||||
sty.z $ff
|
||||
|
@ -17,22 +17,24 @@ main::@1: scope:[main] from main main::@1
|
||||
[6] (byte) main::v#0 ← (byte) main::a#2 + (byte) 1
|
||||
[7] callprepare plus (byte) '0' (byte) main::v#0
|
||||
[8] callexecute plus
|
||||
[9] (byte) main::w#0 ← callfinalize plus
|
||||
[10] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2
|
||||
[11] *((const byte*) SCREEN) ← (byte~) main::$2
|
||||
[12] (byte) main::a#1 ← ++ (byte) main::a#2
|
||||
[13] if((byte) main::a#1!=(byte) 2) goto main::@1
|
||||
stackpull((number) 1)
|
||||
[10] (byte) main::w#0 ← stackpull(byte)
|
||||
[11] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2
|
||||
[12] *((const byte*) SCREEN) ← (byte~) main::$2
|
||||
[13] (byte) main::a#1 ← ++ (byte) main::a#2
|
||||
[14] if((byte) main::a#1!=(byte) 2) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[14] return
|
||||
[15] return
|
||||
to:@return
|
||||
|
||||
__stackcall (byte()) plus((byte) plus::a , (byte) plus::b)
|
||||
plus: scope:[plus] from
|
||||
[15] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A)
|
||||
[16] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B)
|
||||
[17] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0
|
||||
[16] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A)
|
||||
[17] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B)
|
||||
[18] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0
|
||||
to:plus::@return
|
||||
plus::@return: scope:[plus] from plus
|
||||
[18] return (byte) plus::return#0
|
||||
[19] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0
|
||||
[20] return
|
||||
to:@return
|
||||
|
@ -4,6 +4,8 @@ Culled Empty Block (label) plus::@1
|
||||
Calling convention STACK_CALL adding prepare/execute/finalize for (byte~) main::$1 ← call plus (byte) '0' (byte) main::v
|
||||
Calling convention STACK_CALL replacing param((byte) plus::a) with stackidx(byte,(const byte) plus::OFFSET_STACK_A)
|
||||
Calling convention STACK_CALL replacing param((byte) plus::b) with stackidx(byte,(const byte) plus::OFFSET_STACK_B)
|
||||
Calling convention STACK_CALL adding stack return stackidx(byte,plus::OFFSET_STACK_RETURN) ← plus::return
|
||||
Calling convention STACK_CALL adding stack pull main::$1 ← stackpull(byte)
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
@begin: scope:[] from
|
||||
@ -22,7 +24,8 @@ main::@1: scope:[main] from main main::@1
|
||||
(byte) main::v#0 ← (number~) main::$0
|
||||
callprepare plus (byte) '0' (byte) main::v#0
|
||||
callexecute plus
|
||||
(byte~) main::$1 ← callfinalize plus
|
||||
stackpull((number) 1)
|
||||
(byte~) main::$1 ← stackpull(byte)
|
||||
(byte) main::w#0 ← (byte~) main::$1
|
||||
(byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2
|
||||
*((const byte*) SCREEN + (byte) i#4) ← (byte~) main::$2
|
||||
@ -47,7 +50,8 @@ plus: scope:[plus] from
|
||||
to:plus::@return
|
||||
plus::@return: scope:[plus] from plus
|
||||
(byte) plus::return#1 ← phi( plus/(byte) plus::return#0 )
|
||||
return (byte) plus::return#1
|
||||
stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#1
|
||||
return
|
||||
to:@return
|
||||
@2: scope:[] from @begin
|
||||
(byte) i#9 ← phi( @begin/(byte) i#0 )
|
||||
@ -126,17 +130,16 @@ Identical Phi Values (byte) i#8 (byte) i#0
|
||||
Identical Phi Values (byte) i#1 (byte) i#8
|
||||
Identical Phi Values (byte) i#3 (byte) i#1
|
||||
Successful SSA optimization Pass2IdenticalPhiElimination
|
||||
Simple Condition (bool~) main::$3 [12] if((byte) main::a#1!=rangelast(0,1)) goto main::@1
|
||||
Simple Condition (bool~) main::$3 [13] if((byte) main::a#1!=rangelast(0,1)) goto main::@1
|
||||
Successful SSA optimization Pass2ConditionalJumpSimplification
|
||||
Constant (const byte) i#0 = 0
|
||||
Constant (const byte) main::a#0 = 0
|
||||
Successful SSA optimization Pass2ConstantIdentification
|
||||
Resolved ranged next value [10] main::a#1 ← ++ main::a#2 to ++
|
||||
Resolved ranged comparison value [12] if(main::a#1!=rangelast(0,1)) goto main::@1 to (number) 2
|
||||
Simplifying expression containing zero SCREEN in [9] *((const byte*) SCREEN + (const byte) i#0) ← (byte~) main::$2
|
||||
Resolved ranged next value [11] main::a#1 ← ++ main::a#2 to ++
|
||||
Resolved ranged comparison value [13] if(main::a#1!=rangelast(0,1)) goto main::@1 to (number) 2
|
||||
Simplifying expression containing zero SCREEN in [10] *((const byte*) SCREEN + (const byte) i#0) ← (byte~) main::$2
|
||||
Successful SSA optimization PassNSimplifyExpressionWithZero
|
||||
Eliminating unused variable (byte) i#2 and assignment [13] (byte) i#2 ← ++ (byte) i#6
|
||||
Eliminating unused constant (const byte) plus::OFFSET_STACK_RETURN
|
||||
Eliminating unused variable (byte) i#2 and assignment [14] (byte) i#2 ← ++ (byte) i#6
|
||||
Eliminating unused constant (const byte) i#0
|
||||
Successful SSA optimization PassNEliminateUnusedVars
|
||||
Eliminating unused variable - keeping the phi block (byte) i#6
|
||||
@ -161,7 +164,7 @@ Calls in [] to main:2
|
||||
Calls in [main] to plus:9
|
||||
|
||||
Created 1 initial phi equivalence classes
|
||||
Coalesced [16] main::a#3 ← main::a#1
|
||||
Coalesced [17] main::a#3 ← main::a#1
|
||||
Coalesced down to 1 phi equivalence classes
|
||||
Culled Empty Block (label) @3
|
||||
Culled Empty Block (label) main::@3
|
||||
@ -191,24 +194,26 @@ main::@1: scope:[main] from main main::@1
|
||||
[6] (byte) main::v#0 ← (byte) main::a#2 + (byte) 1
|
||||
[7] callprepare plus (byte) '0' (byte) main::v#0
|
||||
[8] callexecute plus
|
||||
[9] (byte) main::w#0 ← callfinalize plus
|
||||
[10] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2
|
||||
[11] *((const byte*) SCREEN) ← (byte~) main::$2
|
||||
[12] (byte) main::a#1 ← ++ (byte) main::a#2
|
||||
[13] if((byte) main::a#1!=(byte) 2) goto main::@1
|
||||
stackpull((number) 1)
|
||||
[10] (byte) main::w#0 ← stackpull(byte)
|
||||
[11] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2
|
||||
[12] *((const byte*) SCREEN) ← (byte~) main::$2
|
||||
[13] (byte) main::a#1 ← ++ (byte) main::a#2
|
||||
[14] if((byte) main::a#1!=(byte) 2) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[14] return
|
||||
[15] return
|
||||
to:@return
|
||||
|
||||
__stackcall (byte()) plus((byte) plus::a , (byte) plus::b)
|
||||
plus: scope:[plus] from
|
||||
[15] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A)
|
||||
[16] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B)
|
||||
[17] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0
|
||||
[16] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A)
|
||||
[17] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B)
|
||||
[18] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0
|
||||
to:plus::@return
|
||||
plus::@return: scope:[plus] from plus
|
||||
[18] return (byte) plus::return#0
|
||||
[19] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0
|
||||
[20] return
|
||||
to:@return
|
||||
|
||||
|
||||
@ -218,18 +223,18 @@ VARIABLE REGISTER WEIGHTS
|
||||
(byte~) main::$2 22.0
|
||||
(byte) main::a
|
||||
(byte) main::a#1 16.5
|
||||
(byte) main::a#2 6.285714285714286
|
||||
(byte) main::a#2 5.5
|
||||
(byte) main::v
|
||||
(byte) main::v#0 11.0
|
||||
(byte) main::w
|
||||
(byte) main::w#0 11.0
|
||||
(byte) main::w#0 22.0
|
||||
__stackcall (byte()) plus((byte) plus::a , (byte) plus::b)
|
||||
(byte) plus::a
|
||||
(byte) plus::a#0 2.0
|
||||
(byte) plus::b
|
||||
(byte) plus::b#0 4.0
|
||||
(byte) plus::return
|
||||
(byte) plus::return#0 2.0
|
||||
(byte) plus::return#0 4.0
|
||||
|
||||
Initial phi equivalence classes
|
||||
[ main::a#2 main::a#1 ]
|
||||
@ -313,29 +318,29 @@ main: {
|
||||
pha
|
||||
// [8] callexecute plus -- jsr
|
||||
jsr plus
|
||||
// [9] (byte) main::w#0 ← callfinalize plus -- _stackpullbyte_1
|
||||
// stackpull((number) 1) -- _stackpullbyte_1
|
||||
pla
|
||||
// [9] (byte) main::w#0 ← callfinalize plus -- vbuz1=_stackpullbyte_
|
||||
// [10] (byte) main::w#0 ← stackpull(byte) -- vbuz1=_stackpullbyte_
|
||||
pla
|
||||
sta.z w
|
||||
// [10] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 -- vbuz1=vbuz2_plus_vbuz3
|
||||
// [11] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 -- vbuz1=vbuz2_plus_vbuz3
|
||||
lda.z w
|
||||
clc
|
||||
adc.z a
|
||||
sta.z __2
|
||||
// [11] *((const byte*) SCREEN) ← (byte~) main::$2 -- _deref_pbuc1=vbuz1
|
||||
// [12] *((const byte*) SCREEN) ← (byte~) main::$2 -- _deref_pbuc1=vbuz1
|
||||
lda.z __2
|
||||
sta SCREEN
|
||||
// [12] (byte) main::a#1 ← ++ (byte) main::a#2 -- vbuz1=_inc_vbuz1
|
||||
// [13] (byte) main::a#1 ← ++ (byte) main::a#2 -- vbuz1=_inc_vbuz1
|
||||
inc.z a
|
||||
// [13] if((byte) main::a#1!=(byte) 2) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
|
||||
// [14] if((byte) main::a#1!=(byte) 2) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
|
||||
lda #2
|
||||
cmp.z a
|
||||
bne __b1_from___b1
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [14] return
|
||||
// [15] return
|
||||
rts
|
||||
}
|
||||
// plus
|
||||
@ -343,18 +348,19 @@ main: {
|
||||
plus: {
|
||||
.const OFFSET_STACK_A = 1
|
||||
.const OFFSET_STACK_B = 0
|
||||
.const OFFSET_STACK_RETURN = 1
|
||||
.label a = 6
|
||||
.label b = 7
|
||||
.label return = 8
|
||||
// [15] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1
|
||||
// [16] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_A,x
|
||||
sta.z a
|
||||
// [16] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuz1=_stackidxbyte_vbuc1
|
||||
// [17] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuz1=_stackidxbyte_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_B,x
|
||||
sta.z b
|
||||
// [17] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuz1=vbuz2_plus_vbuz3
|
||||
// [18] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuz1=vbuz2_plus_vbuz3
|
||||
lda.z a
|
||||
clc
|
||||
adc.z b
|
||||
@ -362,11 +368,11 @@ plus: {
|
||||
jmp __breturn
|
||||
// plus::@return
|
||||
__breturn:
|
||||
// [18] return (byte) plus::return#0
|
||||
// [18] return (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuz1
|
||||
// [19] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuz1
|
||||
lda.z return
|
||||
tsx
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN,x
|
||||
// [20] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
@ -374,22 +380,24 @@ plus: {
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Statement [7] callprepare plus (byte) '0' (byte) main::v#0 [ main::a#2 ] ( main:2 [ main::a#2 ] ) always clobbers reg byte a
|
||||
Removing always clobbered register reg byte a as potential for zp[1]:2 [ main::a#2 main::a#1 ]
|
||||
Statement [9] (byte) main::w#0 ← callfinalize plus [ main::a#2 main::w#0 ] ( main:2 [ main::a#2 main::w#0 ] ) always clobbers reg byte a
|
||||
Statement [10] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 [ main::a#2 main::$2 ] ( main:2 [ main::a#2 main::$2 ] ) always clobbers reg byte a
|
||||
Statement [15] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:8 [ main::a#2 plus::a#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement stackpull((number) 1) always clobbers reg byte a
|
||||
Statement [10] (byte) main::w#0 ← stackpull(byte) [ main::a#2 main::w#0 ] ( main:2 [ main::a#2 main::w#0 ] ) always clobbers reg byte a
|
||||
Statement [11] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 [ main::a#2 main::$2 ] ( main:2 [ main::a#2 main::$2 ] ) always clobbers reg byte a
|
||||
Statement [16] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:8 [ main::a#2 plus::a#0 ] ) always clobbers reg byte a reg byte x
|
||||
Removing always clobbered register reg byte x as potential for zp[1]:2 [ main::a#2 main::a#1 ]
|
||||
Statement [16] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:8 [ main::a#2 plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement [17] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:8 [ main::a#2 plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x
|
||||
Removing always clobbered register reg byte a as potential for zp[1]:6 [ plus::a#0 ]
|
||||
Removing always clobbered register reg byte x as potential for zp[1]:6 [ plus::a#0 ]
|
||||
Statement [17] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 [ plus::return#0 ] ( main:2::plus:8 [ main::a#2 plus::return#0 ] ) always clobbers reg byte a
|
||||
Statement [18] return (byte) plus::return#0 [ ] ( main:2::plus:8 [ main::a#2 ] ) always clobbers reg byte x
|
||||
Statement [18] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 [ plus::return#0 ] ( main:2::plus:8 [ main::a#2 plus::return#0 ] ) always clobbers reg byte a
|
||||
Statement [19] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 [ ] ( main:2::plus:8 [ main::a#2 ] ) always clobbers reg byte x
|
||||
Statement [7] callprepare plus (byte) '0' (byte) main::v#0 [ main::a#2 ] ( main:2 [ main::a#2 ] ) always clobbers reg byte a
|
||||
Statement [9] (byte) main::w#0 ← callfinalize plus [ main::a#2 main::w#0 ] ( main:2 [ main::a#2 main::w#0 ] ) always clobbers reg byte a
|
||||
Statement [10] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 [ main::a#2 main::$2 ] ( main:2 [ main::a#2 main::$2 ] ) always clobbers reg byte a
|
||||
Statement [15] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:8 [ main::a#2 plus::a#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement [16] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:8 [ main::a#2 plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement [17] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 [ plus::return#0 ] ( main:2::plus:8 [ main::a#2 plus::return#0 ] ) always clobbers reg byte a
|
||||
Statement [18] return (byte) plus::return#0 [ ] ( main:2::plus:8 [ main::a#2 ] ) always clobbers reg byte x
|
||||
Statement stackpull((number) 1) always clobbers reg byte a
|
||||
Statement [10] (byte) main::w#0 ← stackpull(byte) [ main::a#2 main::w#0 ] ( main:2 [ main::a#2 main::w#0 ] ) always clobbers reg byte a
|
||||
Statement [11] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 [ main::a#2 main::$2 ] ( main:2 [ main::a#2 main::$2 ] ) always clobbers reg byte a
|
||||
Statement [16] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) [ plus::a#0 ] ( main:2::plus:8 [ main::a#2 plus::a#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement [17] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) [ plus::a#0 plus::b#0 ] ( main:2::plus:8 [ main::a#2 plus::a#0 plus::b#0 ] ) always clobbers reg byte a reg byte x
|
||||
Statement [18] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 [ plus::return#0 ] ( main:2::plus:8 [ main::a#2 plus::return#0 ] ) always clobbers reg byte a
|
||||
Statement [19] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 [ ] ( main:2::plus:8 [ main::a#2 ] ) always clobbers reg byte x
|
||||
Potential registers zp[1]:2 [ main::a#2 main::a#1 ] : zp[1]:2 , reg byte y ,
|
||||
Potential registers zp[1]:3 [ main::v#0 ] : zp[1]:3 , reg byte a , reg byte x , reg byte y ,
|
||||
Potential registers zp[1]:4 [ main::w#0 ] : zp[1]:4 , reg byte a , reg byte x , reg byte y ,
|
||||
@ -399,13 +407,13 @@ Potential registers zp[1]:7 [ plus::b#0 ] : zp[1]:7 , reg byte a , reg byte x ,
|
||||
Potential registers zp[1]:8 [ plus::return#0 ] : zp[1]:8 , reg byte a , reg byte x , reg byte y ,
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [main] 22.79: zp[1]:2 [ main::a#2 main::a#1 ] 22: zp[1]:5 [ main::$2 ] 11: zp[1]:3 [ main::v#0 ] 11: zp[1]:4 [ main::w#0 ]
|
||||
Uplift Scope [plus] 4: zp[1]:7 [ plus::b#0 ] 2: zp[1]:6 [ plus::a#0 ] 2: zp[1]:8 [ plus::return#0 ]
|
||||
Uplift Scope [main] 22: zp[1]:2 [ main::a#2 main::a#1 ] 22: zp[1]:4 [ main::w#0 ] 22: zp[1]:5 [ main::$2 ] 11: zp[1]:3 [ main::v#0 ]
|
||||
Uplift Scope [plus] 4: zp[1]:7 [ plus::b#0 ] 4: zp[1]:8 [ plus::return#0 ] 2: zp[1]:6 [ plus::a#0 ]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [main] best 661 combination reg byte y [ main::a#2 main::a#1 ] reg byte a [ main::$2 ] reg byte x [ main::v#0 ] reg byte a [ main::w#0 ]
|
||||
Uplifting [main] best 661 combination reg byte y [ main::a#2 main::a#1 ] reg byte a [ main::w#0 ] reg byte a [ main::$2 ] reg byte x [ main::v#0 ]
|
||||
Limited combination testing to 100 combinations of 128 possible.
|
||||
Uplifting [plus] best 649 combination reg byte a [ plus::b#0 ] zp[1]:6 [ plus::a#0 ] reg byte a [ plus::return#0 ]
|
||||
Uplifting [plus] best 649 combination reg byte a [ plus::b#0 ] reg byte a [ plus::return#0 ] zp[1]:6 [ plus::a#0 ]
|
||||
Uplifting [] best 649 combination
|
||||
Attempting to uplift remaining variables inzp[1]:6 [ plus::a#0 ]
|
||||
Uplifting [plus] best 649 combination zp[1]:6 [ plus::a#0 ]
|
||||
@ -463,25 +471,25 @@ main: {
|
||||
pha
|
||||
// [8] callexecute plus -- jsr
|
||||
jsr plus
|
||||
// [9] (byte) main::w#0 ← callfinalize plus -- _stackpullbyte_1
|
||||
// stackpull((number) 1) -- _stackpullbyte_1
|
||||
pla
|
||||
// [9] (byte) main::w#0 ← callfinalize plus -- vbuaa=_stackpullbyte_
|
||||
// [10] (byte) main::w#0 ← stackpull(byte) -- vbuaa=_stackpullbyte_
|
||||
pla
|
||||
// [10] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 -- vbuaa=vbuaa_plus_vbuyy
|
||||
// [11] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 -- vbuaa=vbuaa_plus_vbuyy
|
||||
sty.z $ff
|
||||
clc
|
||||
adc.z $ff
|
||||
// [11] *((const byte*) SCREEN) ← (byte~) main::$2 -- _deref_pbuc1=vbuaa
|
||||
// [12] *((const byte*) SCREEN) ← (byte~) main::$2 -- _deref_pbuc1=vbuaa
|
||||
sta SCREEN
|
||||
// [12] (byte) main::a#1 ← ++ (byte) main::a#2 -- vbuyy=_inc_vbuyy
|
||||
// [13] (byte) main::a#1 ← ++ (byte) main::a#2 -- vbuyy=_inc_vbuyy
|
||||
iny
|
||||
// [13] if((byte) main::a#1!=(byte) 2) goto main::@1 -- vbuyy_neq_vbuc1_then_la1
|
||||
// [14] if((byte) main::a#1!=(byte) 2) goto main::@1 -- vbuyy_neq_vbuc1_then_la1
|
||||
cpy #2
|
||||
bne __b1_from___b1
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [14] return
|
||||
// [15] return
|
||||
rts
|
||||
}
|
||||
// plus
|
||||
@ -491,23 +499,23 @@ plus: {
|
||||
.const OFFSET_STACK_B = 0
|
||||
.const OFFSET_STACK_RETURN = 1
|
||||
.label a = 2
|
||||
// [15] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1
|
||||
// [16] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_A,x
|
||||
sta.z a
|
||||
// [16] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuaa=_stackidxbyte_vbuc1
|
||||
// [17] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuaa=_stackidxbyte_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_B,x
|
||||
// [17] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuaa=vbuz1_plus_vbuaa
|
||||
// [18] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuaa=vbuz1_plus_vbuaa
|
||||
clc
|
||||
adc.z a
|
||||
jmp __breturn
|
||||
// plus::@return
|
||||
__breturn:
|
||||
// [18] return (byte) plus::return#0
|
||||
// [18] return (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuaa
|
||||
// [19] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuaa
|
||||
tsx
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN,x
|
||||
// [20] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
@ -552,11 +560,11 @@ FINAL SYMBOL TABLE
|
||||
(label) main::@return
|
||||
(byte) main::a
|
||||
(byte) main::a#1 reg byte y 16.5
|
||||
(byte) main::a#2 reg byte y 6.285714285714286
|
||||
(byte) main::a#2 reg byte y 5.5
|
||||
(byte) main::v
|
||||
(byte) main::v#0 reg byte x 11.0
|
||||
(byte) main::w
|
||||
(byte) main::w#0 reg byte a 11.0
|
||||
(byte) main::w#0 reg byte a 22.0
|
||||
__stackcall (byte()) plus((byte) plus::a , (byte) plus::b)
|
||||
(label) plus::@return
|
||||
(const byte) plus::OFFSET_STACK_A = (byte) 1
|
||||
@ -567,7 +575,7 @@ __stackcall (byte()) plus((byte) plus::a , (byte) plus::b)
|
||||
(byte) plus::b
|
||||
(byte) plus::b#0 reg byte a 4.0
|
||||
(byte) plus::return
|
||||
(byte) plus::return#0 reg byte a 2.0
|
||||
(byte) plus::return#0 reg byte a 4.0
|
||||
|
||||
reg byte y [ main::a#2 main::a#1 ]
|
||||
reg byte x [ main::v#0 ]
|
||||
@ -621,28 +629,28 @@ main: {
|
||||
pha
|
||||
// [8] callexecute plus -- jsr
|
||||
jsr plus
|
||||
// w = plus('0', v)
|
||||
// [9] (byte) main::w#0 ← callfinalize plus -- _stackpullbyte_1
|
||||
// stackpull((number) 1) -- _stackpullbyte_1
|
||||
pla
|
||||
// [9] (byte) main::w#0 ← callfinalize plus -- vbuaa=_stackpullbyte_
|
||||
// w = plus('0', v)
|
||||
// [10] (byte) main::w#0 ← stackpull(byte) -- vbuaa=_stackpullbyte_
|
||||
pla
|
||||
// w+a
|
||||
// [10] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 -- vbuaa=vbuaa_plus_vbuyy
|
||||
// [11] (byte~) main::$2 ← (byte) main::w#0 + (byte) main::a#2 -- vbuaa=vbuaa_plus_vbuyy
|
||||
sty.z $ff
|
||||
clc
|
||||
adc.z $ff
|
||||
// SCREEN[i] = w+a
|
||||
// [11] *((const byte*) SCREEN) ← (byte~) main::$2 -- _deref_pbuc1=vbuaa
|
||||
// [12] *((const byte*) SCREEN) ← (byte~) main::$2 -- _deref_pbuc1=vbuaa
|
||||
sta SCREEN
|
||||
// for(char a:0..1)
|
||||
// [12] (byte) main::a#1 ← ++ (byte) main::a#2 -- vbuyy=_inc_vbuyy
|
||||
// [13] (byte) main::a#1 ← ++ (byte) main::a#2 -- vbuyy=_inc_vbuyy
|
||||
iny
|
||||
// [13] if((byte) main::a#1!=(byte) 2) goto main::@1 -- vbuyy_neq_vbuc1_then_la1
|
||||
// [14] if((byte) main::a#1!=(byte) 2) goto main::@1 -- vbuyy_neq_vbuc1_then_la1
|
||||
cpy #2
|
||||
bne __b1
|
||||
// main::@return
|
||||
// }
|
||||
// [14] return
|
||||
// [15] return
|
||||
rts
|
||||
}
|
||||
// plus
|
||||
@ -652,23 +660,23 @@ plus: {
|
||||
.const OFFSET_STACK_B = 0
|
||||
.const OFFSET_STACK_RETURN = 1
|
||||
.label a = 2
|
||||
// [15] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1
|
||||
// [16] (byte) plus::a#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_A) -- vbuz1=_stackidxbyte_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_A,x
|
||||
sta.z a
|
||||
// [16] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuaa=_stackidxbyte_vbuc1
|
||||
// [17] (byte) plus::b#0 ← stackidx(byte,(const byte) plus::OFFSET_STACK_B) -- vbuaa=_stackidxbyte_vbuc1
|
||||
tsx
|
||||
lda STACK_BASE+OFFSET_STACK_B,x
|
||||
// return a+b;
|
||||
// [17] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuaa=vbuz1_plus_vbuaa
|
||||
// [18] (byte) plus::return#0 ← (byte) plus::a#0 + (byte) plus::b#0 -- vbuaa=vbuz1_plus_vbuaa
|
||||
clc
|
||||
adc.z a
|
||||
// plus::@return
|
||||
// }
|
||||
// [18] return (byte) plus::return#0
|
||||
// [18] return (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuaa
|
||||
// [19] stackidx(byte,(const byte) plus::OFFSET_STACK_RETURN) ← (byte) plus::return#0 -- _stackidxbyte_vbuc1=vbuaa
|
||||
tsx
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN,x
|
||||
// [20] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
@ -10,11 +10,11 @@
|
||||
(label) main::@return
|
||||
(byte) main::a
|
||||
(byte) main::a#1 reg byte y 16.5
|
||||
(byte) main::a#2 reg byte y 6.285714285714286
|
||||
(byte) main::a#2 reg byte y 5.5
|
||||
(byte) main::v
|
||||
(byte) main::v#0 reg byte x 11.0
|
||||
(byte) main::w
|
||||
(byte) main::w#0 reg byte a 11.0
|
||||
(byte) main::w#0 reg byte a 22.0
|
||||
__stackcall (byte()) plus((byte) plus::a , (byte) plus::b)
|
||||
(label) plus::@return
|
||||
(const byte) plus::OFFSET_STACK_A = (byte) 1
|
||||
@ -25,7 +25,7 @@ __stackcall (byte()) plus((byte) plus::a , (byte) plus::b)
|
||||
(byte) plus::b
|
||||
(byte) plus::b#0 reg byte a 4.0
|
||||
(byte) plus::return
|
||||
(byte) plus::return#0 reg byte a 2.0
|
||||
(byte) plus::return#0 reg byte a 4.0
|
||||
|
||||
reg byte y [ main::a#2 main::a#1 ]
|
||||
reg byte x [ main::v#0 ]
|
||||
|
@ -12,11 +12,11 @@
|
||||
main: scope:[main] from @1
|
||||
[4] callprepare next
|
||||
[5] callexecute next
|
||||
[6] (signed word~) main::$0 ← callfinalize next
|
||||
[6] (signed word~) main::$0 ← stackpull(signed word)
|
||||
[7] *((const signed word*) SCREEN) ← (signed word~) main::$0
|
||||
[8] callprepare next
|
||||
[9] callexecute next
|
||||
[10] (signed word~) main::$1 ← callfinalize next
|
||||
[10] (signed word~) main::$1 ← stackpull(signed word)
|
||||
[11] *((const signed word*) SCREEN+(byte) 1*(const byte) SIZEOF_SIGNED_WORD) ← (signed word~) main::$1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
@ -29,5 +29,6 @@ next: scope:[next] from
|
||||
[14] (signed word) next::return#0 ← (signed word) current#5
|
||||
to:next::@return
|
||||
next::@return: scope:[next] from next
|
||||
[15] return (signed word) next::return#0
|
||||
[15] stackidx(signed word,(const byte) next::OFFSET_STACK_RETURN) ← (signed word) next::return#0
|
||||
[16] return
|
||||
to:@return
|
||||
|
@ -3,6 +3,9 @@ Fixing pointer array-indexing *((const signed word*) SCREEN + (number) 1)
|
||||
Culled Empty Block (label) next::@1
|
||||
Calling convention STACK_CALL adding prepare/execute/finalize for (signed word~) main::$0 ← call next
|
||||
Calling convention STACK_CALL adding prepare/execute/finalize for (signed word~) main::$1 ← call next
|
||||
Calling convention STACK_CALL adding stack return stackidx(signed word,next::OFFSET_STACK_RETURN) ← next::return
|
||||
Calling convention STACK_CALL adding stack pull main::$0 ← stackpull(signed word)
|
||||
Calling convention STACK_CALL adding stack pull main::$1 ← stackpull(signed word)
|
||||
|
||||
CONTROL FLOW GRAPH SSA
|
||||
@begin: scope:[] from
|
||||
@ -13,12 +16,12 @@ main: scope:[main] from @2
|
||||
(signed word) current#7 ← phi( @2/(signed word) current#8 )
|
||||
callprepare next
|
||||
callexecute next
|
||||
(signed word~) main::$0 ← callfinalize next
|
||||
(signed word~) main::$0 ← stackpull(signed word)
|
||||
(number~) main::$2 ← (number) 0 * (const byte) SIZEOF_SIGNED_WORD
|
||||
*((const signed word*) SCREEN + (number~) main::$2) ← (signed word~) main::$0
|
||||
callprepare next
|
||||
callexecute next
|
||||
(signed word~) main::$1 ← callfinalize next
|
||||
(signed word~) main::$1 ← stackpull(signed word)
|
||||
(number~) main::$3 ← (number) 1 * (const byte) SIZEOF_SIGNED_WORD
|
||||
*((const signed word*) SCREEN + (number~) main::$3) ← (signed word~) main::$1
|
||||
to:main::@return
|
||||
@ -39,7 +42,8 @@ next: scope:[next] from
|
||||
to:next::@return
|
||||
next::@return: scope:[next] from next
|
||||
(signed word) next::return#1 ← phi( next/(signed word) next::return#0 )
|
||||
return (signed word) next::return#1
|
||||
stackidx(signed word,(const byte) next::OFFSET_STACK_RETURN) ← (signed word) next::return#1
|
||||
return
|
||||
to:@return
|
||||
@2: scope:[] from @1
|
||||
(signed word) current#8 ← phi( @1/(signed word) current#1 )
|
||||
@ -118,7 +122,6 @@ Simplifying expression containing zero SCREEN in [5] *((const signed word*) SCRE
|
||||
Successful SSA optimization PassNSimplifyExpressionWithZero
|
||||
Eliminating unused variable (signed word) current#2 and assignment [11] (signed word) current#2 ← ++ (signed word) current#5
|
||||
Eliminating unused constant (const byte) main::$2
|
||||
Eliminating unused constant (const byte) next::OFFSET_STACK_RETURN
|
||||
Eliminating unused constant (const signed word) current#1
|
||||
Successful SSA optimization PassNEliminateUnusedVars
|
||||
Constant inlined main::$3 = (byte) 1*(const byte) SIZEOF_SIGNED_WORD
|
||||
@ -158,11 +161,11 @@ FINAL CONTROL FLOW GRAPH
|
||||
main: scope:[main] from @1
|
||||
[4] callprepare next
|
||||
[5] callexecute next
|
||||
[6] (signed word~) main::$0 ← callfinalize next
|
||||
[6] (signed word~) main::$0 ← stackpull(signed word)
|
||||
[7] *((const signed word*) SCREEN) ← (signed word~) main::$0
|
||||
[8] callprepare next
|
||||
[9] callexecute next
|
||||
[10] (signed word~) main::$1 ← callfinalize next
|
||||
[10] (signed word~) main::$1 ← stackpull(signed word)
|
||||
[11] *((const signed word*) SCREEN+(byte) 1*(const byte) SIZEOF_SIGNED_WORD) ← (signed word~) main::$1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
@ -175,7 +178,8 @@ next: scope:[next] from
|
||||
[14] (signed word) next::return#0 ← (signed word) current#5
|
||||
to:next::@return
|
||||
next::@return: scope:[next] from next
|
||||
[15] return (signed word) next::return#0
|
||||
[15] stackidx(signed word,(const byte) next::OFFSET_STACK_RETURN) ← (signed word) next::return#0
|
||||
[16] return
|
||||
to:@return
|
||||
|
||||
|
||||
@ -183,11 +187,11 @@ VARIABLE REGISTER WEIGHTS
|
||||
(signed word) current
|
||||
(signed word) current#5 2.0
|
||||
(void()) main()
|
||||
(signed word~) main::$0 2.0
|
||||
(signed word~) main::$1 2.0
|
||||
(signed word~) main::$0 4.0
|
||||
(signed word~) main::$1 4.0
|
||||
__stackcall (signed word()) next()
|
||||
(signed word) next::return
|
||||
(signed word) next::return#0 2.0
|
||||
(signed word) next::return#0 4.0
|
||||
|
||||
Initial phi equivalence classes
|
||||
[ current#5 ]
|
||||
@ -241,7 +245,7 @@ main: {
|
||||
pha
|
||||
// [5] callexecute next -- jsr
|
||||
jsr next
|
||||
// [6] (signed word~) main::$0 ← callfinalize next -- vwsz1=_stackpullsword_
|
||||
// [6] (signed word~) main::$0 ← stackpull(signed word) -- vwsz1=_stackpullsword_
|
||||
pla
|
||||
sta.z __0
|
||||
pla
|
||||
@ -256,7 +260,7 @@ main: {
|
||||
pha
|
||||
// [9] callexecute next -- jsr
|
||||
jsr next
|
||||
// [10] (signed word~) main::$1 ← callfinalize next -- vwsz1=_stackpullsword_
|
||||
// [10] (signed word~) main::$1 ← stackpull(signed word) -- vwsz1=_stackpullsword_
|
||||
pla
|
||||
sta.z __1
|
||||
pla
|
||||
@ -274,6 +278,7 @@ main: {
|
||||
}
|
||||
// next
|
||||
next: {
|
||||
.const OFFSET_STACK_RETURN = 0
|
||||
.label return = 8
|
||||
// [14] (signed word) next::return#0 ← (signed word) current#5 -- vwsz1=vwsz2
|
||||
lda.z current
|
||||
@ -283,32 +288,32 @@ next: {
|
||||
jmp __breturn
|
||||
// next::@return
|
||||
__breturn:
|
||||
// [15] return (signed word) next::return#0
|
||||
// [15] return (signed word) next::return#0 -- _stackidxsword_vbuc1=vwsz1
|
||||
// [15] stackidx(signed word,(const byte) next::OFFSET_STACK_RETURN) ← (signed word) next::return#0 -- _stackidxsword_vbuc1=vwsz1
|
||||
tsx
|
||||
lda.z return
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN,x
|
||||
lda.z return+1
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN+1,x
|
||||
// [16] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Statement [6] (signed word~) main::$0 ← callfinalize next [ main::$0 ] ( main:2 [ main::$0 ] ) always clobbers reg byte a
|
||||
Statement [6] (signed word~) main::$0 ← stackpull(signed word) [ main::$0 ] ( main:2 [ main::$0 ] ) always clobbers reg byte a
|
||||
Statement [7] *((const signed word*) SCREEN) ← (signed word~) main::$0 [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
Statement [10] (signed word~) main::$1 ← callfinalize next [ main::$1 ] ( main:2 [ main::$1 ] ) always clobbers reg byte a
|
||||
Statement [10] (signed word~) main::$1 ← stackpull(signed word) [ main::$1 ] ( main:2 [ main::$1 ] ) always clobbers reg byte a
|
||||
Statement [11] *((const signed word*) SCREEN+(byte) 1*(const byte) SIZEOF_SIGNED_WORD) ← (signed word~) main::$1 [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
Statement [14] (signed word) next::return#0 ← (signed word) current#5 [ next::return#0 ] ( main:2::next:5 [ next::return#0 ] main:2::next:9 [ next::return#0 ] ) always clobbers reg byte a
|
||||
Statement [15] return (signed word) next::return#0 [ ] ( main:2::next:5 [ ] main:2::next:9 [ ] ) always clobbers reg byte a reg byte x
|
||||
Statement [15] stackidx(signed word,(const byte) next::OFFSET_STACK_RETURN) ← (signed word) next::return#0 [ ] ( main:2::next:5 [ ] main:2::next:9 [ ] ) always clobbers reg byte a reg byte x
|
||||
Potential registers zp[2]:2 [ current#5 ] : zp[2]:2 ,
|
||||
Potential registers zp[2]:4 [ main::$0 ] : zp[2]:4 ,
|
||||
Potential registers zp[2]:6 [ main::$1 ] : zp[2]:6 ,
|
||||
Potential registers zp[2]:8 [ next::return#0 ] : zp[2]:8 ,
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [main] 2: zp[2]:4 [ main::$0 ] 2: zp[2]:6 [ main::$1 ]
|
||||
Uplift Scope [next] 2: zp[2]:8 [ next::return#0 ]
|
||||
Uplift Scope [main] 4: zp[2]:4 [ main::$0 ] 4: zp[2]:6 [ main::$1 ]
|
||||
Uplift Scope [next] 4: zp[2]:8 [ next::return#0 ]
|
||||
Uplift Scope [] 2: zp[2]:2 [ current#5 ]
|
||||
|
||||
Uplifting [main] best 140 combination zp[2]:4 [ main::$0 ] zp[2]:6 [ main::$1 ]
|
||||
@ -355,7 +360,7 @@ main: {
|
||||
pha
|
||||
// [5] callexecute next -- jsr
|
||||
jsr next
|
||||
// [6] (signed word~) main::$0 ← callfinalize next -- vwsz1=_stackpullsword_
|
||||
// [6] (signed word~) main::$0 ← stackpull(signed word) -- vwsz1=_stackpullsword_
|
||||
pla
|
||||
sta.z __0
|
||||
pla
|
||||
@ -370,7 +375,7 @@ main: {
|
||||
pha
|
||||
// [9] callexecute next -- jsr
|
||||
jsr next
|
||||
// [10] (signed word~) main::$1 ← callfinalize next -- vwsz1=_stackpullsword_
|
||||
// [10] (signed word~) main::$1 ← stackpull(signed word) -- vwsz1=_stackpullsword_
|
||||
pla
|
||||
sta.z __1
|
||||
pla
|
||||
@ -394,13 +399,13 @@ next: {
|
||||
jmp __breturn
|
||||
// next::@return
|
||||
__breturn:
|
||||
// [15] return (signed word) next::return#0
|
||||
// [15] return (signed word) next::return#0 -- _stackidxsword_vbuc1=vwsz1
|
||||
// [15] stackidx(signed word,(const byte) next::OFFSET_STACK_RETURN) ← (signed word) next::return#0 -- _stackidxsword_vbuc1=vwsz1
|
||||
tsx
|
||||
lda.z return
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN,x
|
||||
lda.z return+1
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN+1,x
|
||||
// [16] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
@ -435,14 +440,14 @@ FINAL SYMBOL TABLE
|
||||
(signed word) current
|
||||
(signed word) current#5 current zp[2]:2 2.0
|
||||
(void()) main()
|
||||
(signed word~) main::$0 zp[2]:2 2.0
|
||||
(signed word~) main::$1 zp[2]:4 2.0
|
||||
(signed word~) main::$0 zp[2]:2 4.0
|
||||
(signed word~) main::$1 zp[2]:4 4.0
|
||||
(label) main::@return
|
||||
__stackcall (signed word()) next()
|
||||
(label) next::@return
|
||||
(const byte) next::OFFSET_STACK_RETURN = (byte) 0
|
||||
(signed word) next::return
|
||||
(signed word) next::return#0 return zp[2]:2 2.0
|
||||
(signed word) next::return#0 return zp[2]:2 4.0
|
||||
|
||||
zp[2]:2 [ main::$0 current#5 next::return#0 ]
|
||||
zp[2]:4 [ main::$1 ]
|
||||
@ -479,7 +484,7 @@ main: {
|
||||
pha
|
||||
// [5] callexecute next -- jsr
|
||||
jsr next
|
||||
// [6] (signed word~) main::$0 ← callfinalize next -- vwsz1=_stackpullsword_
|
||||
// [6] (signed word~) main::$0 ← stackpull(signed word) -- vwsz1=_stackpullsword_
|
||||
pla
|
||||
sta.z __0
|
||||
pla
|
||||
@ -496,7 +501,7 @@ main: {
|
||||
pha
|
||||
// [9] callexecute next -- jsr
|
||||
jsr next
|
||||
// [10] (signed word~) main::$1 ← callfinalize next -- vwsz1=_stackpullsword_
|
||||
// [10] (signed word~) main::$1 ← stackpull(signed word) -- vwsz1=_stackpullsword_
|
||||
pla
|
||||
sta.z __1
|
||||
pla
|
||||
@ -520,13 +525,13 @@ next: {
|
||||
// [14] (signed word) next::return#0 ← (signed word) current#5
|
||||
// next::@return
|
||||
// }
|
||||
// [15] return (signed word) next::return#0
|
||||
// [15] return (signed word) next::return#0 -- _stackidxsword_vbuc1=vwsz1
|
||||
// [15] stackidx(signed word,(const byte) next::OFFSET_STACK_RETURN) ← (signed word) next::return#0 -- _stackidxsword_vbuc1=vwsz1
|
||||
tsx
|
||||
lda.z return
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN,x
|
||||
lda.z return+1
|
||||
sta STACK_BASE+OFFSET_STACK_RETURN+1,x
|
||||
// [16] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
@ -7,14 +7,14 @@
|
||||
(signed word) current
|
||||
(signed word) current#5 current zp[2]:2 2.0
|
||||
(void()) main()
|
||||
(signed word~) main::$0 zp[2]:2 2.0
|
||||
(signed word~) main::$1 zp[2]:4 2.0
|
||||
(signed word~) main::$0 zp[2]:2 4.0
|
||||
(signed word~) main::$1 zp[2]:4 4.0
|
||||
(label) main::@return
|
||||
__stackcall (signed word()) next()
|
||||
(label) next::@return
|
||||
(const byte) next::OFFSET_STACK_RETURN = (byte) 0
|
||||
(signed word) next::return
|
||||
(signed word) next::return#0 return zp[2]:2 2.0
|
||||
(signed word) next::return#0 return zp[2]:2 4.0
|
||||
|
||||
zp[2]:2 [ main::$0 current#5 next::return#0 ]
|
||||
zp[2]:4 [ main::$1 ]
|
||||
|
@ -4,35 +4,33 @@
|
||||
@1: scope:[] from @begin
|
||||
[1] callprepare main
|
||||
[2] callexecute main
|
||||
[3] callfinalize main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[4] phi()
|
||||
[3] phi()
|
||||
|
||||
__stackcall (void()) printline()
|
||||
printline: scope:[printline] from
|
||||
[5] (byte) printline::i ← (byte) 0
|
||||
[4] (byte) printline::i ← (byte) 0
|
||||
to:printline::@1
|
||||
printline::@1: scope:[printline] from printline printline::@2
|
||||
[6] if((byte) printline::i<(byte) $28) goto printline::@2
|
||||
[5] if((byte) printline::i<(byte) $28) goto printline::@2
|
||||
to:printline::@return
|
||||
printline::@return: scope:[printline] from printline::@1
|
||||
[7] return
|
||||
[6] return
|
||||
to:@return
|
||||
printline::@2: scope:[printline] from printline::@1
|
||||
[8] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*'
|
||||
[9] (byte) printline::i ← ++ (byte) printline::i
|
||||
[7] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*'
|
||||
[8] (byte) printline::i ← ++ (byte) printline::i
|
||||
to:printline::@1
|
||||
|
||||
__stackcall (void()) main()
|
||||
main: scope:[main] from
|
||||
[10] (byte) main::val ← (byte) 0
|
||||
[11] (byte) main::val ← *((const byte*) SCREEN)
|
||||
[12] callprepare printline
|
||||
[13] callexecute printline
|
||||
[14] callfinalize printline
|
||||
[15] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val
|
||||
[9] (byte) main::val ← (byte) 0
|
||||
[10] (byte) main::val ← *((const byte*) SCREEN)
|
||||
[11] callprepare printline
|
||||
[12] callexecute printline
|
||||
[13] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[16] return
|
||||
[14] return
|
||||
to:@return
|
||||
|
@ -16,7 +16,6 @@ main: scope:[main] from
|
||||
(byte) main::val ← *((const byte*) SCREEN)
|
||||
callprepare printline
|
||||
callexecute printline
|
||||
callfinalize printline
|
||||
*((const byte*) SCREEN + (number) $50) ← (byte) main::val
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
@ -41,7 +40,6 @@ printline::@return: scope:[printline] from printline::@1
|
||||
@2: scope:[] from @begin
|
||||
callprepare main
|
||||
callexecute main
|
||||
callfinalize main
|
||||
to:@end
|
||||
@end: scope:[] from @2
|
||||
|
||||
@ -70,7 +68,7 @@ Successful SSA optimization PassNCastSimplification
|
||||
Finalized unsigned number type (byte) $50
|
||||
Finalized unsigned number type (byte) $28
|
||||
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||
Simple Condition (bool~) printline::$0 [9] if((byte) printline::i<(byte) $28) goto printline::@2
|
||||
Simple Condition (bool~) printline::$0 [8] if((byte) printline::i<(byte) $28) goto printline::@2
|
||||
Successful SSA optimization Pass2ConditionalJumpSimplification
|
||||
Consolidated array index constant in *(SCREEN+$50)
|
||||
Successful SSA optimization Pass2ConstantAdditionElimination
|
||||
@ -78,7 +76,7 @@ Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @end
|
||||
CALL GRAPH
|
||||
Calls in [] to main:2
|
||||
Calls in [main] to printline:13
|
||||
Calls in [main] to printline:12
|
||||
|
||||
Created 0 initial phi equivalence classes
|
||||
Coalesced down to 0 phi equivalence classes
|
||||
@ -93,43 +91,41 @@ FINAL CONTROL FLOW GRAPH
|
||||
@1: scope:[] from @begin
|
||||
[1] callprepare main
|
||||
[2] callexecute main
|
||||
[3] callfinalize main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[4] phi()
|
||||
[3] phi()
|
||||
|
||||
__stackcall (void()) printline()
|
||||
printline: scope:[printline] from
|
||||
[5] (byte) printline::i ← (byte) 0
|
||||
[4] (byte) printline::i ← (byte) 0
|
||||
to:printline::@1
|
||||
printline::@1: scope:[printline] from printline printline::@2
|
||||
[6] if((byte) printline::i<(byte) $28) goto printline::@2
|
||||
[5] if((byte) printline::i<(byte) $28) goto printline::@2
|
||||
to:printline::@return
|
||||
printline::@return: scope:[printline] from printline::@1
|
||||
[7] return
|
||||
[6] return
|
||||
to:@return
|
||||
printline::@2: scope:[printline] from printline::@1
|
||||
[8] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*'
|
||||
[9] (byte) printline::i ← ++ (byte) printline::i
|
||||
[7] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*'
|
||||
[8] (byte) printline::i ← ++ (byte) printline::i
|
||||
to:printline::@1
|
||||
|
||||
__stackcall (void()) main()
|
||||
main: scope:[main] from
|
||||
[10] (byte) main::val ← (byte) 0
|
||||
[11] (byte) main::val ← *((const byte*) SCREEN)
|
||||
[12] callprepare printline
|
||||
[13] callexecute printline
|
||||
[14] callfinalize printline
|
||||
[15] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val
|
||||
[9] (byte) main::val ← (byte) 0
|
||||
[10] (byte) main::val ← *((const byte*) SCREEN)
|
||||
[11] callprepare printline
|
||||
[12] callexecute printline
|
||||
[13] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[16] return
|
||||
[14] return
|
||||
to:@return
|
||||
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
__stackcall (void()) main()
|
||||
(byte) main::val loadstore 1.5
|
||||
(byte) main::val loadstore 2.0
|
||||
__stackcall (void()) printline()
|
||||
(byte) printline::i loadstore 11.5
|
||||
|
||||
@ -161,8 +157,7 @@ __b1:
|
||||
// [1] callprepare main
|
||||
// [2] callexecute main -- jsr
|
||||
jsr main
|
||||
// [3] callfinalize main
|
||||
// [4] phi from @1 to @end [phi:@1->@end]
|
||||
// [3] phi from @1 to @end [phi:@1->@end]
|
||||
__bend_from___b1:
|
||||
jmp __bend
|
||||
// @end
|
||||
@ -170,68 +165,67 @@ __bend:
|
||||
// printline
|
||||
printline: {
|
||||
.label i = 2
|
||||
// [5] (byte) printline::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
// [4] (byte) printline::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z i
|
||||
jmp __b1
|
||||
// printline::@1
|
||||
__b1:
|
||||
// [6] if((byte) printline::i<(byte) $28) goto printline::@2 -- vbuz1_lt_vbuc1_then_la1
|
||||
// [5] if((byte) printline::i<(byte) $28) goto printline::@2 -- vbuz1_lt_vbuc1_then_la1
|
||||
lda.z i
|
||||
cmp #$28
|
||||
bcc __b2
|
||||
jmp __breturn
|
||||
// printline::@return
|
||||
__breturn:
|
||||
// [7] return
|
||||
// [6] return
|
||||
rts
|
||||
// printline::@2
|
||||
__b2:
|
||||
// [8] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' -- pbuc1_derefidx_vbuz1=vbuc2
|
||||
// [7] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' -- pbuc1_derefidx_vbuz1=vbuc2
|
||||
lda #'*'
|
||||
ldy.z i
|
||||
sta SCREEN,y
|
||||
// [9] (byte) printline::i ← ++ (byte) printline::i -- vbuz1=_inc_vbuz1
|
||||
// [8] (byte) printline::i ← ++ (byte) printline::i -- vbuz1=_inc_vbuz1
|
||||
inc.z i
|
||||
jmp __b1
|
||||
}
|
||||
// main
|
||||
main: {
|
||||
.label val = 3
|
||||
// [10] (byte) main::val ← (byte) 0 -- vbuz1=vbuc1
|
||||
// [9] (byte) main::val ← (byte) 0 -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z val
|
||||
// [11] (byte) main::val ← *((const byte*) SCREEN) -- vbuz1=_deref_pbuc1
|
||||
// [10] (byte) main::val ← *((const byte*) SCREEN) -- vbuz1=_deref_pbuc1
|
||||
lda SCREEN
|
||||
sta.z val
|
||||
// [12] callprepare printline
|
||||
// [13] callexecute printline -- jsr
|
||||
// [11] callprepare printline
|
||||
// [12] callexecute printline -- jsr
|
||||
jsr printline
|
||||
// [14] callfinalize printline
|
||||
// [15] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val -- _deref_pbuc1=vbuz1
|
||||
// [13] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val -- _deref_pbuc1=vbuz1
|
||||
lda.z val
|
||||
sta SCREEN+$50
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [16] return
|
||||
// [14] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Statement [5] (byte) printline::i ← (byte) 0 [ printline::i ] ( main:2::printline:13 [ main::val printline::i ] ) always clobbers reg byte a
|
||||
Statement [6] if((byte) printline::i<(byte) $28) goto printline::@2 [ printline::i ] ( main:2::printline:13 [ main::val printline::i ] ) always clobbers reg byte a
|
||||
Statement [8] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' [ printline::i ] ( main:2::printline:13 [ main::val printline::i ] ) always clobbers reg byte a reg byte y
|
||||
Statement [10] (byte) main::val ← (byte) 0 [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
Statement [11] (byte) main::val ← *((const byte*) SCREEN) [ main::val ] ( main:2 [ main::val ] ) always clobbers reg byte a
|
||||
Statement [15] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
Statement [4] (byte) printline::i ← (byte) 0 [ printline::i ] ( main:2::printline:12 [ main::val printline::i ] ) always clobbers reg byte a
|
||||
Statement [5] if((byte) printline::i<(byte) $28) goto printline::@2 [ printline::i ] ( main:2::printline:12 [ main::val printline::i ] ) always clobbers reg byte a
|
||||
Statement [7] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' [ printline::i ] ( main:2::printline:12 [ main::val printline::i ] ) always clobbers reg byte a reg byte y
|
||||
Statement [9] (byte) main::val ← (byte) 0 [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
Statement [10] (byte) main::val ← *((const byte*) SCREEN) [ main::val ] ( main:2 [ main::val ] ) always clobbers reg byte a
|
||||
Statement [13] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
Potential registers zp[1]:2 [ printline::i ] : zp[1]:2 ,
|
||||
Potential registers zp[1]:3 [ main::val ] : zp[1]:3 ,
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [printline] 11.5: zp[1]:2 [ printline::i ]
|
||||
Uplift Scope [main] 1.5: zp[1]:3 [ main::val ]
|
||||
Uplift Scope [main] 2: zp[1]:3 [ main::val ]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [printline] best 372 combination zp[1]:2 [ printline::i ]
|
||||
@ -260,8 +254,7 @@ __b1:
|
||||
// [1] callprepare main
|
||||
// [2] callexecute main -- jsr
|
||||
jsr main
|
||||
// [3] callfinalize main
|
||||
// [4] phi from @1 to @end [phi:@1->@end]
|
||||
// [3] phi from @1 to @end [phi:@1->@end]
|
||||
__bend_from___b1:
|
||||
jmp __bend
|
||||
// @end
|
||||
@ -269,51 +262,50 @@ __bend:
|
||||
// printline
|
||||
printline: {
|
||||
.label i = 2
|
||||
// [5] (byte) printline::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
// [4] (byte) printline::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z i
|
||||
jmp __b1
|
||||
// printline::@1
|
||||
__b1:
|
||||
// [6] if((byte) printline::i<(byte) $28) goto printline::@2 -- vbuz1_lt_vbuc1_then_la1
|
||||
// [5] if((byte) printline::i<(byte) $28) goto printline::@2 -- vbuz1_lt_vbuc1_then_la1
|
||||
lda.z i
|
||||
cmp #$28
|
||||
bcc __b2
|
||||
jmp __breturn
|
||||
// printline::@return
|
||||
__breturn:
|
||||
// [7] return
|
||||
// [6] return
|
||||
rts
|
||||
// printline::@2
|
||||
__b2:
|
||||
// [8] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' -- pbuc1_derefidx_vbuz1=vbuc2
|
||||
// [7] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' -- pbuc1_derefidx_vbuz1=vbuc2
|
||||
lda #'*'
|
||||
ldy.z i
|
||||
sta SCREEN,y
|
||||
// [9] (byte) printline::i ← ++ (byte) printline::i -- vbuz1=_inc_vbuz1
|
||||
// [8] (byte) printline::i ← ++ (byte) printline::i -- vbuz1=_inc_vbuz1
|
||||
inc.z i
|
||||
jmp __b1
|
||||
}
|
||||
// main
|
||||
main: {
|
||||
.label val = 3
|
||||
// [10] (byte) main::val ← (byte) 0 -- vbuz1=vbuc1
|
||||
// [9] (byte) main::val ← (byte) 0 -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z val
|
||||
// [11] (byte) main::val ← *((const byte*) SCREEN) -- vbuz1=_deref_pbuc1
|
||||
// [10] (byte) main::val ← *((const byte*) SCREEN) -- vbuz1=_deref_pbuc1
|
||||
lda SCREEN
|
||||
sta.z val
|
||||
// [12] callprepare printline
|
||||
// [13] callexecute printline -- jsr
|
||||
// [11] callprepare printline
|
||||
// [12] callexecute printline -- jsr
|
||||
jsr printline
|
||||
// [14] callfinalize printline
|
||||
// [15] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val -- _deref_pbuc1=vbuz1
|
||||
// [13] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val -- _deref_pbuc1=vbuz1
|
||||
lda.z val
|
||||
sta SCREEN+$50
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [16] return
|
||||
// [14] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
@ -342,7 +334,7 @@ FINAL SYMBOL TABLE
|
||||
(const byte*) SCREEN = (byte*) 1024
|
||||
__stackcall (void()) main()
|
||||
(label) main::@return
|
||||
(byte) main::val loadstore zp[1]:3 1.5
|
||||
(byte) main::val loadstore zp[1]:3 2.0
|
||||
__stackcall (void()) printline()
|
||||
(label) printline::@1
|
||||
(label) printline::@2
|
||||
@ -372,36 +364,35 @@ __bbegin:
|
||||
// [2] callexecute main -- jsr
|
||||
jsr main
|
||||
rts
|
||||
// [3] callfinalize main
|
||||
// [4] phi from @1 to @end [phi:@1->@end]
|
||||
// [3] phi from @1 to @end [phi:@1->@end]
|
||||
// @end
|
||||
// printline
|
||||
printline: {
|
||||
.label i = 2
|
||||
// i=0
|
||||
// [5] (byte) printline::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
// [4] (byte) printline::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z i
|
||||
// printline::@1
|
||||
__b1:
|
||||
// for(char i=0; i<40; i++)
|
||||
// [6] if((byte) printline::i<(byte) $28) goto printline::@2 -- vbuz1_lt_vbuc1_then_la1
|
||||
// [5] if((byte) printline::i<(byte) $28) goto printline::@2 -- vbuz1_lt_vbuc1_then_la1
|
||||
lda.z i
|
||||
cmp #$28
|
||||
bcc __b2
|
||||
// printline::@return
|
||||
// }
|
||||
// [7] return
|
||||
// [6] return
|
||||
rts
|
||||
// printline::@2
|
||||
__b2:
|
||||
// SCREEN[i] = '*'
|
||||
// [8] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' -- pbuc1_derefidx_vbuz1=vbuc2
|
||||
// [7] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' -- pbuc1_derefidx_vbuz1=vbuc2
|
||||
lda #'*'
|
||||
ldy.z i
|
||||
sta SCREEN,y
|
||||
// for(char i=0; i<40; i++)
|
||||
// [9] (byte) printline::i ← ++ (byte) printline::i -- vbuz1=_inc_vbuz1
|
||||
// [8] (byte) printline::i ← ++ (byte) printline::i -- vbuz1=_inc_vbuz1
|
||||
inc.z i
|
||||
jmp __b1
|
||||
}
|
||||
@ -409,25 +400,24 @@ printline: {
|
||||
main: {
|
||||
.label val = 3
|
||||
// val
|
||||
// [10] (byte) main::val ← (byte) 0 -- vbuz1=vbuc1
|
||||
// [9] (byte) main::val ← (byte) 0 -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z val
|
||||
// val = *SCREEN
|
||||
// [11] (byte) main::val ← *((const byte*) SCREEN) -- vbuz1=_deref_pbuc1
|
||||
// [10] (byte) main::val ← *((const byte*) SCREEN) -- vbuz1=_deref_pbuc1
|
||||
lda SCREEN
|
||||
sta.z val
|
||||
// printline()
|
||||
// [12] callprepare printline
|
||||
// [13] callexecute printline -- jsr
|
||||
// [11] callprepare printline
|
||||
// [12] callexecute printline -- jsr
|
||||
jsr printline
|
||||
// [14] callfinalize printline
|
||||
// SCREEN[80] = val
|
||||
// [15] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val -- _deref_pbuc1=vbuz1
|
||||
// [13] *((const byte*) SCREEN+(byte) $50) ← (byte) main::val -- _deref_pbuc1=vbuz1
|
||||
lda.z val
|
||||
sta SCREEN+$50
|
||||
// main::@return
|
||||
// }
|
||||
// [16] return
|
||||
// [14] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
@ -4,7 +4,7 @@
|
||||
(const byte*) SCREEN = (byte*) 1024
|
||||
__stackcall (void()) main()
|
||||
(label) main::@return
|
||||
(byte) main::val loadstore zp[1]:3 1.5
|
||||
(byte) main::val loadstore zp[1]:3 2.0
|
||||
__stackcall (void()) printline()
|
||||
(label) printline::@1
|
||||
(label) printline::@2
|
||||
|
@ -4,34 +4,32 @@
|
||||
@1: scope:[] from @begin
|
||||
[1] callprepare main
|
||||
[2] callexecute main
|
||||
[3] callfinalize main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[4] phi()
|
||||
[3] phi()
|
||||
|
||||
__stackcall (void()) printline()
|
||||
printline: scope:[printline] from
|
||||
[5] (byte) printline::i ← (byte) 0
|
||||
[4] (byte) printline::i ← (byte) 0
|
||||
to:printline::@1
|
||||
printline::@1: scope:[printline] from printline printline::@2
|
||||
[6] if((byte) printline::i<(byte) $28) goto printline::@2
|
||||
[5] if((byte) printline::i<(byte) $28) goto printline::@2
|
||||
to:printline::@return
|
||||
printline::@return: scope:[printline] from printline::@1
|
||||
[7] return
|
||||
[6] return
|
||||
to:@return
|
||||
printline::@2: scope:[printline] from printline::@1
|
||||
[8] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*'
|
||||
[9] (byte) printline::i ← ++ (byte) printline::i
|
||||
[7] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*'
|
||||
[8] (byte) printline::i ← ++ (byte) printline::i
|
||||
to:printline::@1
|
||||
|
||||
__stackcall (void()) main()
|
||||
main: scope:[main] from
|
||||
[10] (byte) val ← (byte) '-'
|
||||
[11] callprepare printline
|
||||
[12] callexecute printline
|
||||
[13] callfinalize printline
|
||||
[14] *((const byte*) SCREEN+(byte) $50) ← (byte) val
|
||||
[9] (byte) val ← (byte) '-'
|
||||
[10] callprepare printline
|
||||
[11] callexecute printline
|
||||
[12] *((const byte*) SCREEN+(byte) $50) ← (byte) val
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[15] return
|
||||
[13] return
|
||||
to:@return
|
||||
|
@ -16,7 +16,6 @@ main: scope:[main] from
|
||||
(byte) val ← (byte) '-'
|
||||
callprepare printline
|
||||
callexecute printline
|
||||
callfinalize printline
|
||||
*((const byte*) SCREEN + (number) $50) ← (byte) val
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
@ -41,7 +40,6 @@ printline::@return: scope:[printline] from printline::@1
|
||||
@2: scope:[] from @begin
|
||||
callprepare main
|
||||
callexecute main
|
||||
callfinalize main
|
||||
to:@end
|
||||
@end: scope:[] from @2
|
||||
|
||||
@ -70,14 +68,14 @@ Successful SSA optimization PassNCastSimplification
|
||||
Finalized unsigned number type (byte) $50
|
||||
Finalized unsigned number type (byte) $28
|
||||
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||
Simple Condition (bool~) printline::$0 [9] if((byte) printline::i<(byte) $28) goto printline::@2
|
||||
Simple Condition (bool~) printline::$0 [8] if((byte) printline::i<(byte) $28) goto printline::@2
|
||||
Successful SSA optimization Pass2ConditionalJumpSimplification
|
||||
Consolidated array index constant in *(SCREEN+$50)
|
||||
Successful SSA optimization Pass2ConstantAdditionElimination
|
||||
Adding NOP phi() at start of @end
|
||||
CALL GRAPH
|
||||
Calls in [] to main:2
|
||||
Calls in [main] to printline:12
|
||||
Calls in [main] to printline:11
|
||||
|
||||
Created 0 initial phi equivalence classes
|
||||
Coalesced down to 0 phi equivalence classes
|
||||
@ -91,36 +89,34 @@ FINAL CONTROL FLOW GRAPH
|
||||
@1: scope:[] from @begin
|
||||
[1] callprepare main
|
||||
[2] callexecute main
|
||||
[3] callfinalize main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[4] phi()
|
||||
[3] phi()
|
||||
|
||||
__stackcall (void()) printline()
|
||||
printline: scope:[printline] from
|
||||
[5] (byte) printline::i ← (byte) 0
|
||||
[4] (byte) printline::i ← (byte) 0
|
||||
to:printline::@1
|
||||
printline::@1: scope:[printline] from printline printline::@2
|
||||
[6] if((byte) printline::i<(byte) $28) goto printline::@2
|
||||
[5] if((byte) printline::i<(byte) $28) goto printline::@2
|
||||
to:printline::@return
|
||||
printline::@return: scope:[printline] from printline::@1
|
||||
[7] return
|
||||
[6] return
|
||||
to:@return
|
||||
printline::@2: scope:[printline] from printline::@1
|
||||
[8] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*'
|
||||
[9] (byte) printline::i ← ++ (byte) printline::i
|
||||
[7] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*'
|
||||
[8] (byte) printline::i ← ++ (byte) printline::i
|
||||
to:printline::@1
|
||||
|
||||
__stackcall (void()) main()
|
||||
main: scope:[main] from
|
||||
[10] (byte) val ← (byte) '-'
|
||||
[11] callprepare printline
|
||||
[12] callexecute printline
|
||||
[13] callfinalize printline
|
||||
[14] *((const byte*) SCREEN+(byte) $50) ← (byte) val
|
||||
[9] (byte) val ← (byte) '-'
|
||||
[10] callprepare printline
|
||||
[11] callexecute printline
|
||||
[12] *((const byte*) SCREEN+(byte) $50) ← (byte) val
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[15] return
|
||||
[13] return
|
||||
to:@return
|
||||
|
||||
|
||||
@ -128,7 +124,7 @@ VARIABLE REGISTER WEIGHTS
|
||||
__stackcall (void()) main()
|
||||
__stackcall (void()) printline()
|
||||
(byte) printline::i loadstore 11.5
|
||||
(byte) val loadstore 1.5
|
||||
(byte) val loadstore 2.0
|
||||
|
||||
Initial phi equivalence classes
|
||||
Added variable val to live range equivalence class [ val ]
|
||||
@ -162,8 +158,7 @@ __b1:
|
||||
// [1] callprepare main
|
||||
// [2] callexecute main -- jsr
|
||||
jsr main
|
||||
// [3] callfinalize main
|
||||
// [4] phi from @1 to @end [phi:@1->@end]
|
||||
// [3] phi from @1 to @end [phi:@1->@end]
|
||||
__bend_from___b1:
|
||||
jmp __bend
|
||||
// @end
|
||||
@ -171,64 +166,63 @@ __bend:
|
||||
// printline
|
||||
printline: {
|
||||
.label i = 3
|
||||
// [5] (byte) printline::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
// [4] (byte) printline::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z i
|
||||
jmp __b1
|
||||
// printline::@1
|
||||
__b1:
|
||||
// [6] if((byte) printline::i<(byte) $28) goto printline::@2 -- vbuz1_lt_vbuc1_then_la1
|
||||
// [5] if((byte) printline::i<(byte) $28) goto printline::@2 -- vbuz1_lt_vbuc1_then_la1
|
||||
lda.z i
|
||||
cmp #$28
|
||||
bcc __b2
|
||||
jmp __breturn
|
||||
// printline::@return
|
||||
__breturn:
|
||||
// [7] return
|
||||
// [6] return
|
||||
rts
|
||||
// printline::@2
|
||||
__b2:
|
||||
// [8] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' -- pbuc1_derefidx_vbuz1=vbuc2
|
||||
// [7] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' -- pbuc1_derefidx_vbuz1=vbuc2
|
||||
lda #'*'
|
||||
ldy.z i
|
||||
sta SCREEN,y
|
||||
// [9] (byte) printline::i ← ++ (byte) printline::i -- vbuz1=_inc_vbuz1
|
||||
// [8] (byte) printline::i ← ++ (byte) printline::i -- vbuz1=_inc_vbuz1
|
||||
inc.z i
|
||||
jmp __b1
|
||||
}
|
||||
// main
|
||||
main: {
|
||||
// [10] (byte) val ← (byte) '-' -- vbuz1=vbuc1
|
||||
// [9] (byte) val ← (byte) '-' -- vbuz1=vbuc1
|
||||
lda #'-'
|
||||
sta.z val
|
||||
// [11] callprepare printline
|
||||
// [12] callexecute printline -- jsr
|
||||
// [10] callprepare printline
|
||||
// [11] callexecute printline -- jsr
|
||||
jsr printline
|
||||
// [13] callfinalize printline
|
||||
// [14] *((const byte*) SCREEN+(byte) $50) ← (byte) val -- _deref_pbuc1=vbuz1
|
||||
// [12] *((const byte*) SCREEN+(byte) $50) ← (byte) val -- _deref_pbuc1=vbuz1
|
||||
lda.z val
|
||||
sta SCREEN+$50
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [15] return
|
||||
// [13] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Statement [0] (byte) val ← (byte) 0 [ ] ( [ ] ) always clobbers reg byte a
|
||||
Statement [5] (byte) printline::i ← (byte) 0 [ printline::i ] ( main:2::printline:12 [ val printline::i ] ) always clobbers reg byte a
|
||||
Statement [6] if((byte) printline::i<(byte) $28) goto printline::@2 [ printline::i ] ( main:2::printline:12 [ val printline::i ] ) always clobbers reg byte a
|
||||
Statement [8] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' [ printline::i ] ( main:2::printline:12 [ val printline::i ] ) always clobbers reg byte a reg byte y
|
||||
Statement [10] (byte) val ← (byte) '-' [ val ] ( main:2 [ val ] ) always clobbers reg byte a
|
||||
Statement [14] *((const byte*) SCREEN+(byte) $50) ← (byte) val [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
Statement [4] (byte) printline::i ← (byte) 0 [ printline::i ] ( main:2::printline:11 [ val printline::i ] ) always clobbers reg byte a
|
||||
Statement [5] if((byte) printline::i<(byte) $28) goto printline::@2 [ printline::i ] ( main:2::printline:11 [ val printline::i ] ) always clobbers reg byte a
|
||||
Statement [7] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' [ printline::i ] ( main:2::printline:11 [ val printline::i ] ) always clobbers reg byte a reg byte y
|
||||
Statement [9] (byte) val ← (byte) '-' [ val ] ( main:2 [ val ] ) always clobbers reg byte a
|
||||
Statement [12] *((const byte*) SCREEN+(byte) $50) ← (byte) val [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
Potential registers zp[1]:2 [ val ] : zp[1]:2 ,
|
||||
Potential registers zp[1]:3 [ printline::i ] : zp[1]:3 ,
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [printline] 11.5: zp[1]:3 [ printline::i ]
|
||||
Uplift Scope [] 1.5: zp[1]:2 [ val ]
|
||||
Uplift Scope [] 2: zp[1]:2 [ val ]
|
||||
Uplift Scope [main]
|
||||
|
||||
Uplifting [printline] best 343 combination zp[1]:3 [ printline::i ]
|
||||
@ -261,8 +255,7 @@ __b1:
|
||||
// [1] callprepare main
|
||||
// [2] callexecute main -- jsr
|
||||
jsr main
|
||||
// [3] callfinalize main
|
||||
// [4] phi from @1 to @end [phi:@1->@end]
|
||||
// [3] phi from @1 to @end [phi:@1->@end]
|
||||
__bend_from___b1:
|
||||
jmp __bend
|
||||
// @end
|
||||
@ -270,47 +263,46 @@ __bend:
|
||||
// printline
|
||||
printline: {
|
||||
.label i = 3
|
||||
// [5] (byte) printline::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
// [4] (byte) printline::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z i
|
||||
jmp __b1
|
||||
// printline::@1
|
||||
__b1:
|
||||
// [6] if((byte) printline::i<(byte) $28) goto printline::@2 -- vbuz1_lt_vbuc1_then_la1
|
||||
// [5] if((byte) printline::i<(byte) $28) goto printline::@2 -- vbuz1_lt_vbuc1_then_la1
|
||||
lda.z i
|
||||
cmp #$28
|
||||
bcc __b2
|
||||
jmp __breturn
|
||||
// printline::@return
|
||||
__breturn:
|
||||
// [7] return
|
||||
// [6] return
|
||||
rts
|
||||
// printline::@2
|
||||
__b2:
|
||||
// [8] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' -- pbuc1_derefidx_vbuz1=vbuc2
|
||||
// [7] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' -- pbuc1_derefidx_vbuz1=vbuc2
|
||||
lda #'*'
|
||||
ldy.z i
|
||||
sta SCREEN,y
|
||||
// [9] (byte) printline::i ← ++ (byte) printline::i -- vbuz1=_inc_vbuz1
|
||||
// [8] (byte) printline::i ← ++ (byte) printline::i -- vbuz1=_inc_vbuz1
|
||||
inc.z i
|
||||
jmp __b1
|
||||
}
|
||||
// main
|
||||
main: {
|
||||
// [10] (byte) val ← (byte) '-' -- vbuz1=vbuc1
|
||||
// [9] (byte) val ← (byte) '-' -- vbuz1=vbuc1
|
||||
lda #'-'
|
||||
sta.z val
|
||||
// [11] callprepare printline
|
||||
// [12] callexecute printline -- jsr
|
||||
// [10] callprepare printline
|
||||
// [11] callexecute printline -- jsr
|
||||
jsr printline
|
||||
// [13] callfinalize printline
|
||||
// [14] *((const byte*) SCREEN+(byte) $50) ← (byte) val -- _deref_pbuc1=vbuz1
|
||||
// [12] *((const byte*) SCREEN+(byte) $50) ← (byte) val -- _deref_pbuc1=vbuz1
|
||||
lda.z val
|
||||
sta SCREEN+$50
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [15] return
|
||||
// [13] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
@ -344,7 +336,7 @@ __stackcall (void()) printline()
|
||||
(label) printline::@2
|
||||
(label) printline::@return
|
||||
(byte) printline::i loadstore zp[1]:3 11.5
|
||||
(byte) val loadstore zp[1]:2 1.5
|
||||
(byte) val loadstore zp[1]:2 2.0
|
||||
|
||||
zp[1]:2 [ val ]
|
||||
zp[1]:3 [ printline::i ]
|
||||
@ -374,57 +366,55 @@ __bbegin:
|
||||
// [2] callexecute main -- jsr
|
||||
jsr main
|
||||
rts
|
||||
// [3] callfinalize main
|
||||
// [4] phi from @1 to @end [phi:@1->@end]
|
||||
// [3] phi from @1 to @end [phi:@1->@end]
|
||||
// @end
|
||||
// printline
|
||||
printline: {
|
||||
.label i = 3
|
||||
// i=0
|
||||
// [5] (byte) printline::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
// [4] (byte) printline::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z i
|
||||
// printline::@1
|
||||
__b1:
|
||||
// for(char i=0; i<40; i++)
|
||||
// [6] if((byte) printline::i<(byte) $28) goto printline::@2 -- vbuz1_lt_vbuc1_then_la1
|
||||
// [5] if((byte) printline::i<(byte) $28) goto printline::@2 -- vbuz1_lt_vbuc1_then_la1
|
||||
lda.z i
|
||||
cmp #$28
|
||||
bcc __b2
|
||||
// printline::@return
|
||||
// }
|
||||
// [7] return
|
||||
// [6] return
|
||||
rts
|
||||
// printline::@2
|
||||
__b2:
|
||||
// SCREEN[i] = '*'
|
||||
// [8] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' -- pbuc1_derefidx_vbuz1=vbuc2
|
||||
// [7] *((const byte*) SCREEN + (byte) printline::i) ← (byte) '*' -- pbuc1_derefidx_vbuz1=vbuc2
|
||||
lda #'*'
|
||||
ldy.z i
|
||||
sta SCREEN,y
|
||||
// for(char i=0; i<40; i++)
|
||||
// [9] (byte) printline::i ← ++ (byte) printline::i -- vbuz1=_inc_vbuz1
|
||||
// [8] (byte) printline::i ← ++ (byte) printline::i -- vbuz1=_inc_vbuz1
|
||||
inc.z i
|
||||
jmp __b1
|
||||
}
|
||||
// main
|
||||
main: {
|
||||
// val = '-'
|
||||
// [10] (byte) val ← (byte) '-' -- vbuz1=vbuc1
|
||||
// [9] (byte) val ← (byte) '-' -- vbuz1=vbuc1
|
||||
lda #'-'
|
||||
sta.z val
|
||||
// printline()
|
||||
// [11] callprepare printline
|
||||
// [12] callexecute printline -- jsr
|
||||
// [10] callprepare printline
|
||||
// [11] callexecute printline -- jsr
|
||||
jsr printline
|
||||
// [13] callfinalize printline
|
||||
// SCREEN[80] = val
|
||||
// [14] *((const byte*) SCREEN+(byte) $50) ← (byte) val -- _deref_pbuc1=vbuz1
|
||||
// [12] *((const byte*) SCREEN+(byte) $50) ← (byte) val -- _deref_pbuc1=vbuz1
|
||||
lda.z val
|
||||
sta SCREEN+$50
|
||||
// main::@return
|
||||
// }
|
||||
// [15] return
|
||||
// [13] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
@ -9,7 +9,7 @@ __stackcall (void()) printline()
|
||||
(label) printline::@2
|
||||
(label) printline::@return
|
||||
(byte) printline::i loadstore zp[1]:3 11.5
|
||||
(byte) val loadstore zp[1]:2 1.5
|
||||
(byte) val loadstore zp[1]:2 2.0
|
||||
|
||||
zp[1]:2 [ val ]
|
||||
zp[1]:3 [ printline::i ]
|
||||
|
@ -4,77 +4,71 @@
|
||||
@1: scope:[] from @begin
|
||||
[1] callprepare main
|
||||
[2] callexecute main
|
||||
[3] callfinalize main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[4] phi()
|
||||
[3] phi()
|
||||
|
||||
__stackcall (void()) printother()
|
||||
printother: scope:[printother] from
|
||||
[5] (byte) printother::i ← (byte) 0
|
||||
[4] (byte) printother::i ← (byte) 0
|
||||
to:printother::@1
|
||||
printother::@1: scope:[printother] from printother printother::@1
|
||||
[6] *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) ← ++ *((const byte*) SCREEN+(byte) $28 + (byte) printother::i)
|
||||
[7] (byte) printother::i ← ++ (byte) printother::i
|
||||
[8] if((byte) printother::i!=(byte) 6) goto printother::@1
|
||||
[5] *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) ← ++ *((const byte*) SCREEN+(byte) $28 + (byte) printother::i)
|
||||
[6] (byte) printother::i ← ++ (byte) printother::i
|
||||
[7] if((byte) printother::i!=(byte) 6) goto printother::@1
|
||||
to:printother::@return
|
||||
printother::@return: scope:[printother] from printother::@1
|
||||
[9] return
|
||||
[8] return
|
||||
to:@return
|
||||
|
||||
__stackcall (void()) incval()
|
||||
incval: scope:[incval] from
|
||||
[10] (byte) val ← ++ (byte) val
|
||||
[9] (byte) val ← ++ (byte) val
|
||||
to:incval::@return
|
||||
incval::@return: scope:[incval] from incval
|
||||
[11] return
|
||||
[10] return
|
||||
to:@return
|
||||
|
||||
__stackcall (void()) printval()
|
||||
printval: scope:[printval] from
|
||||
[12] *((const byte*) SCREEN) ← (byte) val
|
||||
[11] *((const byte*) SCREEN) ← (byte) val
|
||||
to:printval::@return
|
||||
printval::@return: scope:[printval] from printval
|
||||
[13] return
|
||||
[12] return
|
||||
to:@return
|
||||
|
||||
__stackcall (void()) ival()
|
||||
ival: scope:[ival] from
|
||||
[14] callprepare incval
|
||||
[15] callexecute incval
|
||||
[16] callfinalize incval
|
||||
[13] callprepare incval
|
||||
[14] callexecute incval
|
||||
to:ival::@return
|
||||
ival::@return: scope:[ival] from ival
|
||||
[17] return
|
||||
[15] return
|
||||
to:@return
|
||||
|
||||
__stackcall (void()) pval()
|
||||
pval: scope:[pval] from
|
||||
[18] callprepare printval
|
||||
[19] callexecute printval
|
||||
[20] callfinalize printval
|
||||
[16] callprepare printval
|
||||
[17] callexecute printval
|
||||
to:pval::@return
|
||||
pval::@return: scope:[pval] from pval
|
||||
[21] return
|
||||
[18] return
|
||||
to:@return
|
||||
|
||||
__stackcall (void()) main()
|
||||
main: scope:[main] from
|
||||
[22] (byte) main::i ← (byte) 0
|
||||
[19] (byte) main::i ← (byte) 0
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
[23] callprepare pval
|
||||
[24] callexecute pval
|
||||
[25] callfinalize pval
|
||||
[26] callprepare printother
|
||||
[27] callexecute printother
|
||||
[28] callfinalize printother
|
||||
[29] callprepare ival
|
||||
[30] callexecute ival
|
||||
[31] callfinalize ival
|
||||
[32] (byte) main::i ← ++ (byte) main::i
|
||||
[33] if((byte) main::i!=(byte) 6) goto main::@1
|
||||
[20] callprepare pval
|
||||
[21] callexecute pval
|
||||
[22] callprepare printother
|
||||
[23] callexecute printother
|
||||
[24] callprepare ival
|
||||
[25] callexecute ival
|
||||
[26] (byte) main::i ← ++ (byte) main::i
|
||||
[27] if((byte) main::i!=(byte) 6) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[34] return
|
||||
[28] return
|
||||
to:@return
|
||||
|
@ -24,13 +24,10 @@ main: scope:[main] from
|
||||
main::@1: scope:[main] from main main::@1
|
||||
callprepare pval
|
||||
callexecute pval
|
||||
callfinalize pval
|
||||
callprepare printother
|
||||
callexecute printother
|
||||
callfinalize printother
|
||||
callprepare ival
|
||||
callexecute ival
|
||||
callfinalize ival
|
||||
(byte) main::i ← (byte) main::i + rangenext(0,5)
|
||||
(bool~) main::$3 ← (byte) main::i != rangelast(0,5)
|
||||
if((bool~) main::$3) goto main::@1
|
||||
@ -43,7 +40,6 @@ __stackcall (void()) pval()
|
||||
pval: scope:[pval] from
|
||||
callprepare printval
|
||||
callexecute printval
|
||||
callfinalize printval
|
||||
to:pval::@return
|
||||
pval::@return: scope:[pval] from pval
|
||||
return
|
||||
@ -53,7 +49,6 @@ __stackcall (void()) ival()
|
||||
ival: scope:[ival] from
|
||||
callprepare incval
|
||||
callexecute incval
|
||||
callfinalize incval
|
||||
to:ival::@return
|
||||
ival::@return: scope:[ival] from ival
|
||||
return
|
||||
@ -91,7 +86,6 @@ printother::@return: scope:[printother] from printother::@1
|
||||
@6: scope:[] from @begin
|
||||
callprepare main
|
||||
callexecute main
|
||||
callfinalize main
|
||||
to:@end
|
||||
@end: scope:[] from @6
|
||||
|
||||
@ -130,14 +124,14 @@ Successful SSA optimization PassNCastSimplification
|
||||
Finalized unsigned number type (byte) 0
|
||||
Finalized unsigned number type (byte) $28
|
||||
Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||
Simple Condition (bool~) main::$3 [13] if((byte) main::i!=rangelast(0,5)) goto main::@1
|
||||
Simple Condition (bool~) printother::$1 [31] if((byte) printother::i!=rangelast(0,5)) goto printother::@1
|
||||
Simple Condition (bool~) main::$3 [10] if((byte) main::i!=rangelast(0,5)) goto main::@1
|
||||
Simple Condition (bool~) printother::$1 [26] if((byte) printother::i!=rangelast(0,5)) goto printother::@1
|
||||
Successful SSA optimization Pass2ConditionalJumpSimplification
|
||||
Resolved ranged next value [11] main::i ← ++ main::i to ++
|
||||
Resolved ranged comparison value [13] if(main::i!=rangelast(0,5)) goto main::@1 to (number) 6
|
||||
Resolved ranged next value [29] printother::i ← ++ printother::i to ++
|
||||
Resolved ranged comparison value [31] if(printother::i!=rangelast(0,5)) goto printother::@1 to (number) 6
|
||||
Simplifying expression containing zero SCREEN in [23] *((const byte*) SCREEN + (byte) 0) ← (byte) val
|
||||
Resolved ranged next value [8] main::i ← ++ main::i to ++
|
||||
Resolved ranged comparison value [10] if(main::i!=rangelast(0,5)) goto main::@1 to (number) 6
|
||||
Resolved ranged next value [24] printother::i ← ++ printother::i to ++
|
||||
Resolved ranged comparison value [26] if(printother::i!=rangelast(0,5)) goto printother::@1 to (number) 6
|
||||
Simplifying expression containing zero SCREEN in [18] *((const byte*) SCREEN + (byte) 0) ← (byte) val
|
||||
Successful SSA optimization PassNSimplifyExpressionWithZero
|
||||
Adding number conversion cast (unumber) 6 in if((byte) main::i!=(number) 6) goto main::@1
|
||||
Adding number conversion cast (unumber) 6 in if((byte) printother::i!=(number) 6) goto printother::@1
|
||||
@ -151,9 +145,9 @@ Successful SSA optimization PassNFinalizeNumberTypeConversions
|
||||
Adding NOP phi() at start of @end
|
||||
CALL GRAPH
|
||||
Calls in [] to main:2
|
||||
Calls in [ival] to incval:15
|
||||
Calls in [pval] to printval:19
|
||||
Calls in [main] to pval:24 printother:27 ival:30
|
||||
Calls in [ival] to incval:14
|
||||
Calls in [pval] to printval:17
|
||||
Calls in [main] to pval:21 printother:23 ival:25
|
||||
|
||||
Created 0 initial phi equivalence classes
|
||||
Coalesced down to 0 phi equivalence classes
|
||||
@ -167,79 +161,73 @@ FINAL CONTROL FLOW GRAPH
|
||||
@1: scope:[] from @begin
|
||||
[1] callprepare main
|
||||
[2] callexecute main
|
||||
[3] callfinalize main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[4] phi()
|
||||
[3] phi()
|
||||
|
||||
__stackcall (void()) printother()
|
||||
printother: scope:[printother] from
|
||||
[5] (byte) printother::i ← (byte) 0
|
||||
[4] (byte) printother::i ← (byte) 0
|
||||
to:printother::@1
|
||||
printother::@1: scope:[printother] from printother printother::@1
|
||||
[6] *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) ← ++ *((const byte*) SCREEN+(byte) $28 + (byte) printother::i)
|
||||
[7] (byte) printother::i ← ++ (byte) printother::i
|
||||
[8] if((byte) printother::i!=(byte) 6) goto printother::@1
|
||||
[5] *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) ← ++ *((const byte*) SCREEN+(byte) $28 + (byte) printother::i)
|
||||
[6] (byte) printother::i ← ++ (byte) printother::i
|
||||
[7] if((byte) printother::i!=(byte) 6) goto printother::@1
|
||||
to:printother::@return
|
||||
printother::@return: scope:[printother] from printother::@1
|
||||
[9] return
|
||||
[8] return
|
||||
to:@return
|
||||
|
||||
__stackcall (void()) incval()
|
||||
incval: scope:[incval] from
|
||||
[10] (byte) val ← ++ (byte) val
|
||||
[9] (byte) val ← ++ (byte) val
|
||||
to:incval::@return
|
||||
incval::@return: scope:[incval] from incval
|
||||
[11] return
|
||||
[10] return
|
||||
to:@return
|
||||
|
||||
__stackcall (void()) printval()
|
||||
printval: scope:[printval] from
|
||||
[12] *((const byte*) SCREEN) ← (byte) val
|
||||
[11] *((const byte*) SCREEN) ← (byte) val
|
||||
to:printval::@return
|
||||
printval::@return: scope:[printval] from printval
|
||||
[13] return
|
||||
[12] return
|
||||
to:@return
|
||||
|
||||
__stackcall (void()) ival()
|
||||
ival: scope:[ival] from
|
||||
[14] callprepare incval
|
||||
[15] callexecute incval
|
||||
[16] callfinalize incval
|
||||
[13] callprepare incval
|
||||
[14] callexecute incval
|
||||
to:ival::@return
|
||||
ival::@return: scope:[ival] from ival
|
||||
[17] return
|
||||
[15] return
|
||||
to:@return
|
||||
|
||||
__stackcall (void()) pval()
|
||||
pval: scope:[pval] from
|
||||
[18] callprepare printval
|
||||
[19] callexecute printval
|
||||
[20] callfinalize printval
|
||||
[16] callprepare printval
|
||||
[17] callexecute printval
|
||||
to:pval::@return
|
||||
pval::@return: scope:[pval] from pval
|
||||
[21] return
|
||||
[18] return
|
||||
to:@return
|
||||
|
||||
__stackcall (void()) main()
|
||||
main: scope:[main] from
|
||||
[22] (byte) main::i ← (byte) 0
|
||||
[19] (byte) main::i ← (byte) 0
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
[23] callprepare pval
|
||||
[24] callexecute pval
|
||||
[25] callfinalize pval
|
||||
[26] callprepare printother
|
||||
[27] callexecute printother
|
||||
[28] callfinalize printother
|
||||
[29] callprepare ival
|
||||
[30] callexecute ival
|
||||
[31] callfinalize ival
|
||||
[32] (byte) main::i ← ++ (byte) main::i
|
||||
[33] if((byte) main::i!=(byte) 6) goto main::@1
|
||||
[20] callprepare pval
|
||||
[21] callexecute pval
|
||||
[22] callprepare printother
|
||||
[23] callexecute printother
|
||||
[24] callprepare ival
|
||||
[25] callexecute ival
|
||||
[26] (byte) main::i ← ++ (byte) main::i
|
||||
[27] if((byte) main::i!=(byte) 6) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[34] return
|
||||
[28] return
|
||||
to:@return
|
||||
|
||||
null depth in calling loop Loop head: main::@1 tails: main::@1 blocks: main::@1 in scope printother
|
||||
@ -252,12 +240,12 @@ VARIABLE REGISTER WEIGHTS
|
||||
__stackcall (void()) incval()
|
||||
__stackcall (void()) ival()
|
||||
__stackcall (void()) main()
|
||||
(byte) main::i loadstore 2.9166666666666665
|
||||
(byte) main::i loadstore 3.8888888888888893
|
||||
__stackcall (void()) printother()
|
||||
(byte) printother::i loadstore 14.25
|
||||
__stackcall (void()) printval()
|
||||
__stackcall (void()) pval()
|
||||
(byte) val loadstore 0.3076923076923077
|
||||
(byte) val loadstore 0.38095238095238093
|
||||
|
||||
Initial phi equivalence classes
|
||||
Added variable val to live range equivalence class [ val ]
|
||||
@ -294,8 +282,7 @@ __b1:
|
||||
// [1] callprepare main
|
||||
// [2] callexecute main -- jsr
|
||||
jsr main
|
||||
// [3] callfinalize main
|
||||
// [4] phi from @1 to @end [phi:@1->@end]
|
||||
// [3] phi from @1 to @end [phi:@1->@end]
|
||||
__bend_from___b1:
|
||||
jmp __bend
|
||||
// @end
|
||||
@ -303,123 +290,118 @@ __bend:
|
||||
// printother
|
||||
printother: {
|
||||
.label i = 3
|
||||
// [5] (byte) printother::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
// [4] (byte) printother::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z i
|
||||
jmp __b1
|
||||
// printother::@1
|
||||
__b1:
|
||||
// [6] *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) ← ++ *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) -- pbuc1_derefidx_vbuz1=_inc_pbuc1_derefidx_vbuz1
|
||||
// [5] *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) ← ++ *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) -- pbuc1_derefidx_vbuz1=_inc_pbuc1_derefidx_vbuz1
|
||||
ldx.z i
|
||||
inc SCREEN+$28,x
|
||||
// [7] (byte) printother::i ← ++ (byte) printother::i -- vbuz1=_inc_vbuz1
|
||||
// [6] (byte) printother::i ← ++ (byte) printother::i -- vbuz1=_inc_vbuz1
|
||||
inc.z i
|
||||
// [8] if((byte) printother::i!=(byte) 6) goto printother::@1 -- vbuz1_neq_vbuc1_then_la1
|
||||
// [7] if((byte) printother::i!=(byte) 6) goto printother::@1 -- vbuz1_neq_vbuc1_then_la1
|
||||
lda #6
|
||||
cmp.z i
|
||||
bne __b1
|
||||
jmp __breturn
|
||||
// printother::@return
|
||||
__breturn:
|
||||
// [9] return
|
||||
// [8] return
|
||||
rts
|
||||
}
|
||||
// incval
|
||||
incval: {
|
||||
// [10] (byte) val ← ++ (byte) val -- vbuz1=_inc_vbuz1
|
||||
// [9] (byte) val ← ++ (byte) val -- vbuz1=_inc_vbuz1
|
||||
inc.z val
|
||||
jmp __breturn
|
||||
// incval::@return
|
||||
__breturn:
|
||||
// [11] return
|
||||
// [10] return
|
||||
rts
|
||||
}
|
||||
// printval
|
||||
printval: {
|
||||
// [12] *((const byte*) SCREEN) ← (byte) val -- _deref_pbuc1=vbuz1
|
||||
// [11] *((const byte*) SCREEN) ← (byte) val -- _deref_pbuc1=vbuz1
|
||||
lda.z val
|
||||
sta SCREEN
|
||||
jmp __breturn
|
||||
// printval::@return
|
||||
__breturn:
|
||||
// [13] return
|
||||
// [12] return
|
||||
rts
|
||||
}
|
||||
// ival
|
||||
ival: {
|
||||
// [14] callprepare incval
|
||||
// [15] callexecute incval -- jsr
|
||||
// [13] callprepare incval
|
||||
// [14] callexecute incval -- jsr
|
||||
jsr incval
|
||||
// [16] callfinalize incval
|
||||
jmp __breturn
|
||||
// ival::@return
|
||||
__breturn:
|
||||
// [17] return
|
||||
// [15] return
|
||||
rts
|
||||
}
|
||||
// pval
|
||||
pval: {
|
||||
// [18] callprepare printval
|
||||
// [19] callexecute printval -- jsr
|
||||
// [16] callprepare printval
|
||||
// [17] callexecute printval -- jsr
|
||||
jsr printval
|
||||
// [20] callfinalize printval
|
||||
jmp __breturn
|
||||
// pval::@return
|
||||
__breturn:
|
||||
// [21] return
|
||||
// [18] return
|
||||
rts
|
||||
}
|
||||
// main
|
||||
main: {
|
||||
.label i = 4
|
||||
// [22] (byte) main::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
// [19] (byte) main::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z i
|
||||
jmp __b1
|
||||
// main::@1
|
||||
__b1:
|
||||
// [23] callprepare pval
|
||||
// [24] callexecute pval -- jsr
|
||||
// [20] callprepare pval
|
||||
// [21] callexecute pval -- jsr
|
||||
jsr pval
|
||||
// [25] callfinalize pval
|
||||
// [26] callprepare printother
|
||||
// [27] callexecute printother -- jsr
|
||||
// [22] callprepare printother
|
||||
// [23] callexecute printother -- jsr
|
||||
jsr printother
|
||||
// [28] callfinalize printother
|
||||
// [29] callprepare ival
|
||||
// [30] callexecute ival -- jsr
|
||||
// [24] callprepare ival
|
||||
// [25] callexecute ival -- jsr
|
||||
jsr ival
|
||||
// [31] callfinalize ival
|
||||
// [32] (byte) main::i ← ++ (byte) main::i -- vbuz1=_inc_vbuz1
|
||||
// [26] (byte) main::i ← ++ (byte) main::i -- vbuz1=_inc_vbuz1
|
||||
inc.z i
|
||||
// [33] if((byte) main::i!=(byte) 6) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
|
||||
// [27] if((byte) main::i!=(byte) 6) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
|
||||
lda #6
|
||||
cmp.z i
|
||||
bne __b1
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [34] return
|
||||
// [28] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Statement [0] (byte) val ← (byte) 0 [ val ] ( [ val ] ) always clobbers reg byte a
|
||||
Statement [5] (byte) printother::i ← (byte) 0 [ printother::i ] ( main:2::printother:27 [ val main::i printother::i ] ) always clobbers reg byte a
|
||||
Statement [6] *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) ← ++ *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) [ printother::i ] ( main:2::printother:27 [ val main::i printother::i ] ) always clobbers reg byte x
|
||||
Statement [8] if((byte) printother::i!=(byte) 6) goto printother::@1 [ printother::i ] ( main:2::printother:27 [ val main::i printother::i ] ) always clobbers reg byte a
|
||||
Statement [12] *((const byte*) SCREEN) ← (byte) val [ val ] ( main:2::pval:24::printval:19 [ main::i val ] ) always clobbers reg byte a
|
||||
Statement [22] (byte) main::i ← (byte) 0 [ val main::i ] ( main:2 [ val main::i ] ) always clobbers reg byte a
|
||||
Statement [33] if((byte) main::i!=(byte) 6) goto main::@1 [ val main::i ] ( main:2 [ val main::i ] ) always clobbers reg byte a
|
||||
Statement [4] (byte) printother::i ← (byte) 0 [ printother::i ] ( main:2::printother:23 [ val main::i printother::i ] ) always clobbers reg byte a
|
||||
Statement [5] *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) ← ++ *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) [ printother::i ] ( main:2::printother:23 [ val main::i printother::i ] ) always clobbers reg byte x
|
||||
Statement [7] if((byte) printother::i!=(byte) 6) goto printother::@1 [ printother::i ] ( main:2::printother:23 [ val main::i printother::i ] ) always clobbers reg byte a
|
||||
Statement [11] *((const byte*) SCREEN) ← (byte) val [ val ] ( main:2::pval:21::printval:17 [ main::i val ] ) always clobbers reg byte a
|
||||
Statement [19] (byte) main::i ← (byte) 0 [ val main::i ] ( main:2 [ val main::i ] ) always clobbers reg byte a
|
||||
Statement [27] if((byte) main::i!=(byte) 6) goto main::@1 [ val main::i ] ( main:2 [ val main::i ] ) always clobbers reg byte a
|
||||
Potential registers zp[1]:2 [ val ] : zp[1]:2 ,
|
||||
Potential registers zp[1]:3 [ printother::i ] : zp[1]:3 ,
|
||||
Potential registers zp[1]:4 [ main::i ] : zp[1]:4 ,
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [printother] 14.25: zp[1]:3 [ printother::i ]
|
||||
Uplift Scope [main] 2.92: zp[1]:4 [ main::i ]
|
||||
Uplift Scope [] 0.31: zp[1]:2 [ val ]
|
||||
Uplift Scope [main] 3.89: zp[1]:4 [ main::i ]
|
||||
Uplift Scope [] 0.38: zp[1]:2 [ val ]
|
||||
Uplift Scope [pval]
|
||||
Uplift Scope [ival]
|
||||
Uplift Scope [printval]
|
||||
@ -461,8 +443,7 @@ __b1:
|
||||
// [1] callprepare main
|
||||
// [2] callexecute main -- jsr
|
||||
jsr main
|
||||
// [3] callfinalize main
|
||||
// [4] phi from @1 to @end [phi:@1->@end]
|
||||
// [3] phi from @1 to @end [phi:@1->@end]
|
||||
__bend_from___b1:
|
||||
jmp __bend
|
||||
// @end
|
||||
@ -470,103 +451,98 @@ __bend:
|
||||
// printother
|
||||
printother: {
|
||||
.label i = 3
|
||||
// [5] (byte) printother::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
// [4] (byte) printother::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z i
|
||||
jmp __b1
|
||||
// printother::@1
|
||||
__b1:
|
||||
// [6] *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) ← ++ *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) -- pbuc1_derefidx_vbuz1=_inc_pbuc1_derefidx_vbuz1
|
||||
// [5] *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) ← ++ *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) -- pbuc1_derefidx_vbuz1=_inc_pbuc1_derefidx_vbuz1
|
||||
ldx.z i
|
||||
inc SCREEN+$28,x
|
||||
// [7] (byte) printother::i ← ++ (byte) printother::i -- vbuz1=_inc_vbuz1
|
||||
// [6] (byte) printother::i ← ++ (byte) printother::i -- vbuz1=_inc_vbuz1
|
||||
inc.z i
|
||||
// [8] if((byte) printother::i!=(byte) 6) goto printother::@1 -- vbuz1_neq_vbuc1_then_la1
|
||||
// [7] if((byte) printother::i!=(byte) 6) goto printother::@1 -- vbuz1_neq_vbuc1_then_la1
|
||||
lda #6
|
||||
cmp.z i
|
||||
bne __b1
|
||||
jmp __breturn
|
||||
// printother::@return
|
||||
__breturn:
|
||||
// [9] return
|
||||
// [8] return
|
||||
rts
|
||||
}
|
||||
// incval
|
||||
incval: {
|
||||
// [10] (byte) val ← ++ (byte) val -- vbuz1=_inc_vbuz1
|
||||
// [9] (byte) val ← ++ (byte) val -- vbuz1=_inc_vbuz1
|
||||
inc.z val
|
||||
jmp __breturn
|
||||
// incval::@return
|
||||
__breturn:
|
||||
// [11] return
|
||||
// [10] return
|
||||
rts
|
||||
}
|
||||
// printval
|
||||
printval: {
|
||||
// [12] *((const byte*) SCREEN) ← (byte) val -- _deref_pbuc1=vbuz1
|
||||
// [11] *((const byte*) SCREEN) ← (byte) val -- _deref_pbuc1=vbuz1
|
||||
lda.z val
|
||||
sta SCREEN
|
||||
jmp __breturn
|
||||
// printval::@return
|
||||
__breturn:
|
||||
// [13] return
|
||||
// [12] return
|
||||
rts
|
||||
}
|
||||
// ival
|
||||
ival: {
|
||||
// [14] callprepare incval
|
||||
// [15] callexecute incval -- jsr
|
||||
// [13] callprepare incval
|
||||
// [14] callexecute incval -- jsr
|
||||
jsr incval
|
||||
// [16] callfinalize incval
|
||||
jmp __breturn
|
||||
// ival::@return
|
||||
__breturn:
|
||||
// [17] return
|
||||
// [15] return
|
||||
rts
|
||||
}
|
||||
// pval
|
||||
pval: {
|
||||
// [18] callprepare printval
|
||||
// [19] callexecute printval -- jsr
|
||||
// [16] callprepare printval
|
||||
// [17] callexecute printval -- jsr
|
||||
jsr printval
|
||||
// [20] callfinalize printval
|
||||
jmp __breturn
|
||||
// pval::@return
|
||||
__breturn:
|
||||
// [21] return
|
||||
// [18] return
|
||||
rts
|
||||
}
|
||||
// main
|
||||
main: {
|
||||
.label i = 4
|
||||
// [22] (byte) main::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
// [19] (byte) main::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z i
|
||||
jmp __b1
|
||||
// main::@1
|
||||
__b1:
|
||||
// [23] callprepare pval
|
||||
// [24] callexecute pval -- jsr
|
||||
// [20] callprepare pval
|
||||
// [21] callexecute pval -- jsr
|
||||
jsr pval
|
||||
// [25] callfinalize pval
|
||||
// [26] callprepare printother
|
||||
// [27] callexecute printother -- jsr
|
||||
// [22] callprepare printother
|
||||
// [23] callexecute printother -- jsr
|
||||
jsr printother
|
||||
// [28] callfinalize printother
|
||||
// [29] callprepare ival
|
||||
// [30] callexecute ival -- jsr
|
||||
// [24] callprepare ival
|
||||
// [25] callexecute ival -- jsr
|
||||
jsr ival
|
||||
// [31] callfinalize ival
|
||||
// [32] (byte) main::i ← ++ (byte) main::i -- vbuz1=_inc_vbuz1
|
||||
// [26] (byte) main::i ← ++ (byte) main::i -- vbuz1=_inc_vbuz1
|
||||
inc.z i
|
||||
// [33] if((byte) main::i!=(byte) 6) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
|
||||
// [27] if((byte) main::i!=(byte) 6) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
|
||||
lda #6
|
||||
cmp.z i
|
||||
bne __b1
|
||||
jmp __breturn
|
||||
// main::@return
|
||||
__breturn:
|
||||
// [34] return
|
||||
// [28] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
@ -609,7 +585,7 @@ __stackcall (void()) ival()
|
||||
__stackcall (void()) main()
|
||||
(label) main::@1
|
||||
(label) main::@return
|
||||
(byte) main::i loadstore zp[1]:4 2.9166666666666665
|
||||
(byte) main::i loadstore zp[1]:4 3.8888888888888893
|
||||
__stackcall (void()) printother()
|
||||
(label) printother::@1
|
||||
(label) printother::@return
|
||||
@ -618,7 +594,7 @@ __stackcall (void()) printval()
|
||||
(label) printval::@return
|
||||
__stackcall (void()) pval()
|
||||
(label) pval::@return
|
||||
(byte) val loadstore zp[1]:2 0.3076923076923077
|
||||
(byte) val loadstore zp[1]:2 0.38095238095238093
|
||||
|
||||
zp[1]:2 [ val ]
|
||||
zp[1]:3 [ printother::i ]
|
||||
@ -649,113 +625,107 @@ __bbegin:
|
||||
// [2] callexecute main -- jsr
|
||||
jsr main
|
||||
rts
|
||||
// [3] callfinalize main
|
||||
// [4] phi from @1 to @end [phi:@1->@end]
|
||||
// [3] phi from @1 to @end [phi:@1->@end]
|
||||
// @end
|
||||
// printother
|
||||
printother: {
|
||||
.label i = 3
|
||||
// for(char i:0..5)
|
||||
// [5] (byte) printother::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
// [4] (byte) printother::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z i
|
||||
// printother::@1
|
||||
__b1:
|
||||
// (SCREEN+40)[i]++;
|
||||
// [6] *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) ← ++ *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) -- pbuc1_derefidx_vbuz1=_inc_pbuc1_derefidx_vbuz1
|
||||
// [5] *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) ← ++ *((const byte*) SCREEN+(byte) $28 + (byte) printother::i) -- pbuc1_derefidx_vbuz1=_inc_pbuc1_derefidx_vbuz1
|
||||
ldx.z i
|
||||
inc SCREEN+$28,x
|
||||
// for(char i:0..5)
|
||||
// [7] (byte) printother::i ← ++ (byte) printother::i -- vbuz1=_inc_vbuz1
|
||||
// [6] (byte) printother::i ← ++ (byte) printother::i -- vbuz1=_inc_vbuz1
|
||||
inc.z i
|
||||
// [8] if((byte) printother::i!=(byte) 6) goto printother::@1 -- vbuz1_neq_vbuc1_then_la1
|
||||
// [7] if((byte) printother::i!=(byte) 6) goto printother::@1 -- vbuz1_neq_vbuc1_then_la1
|
||||
lda #6
|
||||
cmp.z i
|
||||
bne __b1
|
||||
// printother::@return
|
||||
// }
|
||||
// [9] return
|
||||
// [8] return
|
||||
rts
|
||||
}
|
||||
// incval
|
||||
incval: {
|
||||
// val++;
|
||||
// [10] (byte) val ← ++ (byte) val -- vbuz1=_inc_vbuz1
|
||||
// [9] (byte) val ← ++ (byte) val -- vbuz1=_inc_vbuz1
|
||||
inc.z val
|
||||
// incval::@return
|
||||
// }
|
||||
// [11] return
|
||||
// [10] return
|
||||
rts
|
||||
}
|
||||
// printval
|
||||
printval: {
|
||||
// SCREEN[0] = val
|
||||
// [12] *((const byte*) SCREEN) ← (byte) val -- _deref_pbuc1=vbuz1
|
||||
// [11] *((const byte*) SCREEN) ← (byte) val -- _deref_pbuc1=vbuz1
|
||||
lda.z val
|
||||
sta SCREEN
|
||||
// printval::@return
|
||||
// }
|
||||
// [13] return
|
||||
// [12] return
|
||||
rts
|
||||
}
|
||||
// ival
|
||||
ival: {
|
||||
// incval()
|
||||
// [14] callprepare incval
|
||||
// [15] callexecute incval -- jsr
|
||||
// [13] callprepare incval
|
||||
// [14] callexecute incval -- jsr
|
||||
jsr incval
|
||||
// [16] callfinalize incval
|
||||
// ival::@return
|
||||
// }
|
||||
// [17] return
|
||||
// [15] return
|
||||
rts
|
||||
}
|
||||
// pval
|
||||
pval: {
|
||||
// printval()
|
||||
// [18] callprepare printval
|
||||
// [19] callexecute printval -- jsr
|
||||
// [16] callprepare printval
|
||||
// [17] callexecute printval -- jsr
|
||||
jsr printval
|
||||
// [20] callfinalize printval
|
||||
// pval::@return
|
||||
// }
|
||||
// [21] return
|
||||
// [18] return
|
||||
rts
|
||||
}
|
||||
// main
|
||||
main: {
|
||||
.label i = 4
|
||||
// for(char i:0..5)
|
||||
// [22] (byte) main::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
// [19] (byte) main::i ← (byte) 0 -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta.z i
|
||||
// main::@1
|
||||
__b1:
|
||||
// pval()
|
||||
// [23] callprepare pval
|
||||
// [24] callexecute pval -- jsr
|
||||
// [20] callprepare pval
|
||||
// [21] callexecute pval -- jsr
|
||||
jsr pval
|
||||
// [25] callfinalize pval
|
||||
// printother()
|
||||
// [26] callprepare printother
|
||||
// [27] callexecute printother -- jsr
|
||||
// [22] callprepare printother
|
||||
// [23] callexecute printother -- jsr
|
||||
jsr printother
|
||||
// [28] callfinalize printother
|
||||
// ival()
|
||||
// [29] callprepare ival
|
||||
// [30] callexecute ival -- jsr
|
||||
// [24] callprepare ival
|
||||
// [25] callexecute ival -- jsr
|
||||
jsr ival
|
||||
// [31] callfinalize ival
|
||||
// for(char i:0..5)
|
||||
// [32] (byte) main::i ← ++ (byte) main::i -- vbuz1=_inc_vbuz1
|
||||
// [26] (byte) main::i ← ++ (byte) main::i -- vbuz1=_inc_vbuz1
|
||||
inc.z i
|
||||
// [33] if((byte) main::i!=(byte) 6) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
|
||||
// [27] if((byte) main::i!=(byte) 6) goto main::@1 -- vbuz1_neq_vbuc1_then_la1
|
||||
lda #6
|
||||
cmp.z i
|
||||
bne __b1
|
||||
// main::@return
|
||||
// }
|
||||
// [34] return
|
||||
// [28] return
|
||||
rts
|
||||
}
|
||||
// File Data
|
||||
|
@ -9,7 +9,7 @@ __stackcall (void()) ival()
|
||||
__stackcall (void()) main()
|
||||
(label) main::@1
|
||||
(label) main::@return
|
||||
(byte) main::i loadstore zp[1]:4 2.9166666666666665
|
||||
(byte) main::i loadstore zp[1]:4 3.8888888888888893
|
||||
__stackcall (void()) printother()
|
||||
(label) printother::@1
|
||||
(label) printother::@return
|
||||
@ -18,7 +18,7 @@ __stackcall (void()) printval()
|
||||
(label) printval::@return
|
||||
__stackcall (void()) pval()
|
||||
(label) pval::@return
|
||||
(byte) val loadstore zp[1]:2 0.3076923076923077
|
||||
(byte) val loadstore zp[1]:2 0.38095238095238093
|
||||
|
||||
zp[1]:2 [ val ]
|
||||
zp[1]:3 [ printother::i ]
|
||||
|
Loading…
Reference in New Issue
Block a user