mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-04-08 14:37:40 +00:00
Working loop unrolling! There are probably still a lot of non-working cases - and the lack of loop unroll limit will definitely cause infinite loops.
This commit is contained in:
parent
bbeb37ea61
commit
be18a84d98
@ -30,12 +30,17 @@ public class CompileLog {
|
||||
/**
|
||||
* Should SSA optimization be verbose.
|
||||
*/
|
||||
private boolean verboseSSAOptimize = true;
|
||||
private boolean verboseSSAOptimize = false;
|
||||
|
||||
/**
|
||||
* Should SSA optimization be verbose.
|
||||
*/
|
||||
private boolean verboseLoopUnroll = false;
|
||||
|
||||
/**
|
||||
* Should the log be output to System.out while being built
|
||||
*/
|
||||
private boolean sysOut = true;
|
||||
private boolean sysOut = false;
|
||||
|
||||
public CompileLog() {
|
||||
this.log = new StringBuilder();
|
||||
@ -93,6 +98,10 @@ public class CompileLog {
|
||||
this.verboseSSAOptimize = verboseSSAOptimize;
|
||||
}
|
||||
|
||||
public boolean isVerboseLoopUnroll() {
|
||||
return verboseLoopUnroll;
|
||||
}
|
||||
|
||||
public boolean isSysOut() {
|
||||
return sysOut;
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package dk.camelot64.kickc;
|
||||
|
||||
import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.CompileError;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.StatementSequence;
|
||||
import dk.camelot64.kickc.model.statements.StatementCall;
|
||||
import dk.camelot64.kickc.model.statements.StatementSource;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
@ -37,7 +39,7 @@ public class Compiler {
|
||||
}
|
||||
final CharStream fileStream = CharStreams.fromPath(file.toPath());
|
||||
imported.add(file.getAbsolutePath());
|
||||
program.getLog().append("PARSING " + file.getPath().replace("\\","/"));
|
||||
program.getLog().append("PARSING " + file.getPath().replace("\\", "/"));
|
||||
program.getLog().append(fileStream.toString());
|
||||
KickCLexer lexer = new KickCLexer(fileStream);
|
||||
KickCParser parser = new KickCParser(new CommonTokenStream(lexer));
|
||||
@ -93,7 +95,7 @@ public class Compiler {
|
||||
program.setStatementSequence(sequence);
|
||||
|
||||
pass1GenerateSSA();
|
||||
pass2OptimizeSSA();
|
||||
pass2Optimize();
|
||||
pass2UnrollLoops();
|
||||
pass2InlineConstants();
|
||||
pass3Analysis();
|
||||
@ -184,7 +186,7 @@ public class Compiler {
|
||||
}
|
||||
}
|
||||
|
||||
private void pass2OptimizeSSA() {
|
||||
private void pass2Optimize() {
|
||||
List<Pass2SsaOptimization> optimizations = new ArrayList<>();
|
||||
optimizations.add(new Pass2CullEmptyBlocks(program));
|
||||
optimizations.add(new Pass2UnaryNotSimplification(program));
|
||||
@ -203,19 +205,10 @@ public class Compiler {
|
||||
optimizations.add(new Pass2NopCastElimination(program));
|
||||
optimizations.add(new Pass2EliminateUnusedBlocks(program));
|
||||
optimizations.add(new Pass2RangeResolving(program));
|
||||
pass2OptimizeSSA(optimizations);
|
||||
|
||||
pass2Execute(optimizations);
|
||||
}
|
||||
|
||||
private void pass2UnrollLoops() {
|
||||
getLog().append("CONTROL FLOW GRAPH BEFORE UNROLLING");
|
||||
getLog().append(program.getGraph().toString(program));
|
||||
|
||||
new Pass2DominatorsAnalysis(program).step();
|
||||
getLog().append("NATURAL LOOPS");
|
||||
new Pass2LoopAnalysis(program).step();
|
||||
getLog().append(program.getLoopSet().toString());
|
||||
|
||||
List<Pass2SsaOptimization> loopUnrolling = new ArrayList<>();
|
||||
loopUnrolling.add(new PassNStatementIndices(program));
|
||||
loopUnrolling.add(new PassNVariableReferenceInfos(program));
|
||||
@ -224,7 +217,21 @@ public class Compiler {
|
||||
loopUnrolling.add(new Pass2LoopAnalysis(program));
|
||||
loopUnrolling.add(new Pass2LoopUnrollPhiPrepare(program));
|
||||
loopUnrolling.add(new Pass2LoopUnroll(program));
|
||||
pass2OptimizeSSA(loopUnrolling);
|
||||
|
||||
boolean unrolled;
|
||||
do {
|
||||
unrolled = pass2ExecuteOnce(loopUnrolling);
|
||||
if(unrolled) {
|
||||
|
||||
if(getLog().isVerboseLoopUnroll()) {
|
||||
getLog().append("UNROLLED CONTROL FLOW GRAPH");
|
||||
getLog().append(program.getGraph().toString(program));
|
||||
}
|
||||
pass2Optimize();
|
||||
new Pass3BlockSequencePlanner(program).plan();
|
||||
}
|
||||
} while(unrolled);
|
||||
|
||||
}
|
||||
|
||||
private void pass2InlineConstants() {
|
||||
@ -235,10 +242,15 @@ public class Compiler {
|
||||
constantOptimizations.add(new Pass2ConstantIdentification(program));
|
||||
constantOptimizations.add(new Pass2ConstantAdditionElimination(program));
|
||||
constantOptimizations.add(new Pass2ConstantIfs(program));
|
||||
pass2OptimizeSSA(constantOptimizations);
|
||||
pass2Execute(constantOptimizations);
|
||||
}
|
||||
|
||||
private void pass2OptimizeSSA(List<Pass2SsaOptimization> optimizations) {
|
||||
/**
|
||||
* Execute optimization steps repeatedly until none of them performs an optimization anymore
|
||||
*
|
||||
* @param optimizations The optimizations to repeat
|
||||
*/
|
||||
private void pass2Execute(List<Pass2SsaOptimization> optimizations) {
|
||||
getLog().append("OPTIMIZING CONTROL FLOW GRAPH");
|
||||
boolean ssaOptimized = true;
|
||||
while(ssaOptimized) {
|
||||
@ -261,6 +273,29 @@ public class Compiler {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Repeat a set of optimizations steps once each.
|
||||
*
|
||||
* @param optimizations The optimizations
|
||||
* @return true if any step performed an optimization
|
||||
*/
|
||||
private boolean pass2ExecuteOnce(List<Pass2SsaOptimization> optimizations) {
|
||||
boolean ssaOptimized = false;
|
||||
for(Pass2SsaOptimization optimization : optimizations) {
|
||||
pass2AssertSSA();
|
||||
boolean stepOptimized = optimization.step();
|
||||
if(stepOptimized) {
|
||||
getLog().append("Successful SSA optimization " + optimization.getClass().getSimpleName() + "");
|
||||
ssaOptimized = true;
|
||||
if(getLog().isVerboseSSAOptimize()) {
|
||||
getLog().append("CONTROL FLOW GRAPH");
|
||||
getLog().append(program.getGraph().toString(program));
|
||||
}
|
||||
}
|
||||
}
|
||||
return ssaOptimized;
|
||||
}
|
||||
|
||||
private void pass3Analysis() {
|
||||
|
||||
new Pass3AssertRValues(program).check();
|
||||
@ -321,7 +356,10 @@ public class Compiler {
|
||||
getLog().append(program.getDominators().toString());
|
||||
|
||||
getLog().append("NATURAL LOOPS");
|
||||
boolean wasVerbose = getLog().isVerboseSSAOptimize();
|
||||
getLog().setVerboseSSAOptimize(true);
|
||||
new Pass2LoopAnalysis(program).step();
|
||||
getLog().setVerboseSSAOptimize(wasVerbose);
|
||||
getLog().append(program.getLoopSet().toString());
|
||||
|
||||
getLog().append("NATURAL LOOPS WITH DEPTH");
|
||||
|
@ -18,8 +18,12 @@ public interface Statement {
|
||||
void setIndex(Integer idx);
|
||||
|
||||
/**
|
||||
* Get the source for the statement*
|
||||
* Get the source for the statement
|
||||
*/
|
||||
StatementSource getSource();
|
||||
|
||||
/**
|
||||
* Set the source for the statement
|
||||
*/
|
||||
void setSource(StatementSource source);
|
||||
}
|
||||
|
@ -26,6 +26,11 @@ public abstract class StatementBase implements Statement {
|
||||
return source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSource(StatementSource source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getIndex() {
|
||||
return index;
|
||||
|
@ -263,7 +263,7 @@ public abstract class Scope implements Symbol {
|
||||
}
|
||||
|
||||
public Label getLabel(String name) {
|
||||
return (Label) symbols.get(name);
|
||||
return (Label) getSymbol(name);
|
||||
}
|
||||
|
||||
public Label getLabel(LabelRef labelRef) {
|
||||
|
@ -41,6 +41,14 @@ public class Pass2EliminateUnusedBlocks extends Pass2SsaOptimization {
|
||||
Variable variable = getScope().getVariable((VariableRef) lValue);
|
||||
variable.getScope().remove(variable);
|
||||
}
|
||||
} else if(stmt instanceof StatementPhiBlock) {
|
||||
for(StatementPhiBlock.PhiVariable phiVariable : ((StatementPhiBlock) stmt).getPhiVariables()) {
|
||||
VariableRef phiVar = phiVariable.getVariable();
|
||||
getLog().append("Eliminating variable " + phiVar.toString(getProgram()) + " from unused block " + block.getLabel());
|
||||
Variable variable = getScope().getVariable(phiVar);
|
||||
variable.getScope().remove(variable);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -99,7 +99,9 @@ public class Pass2LoopAnalysis extends Pass2SsaOptimization {
|
||||
loop.addTails(other.getTails());
|
||||
loop.addBlocks(other.getBlocks());
|
||||
loopSet.remove(other);
|
||||
getLog().append("Coalesced: " + loop.toString());
|
||||
if(getLog().isVerboseSSAOptimize()) {
|
||||
getLog().append("Coalesced: " + loop.toString());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,14 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementConditionalJump;
|
||||
import dk.camelot64.kickc.model.statements.StatementPhiBlock;
|
||||
import dk.camelot64.kickc.model.iterator.ProgramValue;
|
||||
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
|
||||
import dk.camelot64.kickc.model.statements.*;
|
||||
import dk.camelot64.kickc.model.symbols.Label;
|
||||
import dk.camelot64.kickc.model.symbols.Scope;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.symbols.VariableVersion;
|
||||
import dk.camelot64.kickc.model.values.LabelRef;
|
||||
import dk.camelot64.kickc.model.values.RValue;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@ -23,80 +22,295 @@ public class Pass2LoopUnroll extends Pass2SsaOptimization {
|
||||
@Override
|
||||
public boolean step() {
|
||||
// Look for loops to unroll
|
||||
NaturalLoopSet loops = getProgram().getLoopSet();
|
||||
List<NaturalLoop> unrollLoopCandidates = findUnrollLoopCandidates(getProgram(), loops);
|
||||
List<NaturalLoop> unrollLoops = findUnrollLoops(getProgram());
|
||||
// Is there any unrolling to do?
|
||||
if(unrollLoopCandidates.isEmpty()) {
|
||||
if(unrollLoops.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
// Choose the candidate loop with the fewest blocks (and if several have the same number of blocks the first one encountered)
|
||||
NaturalLoop unrollLoop = chooseUnrollLoop(unrollLoopCandidates);
|
||||
NaturalLoop unrollLoop = chooseUnrollLoop(unrollLoops);
|
||||
getLog().append("Unrolling loop " + unrollLoop);
|
||||
|
||||
// Unroll the first iteration of the loop
|
||||
|
||||
// 0. Unroll Symbols
|
||||
// - Create new versions of all symbols assigned inside the loop
|
||||
Map<VariableRef, VariableRef> definedToNewVar = new LinkedHashMap<>();
|
||||
for(VariableRef definedVarRef : getVarsDefinedInLoop(getProgram(), unrollLoop)) {
|
||||
Variable definedVar = getScope().getVariable(definedVarRef);
|
||||
Variable newVar;
|
||||
if(definedVarRef.isIntermediate()) {
|
||||
newVar = definedVar.getScope().addVariableIntermediate();
|
||||
} else if(definedVarRef.isVersion()) {
|
||||
newVar = ((VariableVersion) definedVar).getVersionOf().createVersion();
|
||||
} else {
|
||||
throw new RuntimeException("Error! Variable is not versioned or intermediate " + definedVar.toString(getProgram()));
|
||||
}
|
||||
definedToNewVar.put(definedVarRef, newVar.getRef());
|
||||
getLog().append("Defined in loop: " + definedVarRef.getFullName() + " -> " + newVar.getRef().getFullName());
|
||||
}
|
||||
Map<VariableRef, VariableRef> definedToNewVar = copyVarsDefinedInLoop(unrollLoop);
|
||||
|
||||
// - Create new labels for all blocks in the loop
|
||||
Map<LabelRef, LabelRef> blockToNewBlock = copyBlocksInLoop(unrollLoop);
|
||||
|
||||
// 1. Copy all loop blocks to create the "rest of the loop" and modifying the existing loop to only be the first iteration)
|
||||
// - Unroll Statements (copy all statements, replace symbols properly (with the new versions / the versions assigned in the existing loop)
|
||||
// - Includes unrolling PHI-statements properly
|
||||
// - Unroll Successors (loop-exit successors should point to the same exit, loop-internal successors should point to the new loop-internal block)
|
||||
for(ControlFlowBlock block : unrollLoop.getBlocks(getGraph())) {
|
||||
// Find the serial number
|
||||
int unrollSerial = 1;
|
||||
String unrollLabelName = block.getLabel() + "_" + unrollSerial;
|
||||
while(getScope().getLabel(unrollLabelName) != null) {
|
||||
unrollSerial++;
|
||||
}
|
||||
// Create a label
|
||||
Label unrollLabel = getScope().getScope(block.getScope()).addLabel(unrollLabelName);
|
||||
// Create the new block
|
||||
ControlFlowBlock unrollBlock = new ControlFlowBlock(unrollLabel.getRef(), block.getScope());
|
||||
getProgram().getGraph().addBlock(unrollBlock);
|
||||
LabelRef newBlockLabel = unrollLabel(block.getLabel(), blockToNewBlock);
|
||||
ControlFlowBlock newBlock = new ControlFlowBlock(newBlockLabel, block.getScope());
|
||||
getProgram().getGraph().addBlock(newBlock);
|
||||
for(Statement statement : block.getStatements()) {
|
||||
Statement newStatement = unrollStatement(statement, unrollLoop, blockToNewBlock, definedToNewVar);
|
||||
newBlock.addStatement(newStatement);
|
||||
if(newStatement instanceof StatementConditionalJump) {
|
||||
newBlock.setConditionalSuccessor(((StatementConditionalJump) newStatement).getDestination());
|
||||
}
|
||||
}
|
||||
newBlock.setDefaultSuccessor(unrollLabel(block.getDefaultSuccessor(), blockToNewBlock));
|
||||
}
|
||||
|
||||
// Patch the "old loop" to only contain the first iteration
|
||||
for(ControlFlowBlock block : unrollLoop.getBlocks(getGraph())) {
|
||||
// - All successors in the old loop to the loop head should point to the new loop head instead.
|
||||
|
||||
// If the successor is the loop head then update to the new copied loop head instead
|
||||
block.setDefaultSuccessor(fixSuccessor(block.getDefaultSuccessor(), blockToNewBlock, unrollLoop));
|
||||
|
||||
for(Statement statement : block.getStatements()) {
|
||||
if(statement instanceof StatementPhiBlock) {
|
||||
StatementPhiBlock phiBlock = (StatementPhiBlock) statement;
|
||||
StatementPhiBlock unrollPhiBlock = new StatementPhiBlock();
|
||||
for(StatementPhiBlock.PhiVariable phiVariable : phiBlock.getPhiVariables()) {
|
||||
VariableRef phiVar = phiVariable.getVariable();
|
||||
VariableRef newVar = definedToNewVar.get(phiVar);
|
||||
StatementPhiBlock.PhiVariable unrollPhiVariable = unrollPhiBlock.addPhiVariable(newVar);
|
||||
for(StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) {
|
||||
/* FIX */
|
||||
LabelRef predecessor = phiRValue.getPredecessor();
|
||||
/* FIX */
|
||||
RValue rValue = phiRValue.getrValue();
|
||||
unrollPhiVariable.setrValue(predecessor, rValue);
|
||||
// - Remove phi-variables in the old head from looping. (as this predecessor now no longer exists)
|
||||
for(StatementPhiBlock.PhiVariable phiVariable : ((StatementPhiBlock) statement).getPhiVariables()) {
|
||||
List<StatementPhiBlock.PhiRValue> phiVariableValues = phiVariable.getValues();
|
||||
ListIterator<StatementPhiBlock.PhiRValue> phiRValueListIterator = phiVariableValues.listIterator();
|
||||
while(phiRValueListIterator.hasNext()) {
|
||||
StatementPhiBlock.PhiRValue phiRValue = phiRValueListIterator.next();
|
||||
if(unrollLoop.getBlocks().contains(phiRValue.getPredecessor())) {
|
||||
// Found predecessor inside the same loop - remove it!
|
||||
phiRValueListIterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("Statement not handled by unroll " + statement);
|
||||
} else if(statement instanceof StatementConditionalJump) {
|
||||
// - Remove the "unroll" directive on the condition in the old loop (as it is already unrolled).
|
||||
// TODO: Only remove "unroll" from the conditional that represents the loop we are unrolling
|
||||
StatementConditionalJump conditionalJump = (StatementConditionalJump) statement;
|
||||
conditionalJump.setDeclaredUnroll(false);
|
||||
// Fix the destination (if needed)!
|
||||
LabelRef fixedDestination = fixSuccessor(conditionalJump.getDestination(), blockToNewBlock, unrollLoop);
|
||||
conditionalJump.setDestination(fixedDestination);
|
||||
block.setConditionalSuccessor(fixedDestination);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Patch the "old loop" to only contain the first iteration
|
||||
// - All successors in the old loop to the loop head should point to the new loop head instead.
|
||||
// - Remove phi-variables in the old head from looping. (as this predecessor now no longer exists)
|
||||
// - Remove the "unroll" directive on the condition in the old loop (as it is already unrolled).
|
||||
// Update phi-blocks in loop successors to also include the new unrolled "rest" loop
|
||||
List<LoopSuccessorBlock> loopSuccessorBlocks = getLoopSuccessorBlocks(unrollLoop, getGraph());
|
||||
for(LoopSuccessorBlock loopSuccessorBlock : loopSuccessorBlocks) {
|
||||
ControlFlowBlock successorBlock = getGraph().getBlock(loopSuccessorBlock.successor);
|
||||
StatementPhiBlock phiBlock = successorBlock.getPhiBlock();
|
||||
for(StatementPhiBlock.PhiVariable phiVariable : phiBlock.getPhiVariables()) {
|
||||
for(StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) {
|
||||
if(unrollLoop.getBlocks().contains(phiRValue.getPredecessor())) {
|
||||
// Found a phi variable with values from the poriginal loop in a loop successor block
|
||||
// Add another value when entering from the unrolled loop
|
||||
phiVariable.setrValue(unrollLabel(phiRValue.getPredecessor(), blockToNewBlock), unrollValue(phiRValue.getrValue(), definedToNewVar));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix a successor block in the original loop (that is now only the first iteration).
|
||||
*
|
||||
* @param successor The successor
|
||||
* @param blockToNewBlock The map from loop blocks to the corresponding unrolled "rest" loop blocks.
|
||||
* @param unrollLoop The loop being unrolled
|
||||
* @return The fixed successor label
|
||||
*/
|
||||
private LabelRef fixSuccessor(LabelRef successor, Map<LabelRef, LabelRef> blockToNewBlock, NaturalLoop unrollLoop) {
|
||||
LabelRef fixed;
|
||||
if(unrollLoop.getHead().equals(successor)) {
|
||||
fixed = blockToNewBlock.get(successor);
|
||||
} else {
|
||||
fixed = successor;
|
||||
}
|
||||
return fixed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unroll a single statement inside a loop.
|
||||
* Copy the statement, replace symbols properly (with the new versions if needed). This includes unrolling loop PHI-statements properly
|
||||
* Unroll Successors (loop-exit successors should point to the same exit, loop-internal successors should point to the new loop-internal block)
|
||||
*
|
||||
* @param statement The statement to unroll
|
||||
* @param unrollLoop The loop being unrolled
|
||||
* @param blockToNewBlock Map from loop block label to the label of the copied block in the new (rest) loop
|
||||
* @param definedToNewVar Map from variables defined in the loop to the copied variable in the new (rest) loop
|
||||
* @return The copied & unrolled statement
|
||||
*/
|
||||
private Statement unrollStatement(Statement statement, NaturalLoop unrollLoop, Map<LabelRef, LabelRef> blockToNewBlock, Map<VariableRef, VariableRef> definedToNewVar) {
|
||||
if(statement instanceof StatementPhiBlock) {
|
||||
StatementPhiBlock phiBlock = (StatementPhiBlock) statement;
|
||||
StatementPhiBlock newPhiBlock = new StatementPhiBlock();
|
||||
for(StatementPhiBlock.PhiVariable phiVariable : phiBlock.getPhiVariables()) {
|
||||
VariableRef phiVar = phiVariable.getVariable();
|
||||
VariableRef newVar = definedToNewVar.get(phiVar);
|
||||
StatementPhiBlock.PhiVariable newPhiVariable = newPhiBlock.addPhiVariable(newVar);
|
||||
for(StatementPhiBlock.PhiRValue phiRValue : phiVariable.getValues()) {
|
||||
LabelRef predecessor = phiRValue.getPredecessor();
|
||||
if(unrollLoop.getBlocks().contains(predecessor)) {
|
||||
// Predecessor inside the loop - create two copies (one from the original loop block and onw from the new copy)
|
||||
// Entering from iteration 1 use the original value from iteration 1
|
||||
RValue rValue = copyValue(phiRValue.getrValue());
|
||||
newPhiVariable.setrValue(predecessor, rValue);
|
||||
// Entering from the new rest-of-loop block perform a mapping replacing all references to variables inside the loop to the new versions.
|
||||
RValue rValueNew = unrollValue(phiRValue.getrValue(), definedToNewVar);
|
||||
newPhiVariable.setrValue(unrollLabel(predecessor, blockToNewBlock), rValueNew);
|
||||
} else {
|
||||
// Predecessor outside loop - do not copy since all entry to the copy of the loop will be through the first iteration
|
||||
}
|
||||
}
|
||||
}
|
||||
return newPhiBlock;
|
||||
} else if(statement instanceof StatementAssignment) {
|
||||
StatementAssignment assignment = (StatementAssignment) statement;
|
||||
return new StatementAssignment(
|
||||
(LValue) unrollValue(assignment.getlValue(), definedToNewVar),
|
||||
unrollValue(assignment.getrValue1(), definedToNewVar),
|
||||
assignment.getOperator(),
|
||||
unrollValue(assignment.getrValue2(), definedToNewVar),
|
||||
assignment.getSource()
|
||||
);
|
||||
} else if(statement instanceof StatementConditionalJump) {
|
||||
StatementConditionalJump conditional = (StatementConditionalJump) statement;
|
||||
LabelRef labelRef = conditional.getDestination();
|
||||
StatementConditionalJump newConditional = new StatementConditionalJump(
|
||||
unrollValue(conditional.getrValue1(), definedToNewVar),
|
||||
conditional.getOperator(),
|
||||
unrollValue(conditional.getrValue2(), definedToNewVar),
|
||||
unrollLabel(labelRef, blockToNewBlock),
|
||||
conditional.getSource()
|
||||
);
|
||||
newConditional.setDeclaredUnroll(conditional.isDeclaredUnroll());
|
||||
return newConditional;
|
||||
} else {
|
||||
throw new RuntimeException("Statement not handled by unroll " + statement);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the passed label is from the original loop return the corresponding label from the unrolled "rest" loop
|
||||
* Otherwise the passed label is returned.
|
||||
*
|
||||
* @param labelRef The label
|
||||
* @param blockToNewBlock Maps labels from the original loop to the new labels in the unrolled "rest" loop.
|
||||
* @return The label to use in the unrolled loop
|
||||
*/
|
||||
private LabelRef unrollLabel(LabelRef labelRef, Map<LabelRef, LabelRef> blockToNewBlock) {
|
||||
LabelRef unrolledLabel = blockToNewBlock.get(labelRef);
|
||||
if(unrolledLabel == null) {
|
||||
return labelRef;
|
||||
} else {
|
||||
return unrolledLabel;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update all variable references in an RValue that point to variables inside the loop to the new unrolled "rest" loop.
|
||||
*
|
||||
* @param rValue The rValue to update
|
||||
* @param definedToNewVar Map from variables defined in the original loop to the variables in the new unrolled "rest" loop
|
||||
* @return A copy of the RValue with all relevant variable sreferences updated
|
||||
*/
|
||||
private RValue unrollValue(RValue rValue, Map<VariableRef, VariableRef> definedToNewVar) {
|
||||
if(rValue == null) return null;
|
||||
RValue rValueCopy = copyValue(rValue);
|
||||
ProgramValue.GenericValue genericValue = new ProgramValue.GenericValue(rValueCopy);
|
||||
ProgramValueIterator.execute(genericValue, (programValue, currentStmt, stmtIt, currentBlock) -> {
|
||||
RValue rVal = programValue.get();
|
||||
if(rVal instanceof VariableRef) {
|
||||
if(definedToNewVar.get(rVal) != null) {
|
||||
programValue.set(definedToNewVar.get(rVal));
|
||||
}
|
||||
}
|
||||
}, null, null, null);
|
||||
return genericValue.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a copy of the passed value object (to avoid that two parts of the model points to the same object).
|
||||
*
|
||||
* @param rValue The value to copy
|
||||
* @return An exact copy of the value
|
||||
*/
|
||||
private RValue copyValue(RValue rValue) {
|
||||
if(rValue == null) return null;
|
||||
ProgramValue.GenericValue genericValue = new ProgramValue.GenericValue(rValue);
|
||||
ProgramValueIterator.execute(genericValue, (programValue, currentStmt, stmtIt, currentBlock) -> {
|
||||
RValue rVal = programValue.get();
|
||||
if(rVal instanceof PointerDereferenceSimple) {
|
||||
programValue.set(new PointerDereferenceSimple(((PointerDereferenceSimple) rVal).getPointer()));
|
||||
} else if(rVal instanceof PointerDereferenceIndexed) {
|
||||
programValue.set(new PointerDereferenceIndexed(((PointerDereferenceIndexed) rVal).getPointer(), ((PointerDereferenceIndexed) rVal).getIndex()));
|
||||
} else if(rVal instanceof CastValue) {
|
||||
programValue.set(new CastValue(((CastValue) rVal).getToType(), ((CastValue) rVal).getValue()));
|
||||
} else if(rVal instanceof ValueList) {
|
||||
programValue.set(new ValueList(new ArrayList<>(((ValueList) rVal).getList())));
|
||||
}
|
||||
}, null, null, null);
|
||||
return genericValue.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy all blocks in a loop. The new copies are named from the original name plus an integer suffix.
|
||||
*
|
||||
* @param unrollLoop The loop being copied
|
||||
* @return A map from each block label (from the loop) to the new copied labels
|
||||
*/
|
||||
private Map<LabelRef, LabelRef> copyBlocksInLoop(NaturalLoop unrollLoop) {
|
||||
LinkedHashMap<LabelRef, LabelRef> blockToNewBlock = new LinkedHashMap<>();
|
||||
for(ControlFlowBlock block : unrollLoop.getBlocks(getGraph())) {
|
||||
Scope blockScope = getScope().getScope(block.getScope());
|
||||
// Find the serial number
|
||||
int unrollSerial = 1;
|
||||
String localName = block.getLabel().getLocalName();
|
||||
int serialPos = localName.lastIndexOf("_");
|
||||
if(serialPos>=0) {
|
||||
localName = localName.substring(0, serialPos);
|
||||
}
|
||||
|
||||
String unrollLabelName;
|
||||
do {
|
||||
unrollLabelName = localName + "_" + unrollSerial++;
|
||||
} while(blockScope.getLabel(unrollLabelName) != null);
|
||||
// Create a label
|
||||
Label unrollLabel = blockScope.addLabel(unrollLabelName);
|
||||
blockToNewBlock.put(block.getLabel(), unrollLabel.getRef());
|
||||
}
|
||||
return blockToNewBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new versions of all symbols assigned inside the loop
|
||||
*
|
||||
* @param unrollLoop The loop being unrolled
|
||||
* @return A map from variables assigned inside the loop to the new copy of the variable
|
||||
*/
|
||||
private Map<VariableRef, VariableRef> copyVarsDefinedInLoop(NaturalLoop unrollLoop) {
|
||||
Map<VariableRef, VariableRef> definedToNewVar = new LinkedHashMap<>();
|
||||
for(VariableRef definedVarRef : getVarsDefinedInLoop(unrollLoop, getProgram())) {
|
||||
Variable definedVar = getScope().getVariable(definedVarRef);
|
||||
Variable newVar;
|
||||
if(definedVarRef.isIntermediate()) {
|
||||
newVar = definedVar.getScope().addVariableIntermediate();
|
||||
newVar.setType(definedVar.getType());
|
||||
newVar.setDeclaredRegister(definedVar.getDeclaredRegister());
|
||||
newVar.setDeclaredVolatile(definedVar.isDeclaredVolatile());
|
||||
newVar.setDeclaredAlignment(definedVar.getDeclaredAlignment());
|
||||
newVar.setInferredType(definedVar.isInferredType());
|
||||
} else if(definedVarRef.isVersion()) {
|
||||
newVar = ((VariableVersion) definedVar).getVersionOf().createVersion();
|
||||
} else {
|
||||
throw new RuntimeException("Error! Variable is not versioned or intermediate " + definedVar.toString(getProgram()));
|
||||
}
|
||||
definedToNewVar.put(definedVarRef, newVar.getRef());
|
||||
//getLog().append("Defined in loop: " + definedVarRef.getFullName() + " -> " + newVar.getRef().getFullName());
|
||||
}
|
||||
return definedToNewVar;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -104,10 +318,10 @@ public class Pass2LoopUnroll extends Pass2SsaOptimization {
|
||||
* The smallest loop (fewest control flow blocks) is chosen.
|
||||
* If multiple loops have the same size the first one is chosen.
|
||||
*
|
||||
* @param unrollLoopCandidates All loops that are decalred to be unrolled
|
||||
* @param unrollLoopCandidates All loops that are declared to be unrolled
|
||||
* @return The loop to unroll first.
|
||||
*/
|
||||
private NaturalLoop chooseUnrollLoop(List<NaturalLoop> unrollLoopCandidates) {
|
||||
private static NaturalLoop chooseUnrollLoop(List<NaturalLoop> unrollLoopCandidates) {
|
||||
NaturalLoop unrollLoop = null;
|
||||
for(NaturalLoop unrollLoopCandidate : unrollLoopCandidates) {
|
||||
if(unrollLoop == null) {
|
||||
@ -121,14 +335,14 @@ public class Pass2LoopUnroll extends Pass2SsaOptimization {
|
||||
return unrollLoop;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find all loops declared for unrolling. This is done by examining all conditional jumps, which hold the loop unroll declaration.
|
||||
*
|
||||
* @param loops All loops identified in the program
|
||||
* @param program The program
|
||||
* @return All loops declared to be unrolled
|
||||
*/
|
||||
static List<NaturalLoop> findUnrollLoopCandidates(Program program, NaturalLoopSet loops) {
|
||||
static List<NaturalLoop> findUnrollLoops(Program program) {
|
||||
NaturalLoopSet loops = program.getLoopSet();
|
||||
List<NaturalLoop> unrollLoopCandidates = new ArrayList<>();
|
||||
for(ControlFlowBlock block : program.getGraph().getAllBlocks()) {
|
||||
for(Statement statement : block.getStatements()) {
|
||||
@ -155,11 +369,12 @@ public class Pass2LoopUnroll extends Pass2SsaOptimization {
|
||||
|
||||
/**
|
||||
* Get all variables defined inside a loop
|
||||
* @param program The program
|
||||
*
|
||||
* @param loop The loop
|
||||
* @param program The program
|
||||
* @return All variables defined inside the blocks of the loop
|
||||
*/
|
||||
static List<VariableRef> getVarsDefinedInLoop(Program program, NaturalLoop loop) {
|
||||
static List<VariableRef> getVarsDefinedInLoop(NaturalLoop loop, Program program) {
|
||||
VariableReferenceInfos variableReferenceInfos = program.getVariableReferenceInfos();
|
||||
List<VariableRef> definedInLoop = new ArrayList<>();
|
||||
for(ControlFlowBlock block : loop.getBlocks(program.getGraph())) {
|
||||
@ -173,23 +388,24 @@ public class Pass2LoopUnroll extends Pass2SsaOptimization {
|
||||
return definedInLoop;
|
||||
}
|
||||
|
||||
/** Information about a block successing a loop - ie. a place where the flow of control leaves a loop. */
|
||||
/** Information about a block succeeding a loop - ie. a place where the flow of control leaves a loop. */
|
||||
public static class LoopSuccessorBlock {
|
||||
/** A block that is the sucessor to a block inside the loop. */
|
||||
LabelRef sucessor;
|
||||
/** The block inside the loop that is the predecessor of the loop sucessor block. */
|
||||
/** A block that is the successor to a block inside the loop. */
|
||||
LabelRef successor;
|
||||
/** The block inside the loop that is the predecessor of the loop successor block. */
|
||||
LabelRef predecessor;
|
||||
|
||||
public LoopSuccessorBlock(LabelRef sucessor, LabelRef predecessor) {
|
||||
this.sucessor = sucessor;
|
||||
public LoopSuccessorBlock(LabelRef successor, LabelRef predecessor) {
|
||||
this.successor = successor;
|
||||
this.predecessor = predecessor;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all transitions where the flow of control leaves a loop
|
||||
*
|
||||
* @param loop The loop to examine
|
||||
* @param graph The control flow graph
|
||||
* @param graph The control flow graph
|
||||
* @return
|
||||
*/
|
||||
static List<LoopSuccessorBlock> getLoopSuccessorBlocks(NaturalLoop loop, ControlFlowGraph graph) {
|
||||
@ -207,5 +423,19 @@ public class Pass2LoopUnroll extends Pass2SsaOptimization {
|
||||
return loopSuccessors;
|
||||
}
|
||||
|
||||
static boolean isReferencedOutsideLoop(VariableRef definedVarRef, NaturalLoop unrollLoop, Program program) {
|
||||
boolean referencedOutsideLoop = false;
|
||||
VariableReferenceInfos variableReferenceInfos = program.getVariableReferenceInfos();
|
||||
Collection<Integer> varRefStatements = variableReferenceInfos.getVarRefStatements(definedVarRef);
|
||||
for(Integer varRefStatement : varRefStatements) {
|
||||
StatementInfos statementInfos = program.getStatementInfos();
|
||||
ControlFlowBlock refBlock = statementInfos.getBlock(varRefStatement);
|
||||
if(!unrollLoop.getBlocks().contains(refBlock.getLabel())) {
|
||||
referencedOutsideLoop = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return referencedOutsideLoop;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.ControlFlowBlock;
|
||||
import dk.camelot64.kickc.model.NaturalLoop;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
|
||||
import dk.camelot64.kickc.model.statements.StatementInfos;
|
||||
import dk.camelot64.kickc.model.statements.StatementPhiBlock;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.symbols.VariableVersion;
|
||||
@ -11,13 +12,11 @@ import dk.camelot64.kickc.model.values.RValue;
|
||||
import dk.camelot64.kickc.model.values.SymbolRef;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Prepare for unrolling loops declared as inline.
|
||||
* This is done byensuring that all variables defined inside the loops and used outside the loop is passed through a PHI-functions
|
||||
* This is done by ensuring that all variables defined inside the loops and used outside the loop is passed through a PHI-functions
|
||||
* upon loop exit thus ensuring that these variables are only used inside the loop and in the PHI-function.
|
||||
* This makes it much easier to perform the unrolling as only a few parts of the program must be modified.
|
||||
*/
|
||||
@ -30,82 +29,45 @@ public class Pass2LoopUnrollPhiPrepare extends Pass2SsaOptimization {
|
||||
@Override
|
||||
public boolean step() {
|
||||
// Look for loops to unroll
|
||||
NaturalLoopSet loops = getProgram().getLoopSet();
|
||||
List<NaturalLoop> unrollLoopCandidates = Pass2LoopUnroll.findUnrollLoopCandidates(getProgram(), loops);
|
||||
// Is there any unrolling to do?
|
||||
if(unrollLoopCandidates.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
for(NaturalLoop unrollLoop : unrollLoopCandidates) {
|
||||
|
||||
List<VariableRef> definedInLoop = Pass2LoopUnroll.getVarsDefinedInLoop(getProgram(), unrollLoop);
|
||||
for(NaturalLoop unrollLoop : Pass2LoopUnroll.findUnrollLoops(getProgram())) {
|
||||
// - Ensure that all variables assigned inside the loop has a PHI in successor blocks to the loop
|
||||
// - Find loop successor blocks
|
||||
List<Pass2LoopUnroll.LoopSuccessorBlock> loopSuccessors = Pass2LoopUnroll.getLoopSuccessorBlocks(unrollLoop, getGraph());
|
||||
// - Add any needed PHI-statements to the successors
|
||||
for(VariableRef definedVarRef : definedInLoop) {
|
||||
for(VariableRef definedVarRef : Pass2LoopUnroll.getVarsDefinedInLoop(unrollLoop, getProgram())) {
|
||||
// Find out if the variable is ever referenced outside the loop
|
||||
if(isReferencedOutsideLoop(definedVarRef, unrollLoop, getProgram())) {
|
||||
for(Pass2LoopUnroll.LoopSuccessorBlock loopSuccessor : loopSuccessors) {
|
||||
LabelRef successorBlockRef = loopSuccessor.sucessor;
|
||||
if(Pass2LoopUnroll.isReferencedOutsideLoop(definedVarRef, unrollLoop, getProgram())) {
|
||||
// - Add any needed PHI-statements to the successors
|
||||
for(Pass2LoopUnroll.LoopSuccessorBlock loopSuccessor : Pass2LoopUnroll.getLoopSuccessorBlocks(unrollLoop, getGraph())) {
|
||||
|
||||
LabelRef successorBlockRef = loopSuccessor.successor;
|
||||
LabelRef successorPredecessorRef = loopSuccessor.predecessor;
|
||||
ControlFlowBlock successorBlock = getGraph().getBlock(successorBlockRef);
|
||||
StatementPhiBlock phiBlock = successorBlock.getPhiBlock();
|
||||
|
||||
// Look for a phi-variable
|
||||
boolean phiFound = false;
|
||||
for(StatementPhiBlock.PhiVariable phiVariable : phiBlock.getPhiVariables()) {
|
||||
if(phiVariable.getVariable().isVersion() && definedVarRef.isVersion()) {
|
||||
if(phiVariable.getVariable().getFullNameUnversioned().equals(definedVarRef.getFullNameUnversioned())) {
|
||||
phiFound = true;
|
||||
// Create a new version of the variable
|
||||
Variable definedVar = getScope().getVariable(definedVarRef);
|
||||
Variable newVar = ((VariableVersion) definedVar).getVersionOf().createVersion();
|
||||
|
||||
// Replace all references outside the loop to the new version!
|
||||
LinkedHashMap<SymbolRef, RValue> aliases = new LinkedHashMap<>();
|
||||
aliases.put(definedVarRef, newVar.getRef());
|
||||
ProgramValueIterator.execute(getProgram(), (programValue, currentStmt, stmtIt, currentBlock) -> {
|
||||
if(currentBlock != null) {
|
||||
if(!unrollLoop.getBlocks().contains(currentBlock.getLabel())) {
|
||||
new AliasReplacer(aliases).execute(programValue, currentStmt, stmtIt, currentBlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!phiFound) {
|
||||
Variable definedVar = getScope().getVariable(definedVarRef);
|
||||
Variable newVar = ((VariableVersion) definedVar).getVersionOf().createVersion();
|
||||
});
|
||||
|
||||
// Replace all references to definedVarRef outside loop to newVar!
|
||||
LinkedHashMap<SymbolRef, RValue> aliases = new LinkedHashMap<>();
|
||||
aliases.put(definedVarRef, newVar.getRef());
|
||||
ProgramValueIterator.execute(getProgram(), (programValue, currentStmt, stmtIt, currentBlock) -> {
|
||||
if(currentBlock != null) {
|
||||
if(!unrollLoop.getBlocks().contains(currentBlock.getLabel())) {
|
||||
new AliasReplacer(aliases).execute(programValue, currentStmt, stmtIt, currentBlock);
|
||||
}
|
||||
}
|
||||
});
|
||||
// Create the new phi-variable in the successor phi block
|
||||
StatementPhiBlock.PhiVariable newPhiVar = phiBlock.addPhiVariable(newVar.getRef());
|
||||
newPhiVar.setrValue(successorPredecessorRef, definedVarRef);
|
||||
getLog().append("Creating PHI for " + definedVarRef.getFullName() + " in block " + successorBlock.getLabel() + " - " + phiBlock.toString(getProgram(), false));
|
||||
|
||||
// Create the new phi-variable
|
||||
StatementPhiBlock.PhiVariable newPhiVar = phiBlock.addPhiVariable(newVar.getRef());
|
||||
newPhiVar.setrValue(successorPredecessorRef, definedVarRef);
|
||||
getLog().append("Creating PHI for " + definedVarRef.getFullName() + " in block " + successorBlock.getLabel() + " - " + phiBlock.toString(getProgram(), false));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
getLog().append(getGraph().toString(getProgram()));
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isReferencedOutsideLoop(VariableRef definedVarRef, NaturalLoop unrollLoop, Program program) {
|
||||
boolean referencedOutsideLoop = false;
|
||||
VariableReferenceInfos variableReferenceInfos = program.getVariableReferenceInfos();
|
||||
Collection<Integer> varRefStatements = variableReferenceInfos.getVarRefStatements(definedVarRef);
|
||||
for(Integer varRefStatement : varRefStatements) {
|
||||
StatementInfos statementInfos = program.getStatementInfos();
|
||||
ControlFlowBlock refBlock = statementInfos.getBlock(varRefStatement);
|
||||
if(!unrollLoop.getBlocks().contains(refBlock.getLabel())) {
|
||||
referencedOutsideLoop = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return referencedOutsideLoop;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,18 +1,15 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.ControlFlowBlock;
|
||||
import dk.camelot64.kickc.model.symbols.Label;
|
||||
import dk.camelot64.kickc.model.symbols.Procedure;
|
||||
import dk.camelot64.kickc.model.values.LabelRef;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.symbols.Scope;
|
||||
import dk.camelot64.kickc.model.values.LabelRef;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/** Plan the optimal sequence for the blocks of the control flow graph */
|
||||
public class Pass3BlockSequencePlanner extends Pass2Base {
|
||||
|
||||
|
||||
Deque<ScopeTodo> todoScopes = new ArrayDeque<>();
|
||||
|
||||
public Pass3BlockSequencePlanner(Program program) {
|
||||
|
@ -52,8 +52,18 @@ public class TestPrograms {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnrollScreenFill() throws IOException, URISyntaxException {
|
||||
compileAndCompare("unroll-screenfill");
|
||||
public void testUnrollScreenFillFor() throws IOException, URISyntaxException {
|
||||
compileAndCompare("unroll-screenfill-for");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnrollScreenFillWhile() throws IOException, URISyntaxException {
|
||||
compileAndCompare("unroll-screenfill-while");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnrollModifyVar() throws IOException, URISyntaxException {
|
||||
compileAndCompare("unroll-loop-modifyvar");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -0,0 +1,13 @@
|
||||
// An unrolled loop modifying a var used later
|
||||
|
||||
void main() {
|
||||
byte* SCREEN = $400;
|
||||
|
||||
byte a=3;
|
||||
inline do {
|
||||
SCREEN[a]=a;
|
||||
a++;
|
||||
} while(a<14);
|
||||
SCREEN[a]=a;
|
||||
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
// Fills the screen using an unrolled inner ranged for()-loop
|
||||
|
||||
void main() {
|
||||
byte* SCREEN = $400;
|
||||
|
||||
for(byte x: 0..39) {
|
||||
inline for(byte line: 0..24) {
|
||||
(SCREEN+line*40)[x] = x;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
// Fills the screen using an unrolled inner while()-loop
|
||||
|
||||
void main() {
|
||||
byte* SCREEN = $400;
|
||||
for(byte x: 0..39) {
|
||||
byte line = 0;
|
||||
inline while(line!=25) {
|
||||
(SCREEN+line*40)[x] = x;
|
||||
line++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
// Fills the screen using an unrolled inner loop
|
||||
|
||||
void main() {
|
||||
byte* SCREEN = $400;
|
||||
|
||||
byte a=3;
|
||||
inline do {
|
||||
SCREEN[a]=a;
|
||||
a++;
|
||||
} while(a<14);
|
||||
SCREEN[a]=a;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
for(byte x: 0..39) {
|
||||
|
||||
inline for(byte line: 0..24) {
|
||||
(SCREEN+line*40)[x] = x;
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
for(byte x: 0..39) {
|
||||
byte line = 0;
|
||||
inline while(line!=25 || x<10) {
|
||||
(SCREEN+line*40)[x] = x;
|
||||
line++;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
12
src/test/java/dk/camelot64/kickc/test/ref/loop100.asm
Normal file
12
src/test/java/dk/camelot64/kickc/test/ref/loop100.asm
Normal file
@ -0,0 +1,12 @@
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
jsr main
|
||||
main: {
|
||||
ldx #0
|
||||
b1:
|
||||
inx
|
||||
cpx #$64
|
||||
bcc b1
|
||||
rts
|
||||
}
|
20
src/test/java/dk/camelot64/kickc/test/ref/loop100.cfg
Normal file
20
src/test/java/dk/camelot64/kickc/test/ref/loop100.cfg
Normal file
@ -0,0 +1,20 @@
|
||||
@begin: scope:[] from
|
||||
[0] phi() [ ] ( )
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi() [ ] ( )
|
||||
[2] call main [ ] ( )
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi() [ ] ( )
|
||||
main: scope:[main] from @1
|
||||
[4] phi() [ ] ( main:2 [ ] )
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
[5] (byte) main::i#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@1/(byte) main::i#1 ) [ main::i#2 ] ( main:2 [ main::i#2 ] )
|
||||
[6] (byte) main::i#1 ← ++ (byte) main::i#2 [ main::i#1 ] ( main:2 [ main::i#1 ] )
|
||||
[7] if((byte) main::i#1<(byte/signed byte/word/signed word/dword/signed dword) 100) goto main::@1 [ main::i#1 ] ( main:2 [ main::i#1 ] )
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[8] return [ ] ( main:2 [ ] )
|
||||
to:@return
|
346
src/test/java/dk/camelot64/kickc/test/ref/loop100.log
Normal file
346
src/test/java/dk/camelot64/kickc/test/ref/loop100.log
Normal file
@ -0,0 +1,346 @@
|
||||
PARSING src/test/java/dk/camelot64/kickc/test/kc/loop100.kc
|
||||
|
||||
void main() {
|
||||
for(byte i=0; i<100; i++) { }
|
||||
}
|
||||
Adding pre/post-modifier (byte) main::i ← ++ (byte) main::i
|
||||
SYMBOLS
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(void()) main()
|
||||
(bool~) main::$0
|
||||
(label) main::@1
|
||||
(label) main::@2
|
||||
(label) main::@return
|
||||
(byte) main::i
|
||||
|
||||
INITIAL CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
to:@1
|
||||
main: scope:[main] from
|
||||
(byte) main::i ← (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
(byte) main::i ← ++ (byte) main::i
|
||||
(bool~) main::$0 ← (byte) main::i < (byte/signed byte/word/signed word/dword/signed dword) 100
|
||||
if((bool~) main::$0) goto main::@1
|
||||
to:main::@2
|
||||
main::@2: scope:[main] from main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@2
|
||||
return
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
|
||||
Removing empty block main::@2
|
||||
PROCEDURE MODIFY VARIABLE ANALYSIS
|
||||
|
||||
Completing Phi functions...
|
||||
|
||||
CONTROL FLOW GRAPH SSA WITH ASSIGNMENT CALL & RETURN
|
||||
@begin: scope:[] from
|
||||
to:@1
|
||||
main: scope:[main] from @1
|
||||
(byte) main::i#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
(byte) main::i#2 ← phi( main/(byte) main::i#0 main::@1/(byte) main::i#1 )
|
||||
(byte) main::i#1 ← ++ (byte) main::i#2
|
||||
(bool~) main::$0 ← (byte) main::i#1 < (byte/signed byte/word/signed word/dword/signed dword) 100
|
||||
if((bool~) main::$0) goto main::@1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
return
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
call main
|
||||
to:@2
|
||||
@2: scope:[] from @1
|
||||
to:@end
|
||||
@end: scope:[] from @2
|
||||
|
||||
SYMBOL TABLE SSA
|
||||
(label) @1
|
||||
(label) @2
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(void()) main()
|
||||
(bool~) main::$0
|
||||
(label) main::@1
|
||||
(label) main::@return
|
||||
(byte) main::i
|
||||
(byte) main::i#0
|
||||
(byte) main::i#1
|
||||
(byte) main::i#2
|
||||
|
||||
OPTIMIZING CONTROL FLOW GRAPH
|
||||
Culled Empty Block (label) @2
|
||||
Succesful SSA optimization Pass2CullEmptyBlocks
|
||||
Simple Condition (bool~) main::$0 if((byte) main::i#1<(byte/signed byte/word/signed word/dword/signed dword) 100) goto main::@1
|
||||
Succesful SSA optimization Pass2ConditionalJumpSimplification
|
||||
Constant (const byte) main::i#0 = 0
|
||||
Succesful SSA optimization Pass2ConstantIdentification
|
||||
OPTIMIZING CONTROL FLOW GRAPH
|
||||
Inlining constant with var siblings (const byte) main::i#0
|
||||
Inlining constant with var siblings (const byte) main::i#0
|
||||
Constant inlined main::i#0 = (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
Succesful SSA optimization Pass2ConstantInlining
|
||||
Block Sequence Planned @begin @1 @end main main::@1 main::@return
|
||||
Added new block during phi lifting main::@3(between main::@1 and main::@1)
|
||||
Block Sequence Planned @begin @1 @end main main::@1 main::@return main::@3
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @1
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of main
|
||||
CALL GRAPH
|
||||
Calls in [] to main:2
|
||||
|
||||
Propagating live ranges...
|
||||
Propagating live ranges...
|
||||
Created 1 initial phi equivalence classes
|
||||
Coalesced [9] main::i#3 ← main::i#1
|
||||
Coalesced down to 1 phi equivalence classes
|
||||
Culled Empty Block (label) main::@3
|
||||
Block Sequence Planned @begin @1 @end main main::@1 main::@return
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @1
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of main
|
||||
Propagating live ranges...
|
||||
Propagating live ranges...
|
||||
|
||||
FINAL CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
[0] phi() [ ] ( )
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi() [ ] ( )
|
||||
[2] call main [ ] ( )
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi() [ ] ( )
|
||||
main: scope:[main] from @1
|
||||
[4] phi() [ ] ( main:2 [ ] )
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
[5] (byte) main::i#2 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@1/(byte) main::i#1 ) [ main::i#2 ] ( main:2 [ main::i#2 ] )
|
||||
[6] (byte) main::i#1 ← ++ (byte) main::i#2 [ main::i#1 ] ( main:2 [ main::i#1 ] )
|
||||
[7] if((byte) main::i#1<(byte/signed byte/word/signed word/dword/signed dword) 100) goto main::@1 [ main::i#1 ] ( main:2 [ main::i#1 ] )
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@1
|
||||
[8] return [ ] ( main:2 [ ] )
|
||||
to:@return
|
||||
|
||||
DOMINATORS
|
||||
@begin dominated by @begin
|
||||
@1 dominated by @1 @begin
|
||||
@end dominated by @1 @begin @end
|
||||
main dominated by @1 @begin main
|
||||
main::@1 dominated by @1 @begin main::@1 main
|
||||
main::@return dominated by main::@return @1 @begin main::@1 main
|
||||
|
||||
NATURAL LOOPS
|
||||
Found back edge: Loop head: main::@1 tails: main::@1 blocks: null
|
||||
Populated: Loop head: main::@1 tails: main::@1 blocks: main::@1
|
||||
Loop head: main::@1 tails: main::@1 blocks: main::@1
|
||||
|
||||
NATURAL LOOPS WITH DEPTH
|
||||
Found 0 loops in scope []
|
||||
Found 1 loops in scope [main]
|
||||
Loop head: main::@1 tails: main::@1 blocks: main::@1
|
||||
Loop head: main::@1 tails: main::@1 blocks: main::@1 depth: 1
|
||||
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
(void()) main()
|
||||
(byte) main::i
|
||||
(byte) main::i#1 16.5
|
||||
(byte) main::i#2 22.0
|
||||
|
||||
Initial phi equivalence classes
|
||||
[ main::i#2 main::i#1 ]
|
||||
Complete equivalence classes
|
||||
[ main::i#2 main::i#1 ]
|
||||
Allocated zp ZP_BYTE:2 [ main::i#2 main::i#1 ]
|
||||
|
||||
INITIAL ASM
|
||||
//SEG0 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
//SEG1 Global Constants & labels
|
||||
//SEG2 @begin
|
||||
bbegin:
|
||||
//SEG3 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
b1_from_bbegin:
|
||||
jmp b1
|
||||
//SEG4 @1
|
||||
b1:
|
||||
//SEG5 [2] call main [ ] ( )
|
||||
//SEG6 [4] phi from @1 to main [phi:@1->main]
|
||||
main_from_b1:
|
||||
jsr main
|
||||
//SEG7 [3] phi from @1 to @end [phi:@1->@end]
|
||||
bend_from_b1:
|
||||
jmp bend
|
||||
//SEG8 @end
|
||||
bend:
|
||||
//SEG9 main
|
||||
main: {
|
||||
.label i = 2
|
||||
//SEG10 [5] phi from main to main::@1 [phi:main->main::@1]
|
||||
b1_from_main:
|
||||
//SEG11 [5] phi (byte) main::i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#0] -- vbuz1=vbuc1
|
||||
lda #0
|
||||
sta i
|
||||
jmp b1
|
||||
//SEG12 [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
|
||||
b1_from_b1:
|
||||
//SEG13 [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy
|
||||
jmp b1
|
||||
//SEG14 main::@1
|
||||
b1:
|
||||
//SEG15 [6] (byte) main::i#1 ← ++ (byte) main::i#2 [ main::i#1 ] ( main:2 [ main::i#1 ] ) -- vbuz1=_inc_vbuz1
|
||||
inc i
|
||||
//SEG16 [7] if((byte) main::i#1<(byte/signed byte/word/signed word/dword/signed dword) 100) goto main::@1 [ main::i#1 ] ( main:2 [ main::i#1 ] ) -- vbuz1_lt_vbuc1_then_la1
|
||||
lda i
|
||||
cmp #$64
|
||||
bcc b1_from_b1
|
||||
jmp breturn
|
||||
//SEG17 main::@return
|
||||
breturn:
|
||||
//SEG18 [8] return [ ] ( main:2 [ ] )
|
||||
rts
|
||||
}
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Potential registers zp ZP_BYTE:2 [ main::i#2 main::i#1 ] : zp ZP_BYTE:2 , reg byte a , reg byte x , reg byte y ,
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [main] 38.5: zp ZP_BYTE:2 [ main::i#2 main::i#1 ]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [main] best 193 combination reg byte x [ main::i#2 main::i#1 ]
|
||||
Uplifting [] best 193 combination
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
//SEG0 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
//SEG1 Global Constants & labels
|
||||
//SEG2 @begin
|
||||
bbegin:
|
||||
//SEG3 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
b1_from_bbegin:
|
||||
jmp b1
|
||||
//SEG4 @1
|
||||
b1:
|
||||
//SEG5 [2] call main [ ] ( )
|
||||
//SEG6 [4] phi from @1 to main [phi:@1->main]
|
||||
main_from_b1:
|
||||
jsr main
|
||||
//SEG7 [3] phi from @1 to @end [phi:@1->@end]
|
||||
bend_from_b1:
|
||||
jmp bend
|
||||
//SEG8 @end
|
||||
bend:
|
||||
//SEG9 main
|
||||
main: {
|
||||
//SEG10 [5] phi from main to main::@1 [phi:main->main::@1]
|
||||
b1_from_main:
|
||||
//SEG11 [5] phi (byte) main::i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1
|
||||
ldx #0
|
||||
jmp b1
|
||||
//SEG12 [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
|
||||
b1_from_b1:
|
||||
//SEG13 [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy
|
||||
jmp b1
|
||||
//SEG14 main::@1
|
||||
b1:
|
||||
//SEG15 [6] (byte) main::i#1 ← ++ (byte) main::i#2 [ main::i#1 ] ( main:2 [ main::i#1 ] ) -- vbuxx=_inc_vbuxx
|
||||
inx
|
||||
//SEG16 [7] if((byte) main::i#1<(byte/signed byte/word/signed word/dword/signed dword) 100) goto main::@1 [ main::i#1 ] ( main:2 [ main::i#1 ] ) -- vbuxx_lt_vbuc1_then_la1
|
||||
cpx #$64
|
||||
bcc b1_from_b1
|
||||
jmp breturn
|
||||
//SEG17 main::@return
|
||||
breturn:
|
||||
//SEG18 [8] return [ ] ( main:2 [ ] )
|
||||
rts
|
||||
}
|
||||
|
||||
ASSEMBLER OPTIMIZATIONS
|
||||
Removing instruction jmp b1
|
||||
Removing instruction jmp bend
|
||||
Removing instruction jmp b1
|
||||
Removing instruction jmp breturn
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Replacing label b1_from_b1 with b1
|
||||
Removing instruction bbegin:
|
||||
Removing instruction b1_from_bbegin:
|
||||
Removing instruction main_from_b1:
|
||||
Removing instruction bend_from_b1:
|
||||
Removing instruction b1_from_b1:
|
||||
Succesful ASM optimization Pass5RedundantLabelElimination
|
||||
Removing instruction b1:
|
||||
Removing instruction bend:
|
||||
Removing instruction b1_from_main:
|
||||
Removing instruction breturn:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
Removing instruction jmp b1
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
|
||||
FINAL SYMBOL TABLE
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(void()) main()
|
||||
(label) main::@1
|
||||
(label) main::@return
|
||||
(byte) main::i
|
||||
(byte) main::i#1 reg byte x 16.5
|
||||
(byte) main::i#2 reg byte x 22.0
|
||||
|
||||
reg byte x [ main::i#2 main::i#1 ]
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 97
|
||||
|
||||
//SEG0 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
//SEG1 Global Constants & labels
|
||||
//SEG2 @begin
|
||||
//SEG3 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
//SEG4 @1
|
||||
//SEG5 [2] call main [ ] ( )
|
||||
//SEG6 [4] phi from @1 to main [phi:@1->main]
|
||||
jsr main
|
||||
//SEG7 [3] phi from @1 to @end [phi:@1->@end]
|
||||
//SEG8 @end
|
||||
//SEG9 main
|
||||
main: {
|
||||
//SEG10 [5] phi from main to main::@1 [phi:main->main::@1]
|
||||
//SEG11 [5] phi (byte) main::i#2 = (byte/signed byte/word/signed word/dword/signed dword) 0 [phi:main->main::@1#0] -- vbuxx=vbuc1
|
||||
ldx #0
|
||||
//SEG12 [5] phi from main::@1 to main::@1 [phi:main::@1->main::@1]
|
||||
//SEG13 [5] phi (byte) main::i#2 = (byte) main::i#1 [phi:main::@1->main::@1#0] -- register_copy
|
||||
//SEG14 main::@1
|
||||
b1:
|
||||
//SEG15 [6] (byte) main::i#1 ← ++ (byte) main::i#2 [ main::i#1 ] ( main:2 [ main::i#1 ] ) -- vbuxx=_inc_vbuxx
|
||||
inx
|
||||
//SEG16 [7] if((byte) main::i#1<(byte/signed byte/word/signed word/dword/signed dword) 100) goto main::@1 [ main::i#1 ] ( main:2 [ main::i#1 ] ) -- vbuxx_lt_vbuc1_then_la1
|
||||
cpx #$64
|
||||
bcc b1
|
||||
//SEG17 main::@return
|
||||
//SEG18 [8] return [ ] ( main:2 [ ] )
|
||||
rts
|
||||
}
|
||||
|
11
src/test/java/dk/camelot64/kickc/test/ref/loop100.sym
Normal file
11
src/test/java/dk/camelot64/kickc/test/ref/loop100.sym
Normal file
@ -0,0 +1,11 @@
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(void()) main()
|
||||
(label) main::@1
|
||||
(label) main::@return
|
||||
(byte) main::i
|
||||
(byte) main::i#1 reg byte x 16.5
|
||||
(byte) main::i#2 reg byte x 22.0
|
||||
|
||||
reg byte x [ main::i#2 main::i#1 ]
|
@ -0,0 +1,32 @@
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
jsr main
|
||||
main: {
|
||||
.label SCREEN = $400
|
||||
lda #3
|
||||
sta SCREEN+3
|
||||
lda #3+1
|
||||
sta SCREEN+3+1
|
||||
lda #3+1+1
|
||||
sta SCREEN+3+1+1
|
||||
lda #3+1+1+1
|
||||
sta SCREEN+3+1+1+1
|
||||
lda #3+1+1+1+1
|
||||
sta SCREEN+3+1+1+1+1
|
||||
lda #3+1+1+1+1+1
|
||||
sta SCREEN+3+1+1+1+1+1
|
||||
lda #3+1+1+1+1+1+1
|
||||
sta SCREEN+3+1+1+1+1+1+1
|
||||
lda #3+1+1+1+1+1+1+1
|
||||
sta SCREEN+3+1+1+1+1+1+1+1
|
||||
lda #3+1+1+1+1+1+1+1+1
|
||||
sta SCREEN+3+1+1+1+1+1+1+1+1
|
||||
lda #3+1+1+1+1+1+1+1+1+1
|
||||
sta SCREEN+3+1+1+1+1+1+1+1+1+1
|
||||
lda #3+1+1+1+1+1+1+1+1+1+1
|
||||
sta SCREEN+3+1+1+1+1+1+1+1+1+1+1
|
||||
lda #3+1+1+1+1+1+1+1+1+1+1+1
|
||||
sta SCREEN+3+1+1+1+1+1+1+1+1+1+1+1
|
||||
rts
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
@begin: scope:[] from
|
||||
[0] phi() [ ] ( )
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi() [ ] ( )
|
||||
[2] call main [ ] ( )
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi() [ ] ( )
|
||||
main: scope:[main] from @1
|
||||
[4] phi() [ ] ( main:2 [ ] )
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main
|
||||
[5] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 3) ← (byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] )
|
||||
to:main::@1_1
|
||||
main::@1_1: scope:[main] from main::@1
|
||||
[6] *((const byte*) main::SCREEN#0+++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] )
|
||||
to:main::@1_2
|
||||
main::@1_2: scope:[main] from main::@1_1
|
||||
[7] *((const byte*) main::SCREEN#0+++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] )
|
||||
to:main::@1_3
|
||||
main::@1_3: scope:[main] from main::@1_2
|
||||
[8] *((const byte*) main::SCREEN#0+++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] )
|
||||
to:main::@1_4
|
||||
main::@1_4: scope:[main] from main::@1_3
|
||||
[9] *((const byte*) main::SCREEN#0+++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] )
|
||||
to:main::@1_5
|
||||
main::@1_5: scope:[main] from main::@1_4
|
||||
[10] *((const byte*) main::SCREEN#0+++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] )
|
||||
to:main::@1_6
|
||||
main::@1_6: scope:[main] from main::@1_5
|
||||
[11] *((const byte*) main::SCREEN#0+++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] )
|
||||
to:main::@1_7
|
||||
main::@1_7: scope:[main] from main::@1_6
|
||||
[12] *((const byte*) main::SCREEN#0+++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] )
|
||||
to:main::@1_8
|
||||
main::@1_8: scope:[main] from main::@1_7
|
||||
[13] *((const byte*) main::SCREEN#0+++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] )
|
||||
to:main::@1_9
|
||||
main::@1_9: scope:[main] from main::@1_8
|
||||
[14] *((const byte*) main::SCREEN#0+++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] )
|
||||
to:main::@1_10
|
||||
main::@1_10: scope:[main] from main::@1_9
|
||||
[15] *((const byte*) main::SCREEN#0+++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] )
|
||||
to:main::@2
|
||||
main::@2: scope:[main] from main::@1_10
|
||||
[16] *((const byte*) main::SCREEN#0+++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] )
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@2
|
||||
[17] return [ ] ( main:2 [ ] )
|
||||
to:@return
|
@ -0,0 +1,920 @@
|
||||
PARSING src/test/java/dk/camelot64/kickc/test/kc/unroll-loop-modifyvar.kc
|
||||
// An unrolled loop modifying a var used later
|
||||
|
||||
void main() {
|
||||
byte* SCREEN = $400;
|
||||
|
||||
byte a=3;
|
||||
inline do {
|
||||
SCREEN[a]=a;
|
||||
a++;
|
||||
} while(a<14);
|
||||
SCREEN[a]=a;
|
||||
|
||||
}
|
||||
Adding pre/post-modifier (byte) main::a ← ++ (byte) main::a
|
||||
SYMBOLS
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(void()) main()
|
||||
(bool~) main::$0
|
||||
(label) main::@1
|
||||
(label) main::@2
|
||||
(label) main::@return
|
||||
(byte*) main::SCREEN
|
||||
(byte) main::a
|
||||
|
||||
Promoting word/signed word/dword/signed dword to byte* in main::SCREEN ← ((byte*)) 1024
|
||||
INITIAL CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
to:@1
|
||||
main: scope:[main] from
|
||||
(byte*) main::SCREEN ← ((byte*)) (word/signed word/dword/signed dword) 1024
|
||||
(byte) main::a ← (byte/signed byte/word/signed word/dword/signed dword) 3
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
*((byte*) main::SCREEN + (byte) main::a) ← (byte) main::a
|
||||
(byte) main::a ← ++ (byte) main::a
|
||||
(bool~) main::$0 ← (byte) main::a < (byte/signed byte/word/signed word/dword/signed dword) 14
|
||||
unroll if((bool~) main::$0) goto main::@1
|
||||
to:main::@2
|
||||
main::@2: scope:[main] from main::@1
|
||||
*((byte*) main::SCREEN + (byte) main::a) ← (byte) main::a
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@2
|
||||
return
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
|
||||
PROCEDURE MODIFY VARIABLE ANALYSIS
|
||||
|
||||
Completing Phi functions...
|
||||
|
||||
CONTROL FLOW GRAPH SSA WITH ASSIGNMENT CALL & RETURN
|
||||
@begin: scope:[] from
|
||||
to:@1
|
||||
main: scope:[main] from @1
|
||||
(byte*) main::SCREEN#0 ← ((byte*)) (word/signed word/dword/signed dword) 1024
|
||||
(byte) main::a#0 ← (byte/signed byte/word/signed word/dword/signed dword) 3
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@1
|
||||
(byte*) main::SCREEN#1 ← phi( main/(byte*) main::SCREEN#0 main::@1/(byte*) main::SCREEN#1 )
|
||||
(byte) main::a#2 ← phi( main/(byte) main::a#0 main::@1/(byte) main::a#1 )
|
||||
*((byte*) main::SCREEN#1 + (byte) main::a#2) ← (byte) main::a#2
|
||||
(byte) main::a#1 ← ++ (byte) main::a#2
|
||||
(bool~) main::$0 ← (byte) main::a#1 < (byte/signed byte/word/signed word/dword/signed dword) 14
|
||||
unroll if((bool~) main::$0) goto main::@1
|
||||
to:main::@2
|
||||
main::@2: scope:[main] from main::@1
|
||||
(byte*) main::SCREEN#2 ← phi( main::@1/(byte*) main::SCREEN#1 )
|
||||
(byte) main::a#3 ← phi( main::@1/(byte) main::a#1 )
|
||||
*((byte*) main::SCREEN#2 + (byte) main::a#3) ← (byte) main::a#3
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@2
|
||||
return
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
call main
|
||||
to:@2
|
||||
@2: scope:[] from @1
|
||||
to:@end
|
||||
@end: scope:[] from @2
|
||||
|
||||
SYMBOL TABLE SSA
|
||||
(label) @1
|
||||
(label) @2
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(void()) main()
|
||||
(bool~) main::$0
|
||||
(label) main::@1
|
||||
(label) main::@2
|
||||
(label) main::@return
|
||||
(byte*) main::SCREEN
|
||||
(byte*) main::SCREEN#0
|
||||
(byte*) main::SCREEN#1
|
||||
(byte*) main::SCREEN#2
|
||||
(byte) main::a
|
||||
(byte) main::a#0
|
||||
(byte) main::a#1
|
||||
(byte) main::a#2
|
||||
(byte) main::a#3
|
||||
|
||||
OPTIMIZING CONTROL FLOW GRAPH
|
||||
Culled Empty Block (label) @2
|
||||
Succesful SSA optimization Pass2CullEmptyBlocks
|
||||
Alias (byte) main::a#1 = (byte) main::a#3
|
||||
Alias (byte*) main::SCREEN#1 = (byte*) main::SCREEN#2
|
||||
Succesful SSA optimization Pass2AliasElimination
|
||||
Self Phi Eliminated (byte*) main::SCREEN#1
|
||||
Succesful SSA optimization Pass2SelfPhiElimination
|
||||
Redundant Phi (byte*) main::SCREEN#1 (byte*) main::SCREEN#0
|
||||
Succesful SSA optimization Pass2RedundantPhiElimination
|
||||
Simple Condition (bool~) main::$0 unroll if((byte) main::a#1<(byte/signed byte/word/signed word/dword/signed dword) 14) goto main::@1
|
||||
Succesful SSA optimization Pass2ConditionalJumpSimplification
|
||||
Constant (const byte*) main::SCREEN#0 = ((byte*))1024
|
||||
Constant (const byte) main::a#0 = 3
|
||||
Succesful SSA optimization Pass2ConstantIdentification
|
||||
Creating PHI for main::a#1 in block main::@2 - (byte) main::a#4 ← phi( main::@1/(byte) main::a#1 )
|
||||
Unrolling loop Loop head: main::@1 tails: main::@1 blocks: main::@1
|
||||
Successful SSA optimization Pass2LoopUnroll
|
||||
OPTIMIZING CONTROL FLOW GRAPH
|
||||
Redundant Phi (byte) main::a#2 (const byte) main::a#0
|
||||
Succesful SSA optimization Pass2RedundantPhiElimination
|
||||
Constant (const byte) main::a#1 = ++main::a#0
|
||||
Succesful SSA optimization Pass2ConstantIdentification
|
||||
Consolidated array index constant in *(main::SCREEN#0+main::a#0)
|
||||
Succesful SSA optimization Pass2ConstantAdditionElimination
|
||||
Removing PHI-reference to removed block (main::@1) in block main::@2
|
||||
if() condition always true - replacing block destination [3] if((const byte) main::a#1<(byte/signed byte/word/signed word/dword/signed dword) 14) goto main::@1_1
|
||||
Succesful SSA optimization Pass2ConstantIfs
|
||||
Alias (byte) main::a#4 = (byte) main::a#6
|
||||
Succesful SSA optimization Pass2AliasElimination
|
||||
Block Sequence Planned @begin @1 @end main main::@1 main::@1_1 main::@2 main::@return
|
||||
Creating PHI for main::a#4 in block main::@2 - (byte) main::a#7 ← phi( main::@1_1/(byte) main::a#4 )
|
||||
Unrolling loop Loop head: main::@1_1 tails: main::@1_1 blocks: main::@1_1
|
||||
Successful SSA optimization Pass2LoopUnroll
|
||||
OPTIMIZING CONTROL FLOW GRAPH
|
||||
Redundant Phi (byte) main::a#5 (const byte) main::a#1
|
||||
Succesful SSA optimization Pass2RedundantPhiElimination
|
||||
Constant (const byte) main::a#4 = ++main::a#1
|
||||
Succesful SSA optimization Pass2ConstantIdentification
|
||||
Consolidated array index constant in *(main::SCREEN#0+main::a#1)
|
||||
Succesful SSA optimization Pass2ConstantAdditionElimination
|
||||
Removing PHI-reference to removed block (main::@1_1) in block main::@2
|
||||
if() condition always true - replacing block destination [5] if((const byte) main::a#4<(byte/signed byte/word/signed word/dword/signed dword) 14) goto main::@1_2
|
||||
Succesful SSA optimization Pass2ConstantIfs
|
||||
Alias (byte) main::a#7 = (byte) main::a#9
|
||||
Succesful SSA optimization Pass2AliasElimination
|
||||
Block Sequence Planned @begin @1 @end main main::@1 main::@1_1 main::@1_2 main::@2 main::@return
|
||||
Creating PHI for main::a#7 in block main::@2 - (byte) main::a#10 ← phi( main::@1_2/(byte) main::a#7 )
|
||||
Unrolling loop Loop head: main::@1_2 tails: main::@1_2 blocks: main::@1_2
|
||||
Successful SSA optimization Pass2LoopUnroll
|
||||
OPTIMIZING CONTROL FLOW GRAPH
|
||||
Redundant Phi (byte) main::a#8 (const byte) main::a#4
|
||||
Succesful SSA optimization Pass2RedundantPhiElimination
|
||||
Constant (const byte) main::a#7 = ++main::a#4
|
||||
Succesful SSA optimization Pass2ConstantIdentification
|
||||
Consolidated array index constant in *(main::SCREEN#0+main::a#4)
|
||||
Succesful SSA optimization Pass2ConstantAdditionElimination
|
||||
Removing PHI-reference to removed block (main::@1_2) in block main::@2
|
||||
if() condition always true - replacing block destination [6] if((const byte) main::a#7<(byte/signed byte/word/signed word/dword/signed dword) 14) goto main::@1_3
|
||||
Succesful SSA optimization Pass2ConstantIfs
|
||||
Alias (byte) main::a#10 = (byte) main::a#12
|
||||
Succesful SSA optimization Pass2AliasElimination
|
||||
Block Sequence Planned @begin @1 @end main main::@1 main::@1_1 main::@1_2 main::@1_3 main::@2 main::@return
|
||||
Creating PHI for main::a#10 in block main::@2 - (byte) main::a#13 ← phi( main::@1_3/(byte) main::a#10 )
|
||||
Unrolling loop Loop head: main::@1_3 tails: main::@1_3 blocks: main::@1_3
|
||||
Successful SSA optimization Pass2LoopUnroll
|
||||
OPTIMIZING CONTROL FLOW GRAPH
|
||||
Redundant Phi (byte) main::a#11 (const byte) main::a#7
|
||||
Succesful SSA optimization Pass2RedundantPhiElimination
|
||||
Constant (const byte) main::a#10 = ++main::a#7
|
||||
Succesful SSA optimization Pass2ConstantIdentification
|
||||
Consolidated array index constant in *(main::SCREEN#0+main::a#7)
|
||||
Succesful SSA optimization Pass2ConstantAdditionElimination
|
||||
Removing PHI-reference to removed block (main::@1_3) in block main::@2
|
||||
if() condition always true - replacing block destination [7] if((const byte) main::a#10<(byte/signed byte/word/signed word/dword/signed dword) 14) goto main::@1_4
|
||||
Succesful SSA optimization Pass2ConstantIfs
|
||||
Alias (byte) main::a#13 = (byte) main::a#15
|
||||
Succesful SSA optimization Pass2AliasElimination
|
||||
Block Sequence Planned @begin @1 @end main main::@1 main::@1_1 main::@1_2 main::@1_3 main::@1_4 main::@2 main::@return
|
||||
Creating PHI for main::a#13 in block main::@2 - (byte) main::a#16 ← phi( main::@1_4/(byte) main::a#13 )
|
||||
Unrolling loop Loop head: main::@1_4 tails: main::@1_4 blocks: main::@1_4
|
||||
Successful SSA optimization Pass2LoopUnroll
|
||||
OPTIMIZING CONTROL FLOW GRAPH
|
||||
Redundant Phi (byte) main::a#14 (const byte) main::a#10
|
||||
Succesful SSA optimization Pass2RedundantPhiElimination
|
||||
Constant (const byte) main::a#13 = ++main::a#10
|
||||
Succesful SSA optimization Pass2ConstantIdentification
|
||||
Consolidated array index constant in *(main::SCREEN#0+main::a#10)
|
||||
Succesful SSA optimization Pass2ConstantAdditionElimination
|
||||
Removing PHI-reference to removed block (main::@1_4) in block main::@2
|
||||
if() condition always true - replacing block destination [8] if((const byte) main::a#13<(byte/signed byte/word/signed word/dword/signed dword) 14) goto main::@1_5
|
||||
Succesful SSA optimization Pass2ConstantIfs
|
||||
Alias (byte) main::a#16 = (byte) main::a#18
|
||||
Succesful SSA optimization Pass2AliasElimination
|
||||
Block Sequence Planned @begin @1 @end main main::@1 main::@1_1 main::@1_2 main::@1_3 main::@1_4 main::@1_5 main::@2 main::@return
|
||||
Creating PHI for main::a#16 in block main::@2 - (byte) main::a#19 ← phi( main::@1_5/(byte) main::a#16 )
|
||||
Unrolling loop Loop head: main::@1_5 tails: main::@1_5 blocks: main::@1_5
|
||||
Successful SSA optimization Pass2LoopUnroll
|
||||
OPTIMIZING CONTROL FLOW GRAPH
|
||||
Redundant Phi (byte) main::a#17 (const byte) main::a#13
|
||||
Succesful SSA optimization Pass2RedundantPhiElimination
|
||||
Constant (const byte) main::a#16 = ++main::a#13
|
||||
Succesful SSA optimization Pass2ConstantIdentification
|
||||
Consolidated array index constant in *(main::SCREEN#0+main::a#13)
|
||||
Succesful SSA optimization Pass2ConstantAdditionElimination
|
||||
Removing PHI-reference to removed block (main::@1_5) in block main::@2
|
||||
if() condition always true - replacing block destination [9] if((const byte) main::a#16<(byte/signed byte/word/signed word/dword/signed dword) 14) goto main::@1_6
|
||||
Succesful SSA optimization Pass2ConstantIfs
|
||||
Alias (byte) main::a#19 = (byte) main::a#21
|
||||
Succesful SSA optimization Pass2AliasElimination
|
||||
Block Sequence Planned @begin @1 @end main main::@1 main::@1_1 main::@1_2 main::@1_3 main::@1_4 main::@1_5 main::@1_6 main::@2 main::@return
|
||||
Creating PHI for main::a#19 in block main::@2 - (byte) main::a#22 ← phi( main::@1_6/(byte) main::a#19 )
|
||||
Unrolling loop Loop head: main::@1_6 tails: main::@1_6 blocks: main::@1_6
|
||||
Successful SSA optimization Pass2LoopUnroll
|
||||
OPTIMIZING CONTROL FLOW GRAPH
|
||||
Redundant Phi (byte) main::a#20 (const byte) main::a#16
|
||||
Succesful SSA optimization Pass2RedundantPhiElimination
|
||||
Constant (const byte) main::a#19 = ++main::a#16
|
||||
Succesful SSA optimization Pass2ConstantIdentification
|
||||
Consolidated array index constant in *(main::SCREEN#0+main::a#16)
|
||||
Succesful SSA optimization Pass2ConstantAdditionElimination
|
||||
Removing PHI-reference to removed block (main::@1_6) in block main::@2
|
||||
if() condition always true - replacing block destination [10] if((const byte) main::a#19<(byte/signed byte/word/signed word/dword/signed dword) 14) goto main::@1_7
|
||||
Succesful SSA optimization Pass2ConstantIfs
|
||||
Alias (byte) main::a#22 = (byte) main::a#24
|
||||
Succesful SSA optimization Pass2AliasElimination
|
||||
Block Sequence Planned @begin @1 @end main main::@1 main::@1_1 main::@1_2 main::@1_3 main::@1_4 main::@1_5 main::@1_6 main::@1_7 main::@2 main::@return
|
||||
Creating PHI for main::a#22 in block main::@2 - (byte) main::a#25 ← phi( main::@1_7/(byte) main::a#22 )
|
||||
Unrolling loop Loop head: main::@1_7 tails: main::@1_7 blocks: main::@1_7
|
||||
Successful SSA optimization Pass2LoopUnroll
|
||||
OPTIMIZING CONTROL FLOW GRAPH
|
||||
Redundant Phi (byte) main::a#23 (const byte) main::a#19
|
||||
Succesful SSA optimization Pass2RedundantPhiElimination
|
||||
Constant (const byte) main::a#22 = ++main::a#19
|
||||
Succesful SSA optimization Pass2ConstantIdentification
|
||||
Consolidated array index constant in *(main::SCREEN#0+main::a#19)
|
||||
Succesful SSA optimization Pass2ConstantAdditionElimination
|
||||
Removing PHI-reference to removed block (main::@1_7) in block main::@2
|
||||
if() condition always true - replacing block destination [11] if((const byte) main::a#22<(byte/signed byte/word/signed word/dword/signed dword) 14) goto main::@1_8
|
||||
Succesful SSA optimization Pass2ConstantIfs
|
||||
Alias (byte) main::a#25 = (byte) main::a#27
|
||||
Succesful SSA optimization Pass2AliasElimination
|
||||
Block Sequence Planned @begin @1 @end main main::@1 main::@1_1 main::@1_2 main::@1_3 main::@1_4 main::@1_5 main::@1_6 main::@1_7 main::@1_8 main::@2 main::@return
|
||||
Creating PHI for main::a#25 in block main::@2 - (byte) main::a#28 ← phi( main::@1_8/(byte) main::a#25 )
|
||||
Unrolling loop Loop head: main::@1_8 tails: main::@1_8 blocks: main::@1_8
|
||||
Successful SSA optimization Pass2LoopUnroll
|
||||
OPTIMIZING CONTROL FLOW GRAPH
|
||||
Redundant Phi (byte) main::a#26 (const byte) main::a#22
|
||||
Succesful SSA optimization Pass2RedundantPhiElimination
|
||||
Constant (const byte) main::a#25 = ++main::a#22
|
||||
Succesful SSA optimization Pass2ConstantIdentification
|
||||
Consolidated array index constant in *(main::SCREEN#0+main::a#22)
|
||||
Succesful SSA optimization Pass2ConstantAdditionElimination
|
||||
Removing PHI-reference to removed block (main::@1_8) in block main::@2
|
||||
if() condition always true - replacing block destination [12] if((const byte) main::a#25<(byte/signed byte/word/signed word/dword/signed dword) 14) goto main::@1_9
|
||||
Succesful SSA optimization Pass2ConstantIfs
|
||||
Alias (byte) main::a#28 = (byte) main::a#30
|
||||
Succesful SSA optimization Pass2AliasElimination
|
||||
Block Sequence Planned @begin @1 @end main main::@1 main::@1_1 main::@1_2 main::@1_3 main::@1_4 main::@1_5 main::@1_6 main::@1_7 main::@1_8 main::@1_9 main::@2 main::@return
|
||||
Creating PHI for main::a#28 in block main::@2 - (byte) main::a#31 ← phi( main::@1_9/(byte) main::a#28 )
|
||||
Unrolling loop Loop head: main::@1_9 tails: main::@1_9 blocks: main::@1_9
|
||||
Successful SSA optimization Pass2LoopUnroll
|
||||
OPTIMIZING CONTROL FLOW GRAPH
|
||||
Redundant Phi (byte) main::a#29 (const byte) main::a#25
|
||||
Succesful SSA optimization Pass2RedundantPhiElimination
|
||||
Constant (const byte) main::a#28 = ++main::a#25
|
||||
Succesful SSA optimization Pass2ConstantIdentification
|
||||
Consolidated array index constant in *(main::SCREEN#0+main::a#25)
|
||||
Succesful SSA optimization Pass2ConstantAdditionElimination
|
||||
Removing PHI-reference to removed block (main::@1_9) in block main::@2
|
||||
if() condition always true - replacing block destination [13] if((const byte) main::a#28<(byte/signed byte/word/signed word/dword/signed dword) 14) goto main::@1_10
|
||||
Succesful SSA optimization Pass2ConstantIfs
|
||||
Alias (byte) main::a#31 = (byte) main::a#33
|
||||
Succesful SSA optimization Pass2AliasElimination
|
||||
Block Sequence Planned @begin @1 @end main main::@1 main::@1_1 main::@1_2 main::@1_3 main::@1_4 main::@1_5 main::@1_6 main::@1_7 main::@1_8 main::@1_9 main::@1_10 main::@2 main::@return
|
||||
Creating PHI for main::a#31 in block main::@2 - (byte) main::a#34 ← phi( main::@1_10/(byte) main::a#31 )
|
||||
Unrolling loop Loop head: main::@1_10 tails: main::@1_10 blocks: main::@1_10
|
||||
Successful SSA optimization Pass2LoopUnroll
|
||||
OPTIMIZING CONTROL FLOW GRAPH
|
||||
Redundant Phi (byte) main::a#32 (const byte) main::a#28
|
||||
Succesful SSA optimization Pass2RedundantPhiElimination
|
||||
Constant (const byte) main::a#31 = ++main::a#28
|
||||
Succesful SSA optimization Pass2ConstantIdentification
|
||||
Consolidated array index constant in *(main::SCREEN#0+main::a#28)
|
||||
Succesful SSA optimization Pass2ConstantAdditionElimination
|
||||
Removing PHI-reference to removed block (main::@1_10) in block main::@1_11
|
||||
if() condition always false - eliminating [14] if((const byte) main::a#31<(byte/signed byte/word/signed word/dword/signed dword) 14) goto main::@1_11
|
||||
Succesful SSA optimization Pass2ConstantIfs
|
||||
Eliminating variable (byte) main::a#35 from unused block main::@1_11
|
||||
Eliminating variable (byte) main::a#36 and from unused block main::@1_11
|
||||
Removing PHI-reference to removed block (main::@1_11) in block main::@2
|
||||
Removing unused block main::@1_11
|
||||
Succesful SSA optimization Pass2EliminateUnusedBlocks
|
||||
Redundant Phi (byte) main::a#34 (const byte) main::a#31
|
||||
Succesful SSA optimization Pass2RedundantPhiElimination
|
||||
Consolidated array index constant in *(main::SCREEN#0+main::a#31)
|
||||
Succesful SSA optimization Pass2ConstantAdditionElimination
|
||||
Block Sequence Planned @begin @1 @end main main::@1 main::@1_1 main::@1_2 main::@1_3 main::@1_4 main::@1_5 main::@1_6 main::@1_7 main::@1_8 main::@1_9 main::@1_10 main::@2 main::@return
|
||||
OPTIMIZING CONTROL FLOW GRAPH
|
||||
Inlining constant with different constant siblings (const byte) main::a#0
|
||||
Inlining constant with different constant siblings (const byte) main::a#0
|
||||
Inlining constant with different constant siblings (const byte) main::a#0
|
||||
Inlining constant with different constant siblings (const byte) main::a#0
|
||||
Inlining constant with different constant siblings (const byte) main::a#0
|
||||
Inlining constant with different constant siblings (const byte) main::a#0
|
||||
Inlining constant with different constant siblings (const byte) main::a#0
|
||||
Inlining constant with different constant siblings (const byte) main::a#0
|
||||
Inlining constant with different constant siblings (const byte) main::a#0
|
||||
Inlining constant with different constant siblings (const byte) main::a#0
|
||||
Inlining constant with different constant siblings (const byte) main::a#0
|
||||
Inlining constant with different constant siblings (const byte) main::a#1
|
||||
Inlining constant with different constant siblings (const byte) main::a#1
|
||||
Inlining constant with different constant siblings (const byte) main::a#1
|
||||
Inlining constant with different constant siblings (const byte) main::a#1
|
||||
Inlining constant with different constant siblings (const byte) main::a#1
|
||||
Inlining constant with different constant siblings (const byte) main::a#1
|
||||
Inlining constant with different constant siblings (const byte) main::a#1
|
||||
Inlining constant with different constant siblings (const byte) main::a#1
|
||||
Inlining constant with different constant siblings (const byte) main::a#1
|
||||
Inlining constant with different constant siblings (const byte) main::a#1
|
||||
Inlining constant with different constant siblings (const byte) main::a#1
|
||||
Inlining constant with different constant siblings (const byte) main::a#4
|
||||
Inlining constant with different constant siblings (const byte) main::a#4
|
||||
Inlining constant with different constant siblings (const byte) main::a#4
|
||||
Inlining constant with different constant siblings (const byte) main::a#4
|
||||
Inlining constant with different constant siblings (const byte) main::a#4
|
||||
Inlining constant with different constant siblings (const byte) main::a#4
|
||||
Inlining constant with different constant siblings (const byte) main::a#4
|
||||
Inlining constant with different constant siblings (const byte) main::a#4
|
||||
Inlining constant with different constant siblings (const byte) main::a#4
|
||||
Inlining constant with different constant siblings (const byte) main::a#4
|
||||
Inlining constant with different constant siblings (const byte) main::a#4
|
||||
Inlining constant with different constant siblings (const byte) main::a#7
|
||||
Inlining constant with different constant siblings (const byte) main::a#7
|
||||
Inlining constant with different constant siblings (const byte) main::a#7
|
||||
Inlining constant with different constant siblings (const byte) main::a#7
|
||||
Inlining constant with different constant siblings (const byte) main::a#7
|
||||
Inlining constant with different constant siblings (const byte) main::a#7
|
||||
Inlining constant with different constant siblings (const byte) main::a#7
|
||||
Inlining constant with different constant siblings (const byte) main::a#7
|
||||
Inlining constant with different constant siblings (const byte) main::a#7
|
||||
Inlining constant with different constant siblings (const byte) main::a#7
|
||||
Inlining constant with different constant siblings (const byte) main::a#7
|
||||
Inlining constant with different constant siblings (const byte) main::a#10
|
||||
Inlining constant with different constant siblings (const byte) main::a#10
|
||||
Inlining constant with different constant siblings (const byte) main::a#10
|
||||
Inlining constant with different constant siblings (const byte) main::a#10
|
||||
Inlining constant with different constant siblings (const byte) main::a#10
|
||||
Inlining constant with different constant siblings (const byte) main::a#10
|
||||
Inlining constant with different constant siblings (const byte) main::a#10
|
||||
Inlining constant with different constant siblings (const byte) main::a#10
|
||||
Inlining constant with different constant siblings (const byte) main::a#10
|
||||
Inlining constant with different constant siblings (const byte) main::a#10
|
||||
Inlining constant with different constant siblings (const byte) main::a#10
|
||||
Inlining constant with different constant siblings (const byte) main::a#13
|
||||
Inlining constant with different constant siblings (const byte) main::a#13
|
||||
Inlining constant with different constant siblings (const byte) main::a#13
|
||||
Inlining constant with different constant siblings (const byte) main::a#13
|
||||
Inlining constant with different constant siblings (const byte) main::a#13
|
||||
Inlining constant with different constant siblings (const byte) main::a#13
|
||||
Inlining constant with different constant siblings (const byte) main::a#13
|
||||
Inlining constant with different constant siblings (const byte) main::a#13
|
||||
Inlining constant with different constant siblings (const byte) main::a#13
|
||||
Inlining constant with different constant siblings (const byte) main::a#13
|
||||
Inlining constant with different constant siblings (const byte) main::a#13
|
||||
Inlining constant with different constant siblings (const byte) main::a#16
|
||||
Inlining constant with different constant siblings (const byte) main::a#16
|
||||
Inlining constant with different constant siblings (const byte) main::a#16
|
||||
Inlining constant with different constant siblings (const byte) main::a#16
|
||||
Inlining constant with different constant siblings (const byte) main::a#16
|
||||
Inlining constant with different constant siblings (const byte) main::a#16
|
||||
Inlining constant with different constant siblings (const byte) main::a#16
|
||||
Inlining constant with different constant siblings (const byte) main::a#16
|
||||
Inlining constant with different constant siblings (const byte) main::a#16
|
||||
Inlining constant with different constant siblings (const byte) main::a#16
|
||||
Inlining constant with different constant siblings (const byte) main::a#16
|
||||
Inlining constant with different constant siblings (const byte) main::a#19
|
||||
Inlining constant with different constant siblings (const byte) main::a#19
|
||||
Inlining constant with different constant siblings (const byte) main::a#19
|
||||
Inlining constant with different constant siblings (const byte) main::a#19
|
||||
Inlining constant with different constant siblings (const byte) main::a#19
|
||||
Inlining constant with different constant siblings (const byte) main::a#19
|
||||
Inlining constant with different constant siblings (const byte) main::a#19
|
||||
Inlining constant with different constant siblings (const byte) main::a#19
|
||||
Inlining constant with different constant siblings (const byte) main::a#19
|
||||
Inlining constant with different constant siblings (const byte) main::a#19
|
||||
Inlining constant with different constant siblings (const byte) main::a#19
|
||||
Inlining constant with different constant siblings (const byte) main::a#22
|
||||
Inlining constant with different constant siblings (const byte) main::a#22
|
||||
Inlining constant with different constant siblings (const byte) main::a#22
|
||||
Inlining constant with different constant siblings (const byte) main::a#22
|
||||
Inlining constant with different constant siblings (const byte) main::a#22
|
||||
Inlining constant with different constant siblings (const byte) main::a#22
|
||||
Inlining constant with different constant siblings (const byte) main::a#22
|
||||
Inlining constant with different constant siblings (const byte) main::a#22
|
||||
Inlining constant with different constant siblings (const byte) main::a#22
|
||||
Inlining constant with different constant siblings (const byte) main::a#22
|
||||
Inlining constant with different constant siblings (const byte) main::a#22
|
||||
Inlining constant with different constant siblings (const byte) main::a#25
|
||||
Inlining constant with different constant siblings (const byte) main::a#25
|
||||
Inlining constant with different constant siblings (const byte) main::a#25
|
||||
Inlining constant with different constant siblings (const byte) main::a#25
|
||||
Inlining constant with different constant siblings (const byte) main::a#25
|
||||
Inlining constant with different constant siblings (const byte) main::a#25
|
||||
Inlining constant with different constant siblings (const byte) main::a#25
|
||||
Inlining constant with different constant siblings (const byte) main::a#25
|
||||
Inlining constant with different constant siblings (const byte) main::a#25
|
||||
Inlining constant with different constant siblings (const byte) main::a#25
|
||||
Inlining constant with different constant siblings (const byte) main::a#25
|
||||
Inlining constant with different constant siblings (const byte) main::a#28
|
||||
Inlining constant with different constant siblings (const byte) main::a#28
|
||||
Inlining constant with different constant siblings (const byte) main::a#28
|
||||
Inlining constant with different constant siblings (const byte) main::a#28
|
||||
Inlining constant with different constant siblings (const byte) main::a#28
|
||||
Inlining constant with different constant siblings (const byte) main::a#28
|
||||
Inlining constant with different constant siblings (const byte) main::a#28
|
||||
Inlining constant with different constant siblings (const byte) main::a#28
|
||||
Inlining constant with different constant siblings (const byte) main::a#28
|
||||
Inlining constant with different constant siblings (const byte) main::a#28
|
||||
Inlining constant with different constant siblings (const byte) main::a#28
|
||||
Inlining constant with different constant siblings (const byte) main::a#31
|
||||
Inlining constant with different constant siblings (const byte) main::a#31
|
||||
Inlining constant with different constant siblings (const byte) main::a#31
|
||||
Inlining constant with different constant siblings (const byte) main::a#31
|
||||
Inlining constant with different constant siblings (const byte) main::a#31
|
||||
Inlining constant with different constant siblings (const byte) main::a#31
|
||||
Inlining constant with different constant siblings (const byte) main::a#31
|
||||
Inlining constant with different constant siblings (const byte) main::a#31
|
||||
Inlining constant with different constant siblings (const byte) main::a#31
|
||||
Inlining constant with different constant siblings (const byte) main::a#31
|
||||
Inlining constant with different constant siblings (const byte) main::a#31
|
||||
Constant inlined main::a#22 = ++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3
|
||||
Constant inlined main::a#10 = ++++++++(byte/signed byte/word/signed word/dword/signed dword) 3
|
||||
Constant inlined main::a#31 = ++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3
|
||||
Constant inlined main::a#25 = ++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3
|
||||
Constant inlined main::a#13 = ++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3
|
||||
Constant inlined main::a#0 = (byte/signed byte/word/signed word/dword/signed dword) 3
|
||||
Constant inlined main::a#19 = ++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3
|
||||
Constant inlined main::a#28 = ++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3
|
||||
Constant inlined main::a#1 = ++(byte/signed byte/word/signed word/dword/signed dword) 3
|
||||
Constant inlined main::a#16 = ++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3
|
||||
Constant inlined main::a#7 = ++++++(byte/signed byte/word/signed word/dword/signed dword) 3
|
||||
Constant inlined main::a#4 = ++++(byte/signed byte/word/signed word/dword/signed dword) 3
|
||||
Succesful SSA optimization Pass2ConstantInlining
|
||||
Block Sequence Planned @begin @1 @end main main::@1 main::@1_1 main::@1_2 main::@1_3 main::@1_4 main::@1_5 main::@1_6 main::@1_7 main::@1_8 main::@1_9 main::@1_10 main::@2 main::@return
|
||||
Block Sequence Planned @begin @1 @end main main::@1 main::@1_1 main::@1_2 main::@1_3 main::@1_4 main::@1_5 main::@1_6 main::@1_7 main::@1_8 main::@1_9 main::@1_10 main::@2 main::@return
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @1
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of main
|
||||
CALL GRAPH
|
||||
Calls in [] to main:2
|
||||
|
||||
Propagating live ranges...
|
||||
Created 0 initial phi equivalence classes
|
||||
Coalesced down to 0 phi equivalence classes
|
||||
Block Sequence Planned @begin @1 @end main main::@1 main::@1_1 main::@1_2 main::@1_3 main::@1_4 main::@1_5 main::@1_6 main::@1_7 main::@1_8 main::@1_9 main::@1_10 main::@2 main::@return
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @1
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of main
|
||||
Propagating live ranges...
|
||||
|
||||
FINAL CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
[0] phi() [ ] ( )
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi() [ ] ( )
|
||||
[2] call main [ ] ( )
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi() [ ] ( )
|
||||
main: scope:[main] from @1
|
||||
[4] phi() [ ] ( main:2 [ ] )
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main
|
||||
[5] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 3) ← (byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] )
|
||||
to:main::@1_1
|
||||
main::@1_1: scope:[main] from main::@1
|
||||
[6] *((const byte*) main::SCREEN#0+++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] )
|
||||
to:main::@1_2
|
||||
main::@1_2: scope:[main] from main::@1_1
|
||||
[7] *((const byte*) main::SCREEN#0+++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] )
|
||||
to:main::@1_3
|
||||
main::@1_3: scope:[main] from main::@1_2
|
||||
[8] *((const byte*) main::SCREEN#0+++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] )
|
||||
to:main::@1_4
|
||||
main::@1_4: scope:[main] from main::@1_3
|
||||
[9] *((const byte*) main::SCREEN#0+++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] )
|
||||
to:main::@1_5
|
||||
main::@1_5: scope:[main] from main::@1_4
|
||||
[10] *((const byte*) main::SCREEN#0+++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] )
|
||||
to:main::@1_6
|
||||
main::@1_6: scope:[main] from main::@1_5
|
||||
[11] *((const byte*) main::SCREEN#0+++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] )
|
||||
to:main::@1_7
|
||||
main::@1_7: scope:[main] from main::@1_6
|
||||
[12] *((const byte*) main::SCREEN#0+++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] )
|
||||
to:main::@1_8
|
||||
main::@1_8: scope:[main] from main::@1_7
|
||||
[13] *((const byte*) main::SCREEN#0+++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] )
|
||||
to:main::@1_9
|
||||
main::@1_9: scope:[main] from main::@1_8
|
||||
[14] *((const byte*) main::SCREEN#0+++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] )
|
||||
to:main::@1_10
|
||||
main::@1_10: scope:[main] from main::@1_9
|
||||
[15] *((const byte*) main::SCREEN#0+++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] )
|
||||
to:main::@2
|
||||
main::@2: scope:[main] from main::@1_10
|
||||
[16] *((const byte*) main::SCREEN#0+++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] )
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@2
|
||||
[17] return [ ] ( main:2 [ ] )
|
||||
to:@return
|
||||
|
||||
DOMINATORS
|
||||
@begin dominated by @begin
|
||||
@1 dominated by @begin @1
|
||||
@end dominated by @begin @end @1
|
||||
main dominated by @begin main @1
|
||||
main::@1 dominated by @begin main @1 main::@1
|
||||
main::@1_1 dominated by @begin main @1 main::@1 main::@1_1
|
||||
main::@1_2 dominated by @begin main @1 main::@1 main::@1_1 main::@1_2
|
||||
main::@1_3 dominated by @begin main @1 main::@1 main::@1_1 main::@1_2 main::@1_3
|
||||
main::@1_4 dominated by @begin main @1 main::@1 main::@1_1 main::@1_2 main::@1_3 main::@1_4
|
||||
main::@1_5 dominated by @begin main::@1_5 main @1 main::@1 main::@1_1 main::@1_2 main::@1_3 main::@1_4
|
||||
main::@1_6 dominated by @begin main::@1_5 main::@1_6 main @1 main::@1 main::@1_1 main::@1_2 main::@1_3 main::@1_4
|
||||
main::@1_7 dominated by @begin main::@1_5 main::@1_6 main::@1_7 main @1 main::@1 main::@1_1 main::@1_2 main::@1_3 main::@1_4
|
||||
main::@1_8 dominated by @begin main::@1_5 main::@1_6 main::@1_7 main::@1_8 main @1 main::@1 main::@1_1 main::@1_2 main::@1_3 main::@1_4
|
||||
main::@1_9 dominated by main::@1_9 @begin main::@1_5 main::@1_6 main::@1_7 main::@1_8 main @1 main::@1 main::@1_1 main::@1_2 main::@1_3 main::@1_4
|
||||
main::@1_10 dominated by main::@1_9 @begin main::@1_5 main::@1_6 main::@1_7 main::@1_8 main @1 main::@1_10 main::@1 main::@1_1 main::@1_2 main::@1_3 main::@1_4
|
||||
main::@2 dominated by main::@1_9 @begin main::@1_5 main::@1_6 main::@1_7 main::@1_8 main @1 main::@1_10 main::@1 main::@1_1 main::@1_2 main::@2 main::@1_3 main::@1_4
|
||||
main::@return dominated by main::@1_9 main::@return @begin main::@1_5 main::@1_6 main::@1_7 main::@1_8 main @1 main::@1_10 main::@1 main::@1_1 main::@1_2 main::@2 main::@1_3 main::@1_4
|
||||
|
||||
NATURAL LOOPS
|
||||
|
||||
NATURAL LOOPS WITH DEPTH
|
||||
Found 0 loops in scope []
|
||||
Found 0 loops in scope [main]
|
||||
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
(void()) main()
|
||||
(byte*) main::SCREEN
|
||||
(byte) main::a
|
||||
|
||||
Initial phi equivalence classes
|
||||
Complete equivalence classes
|
||||
|
||||
INITIAL ASM
|
||||
//SEG0 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
//SEG1 Global Constants & labels
|
||||
//SEG2 @begin
|
||||
bbegin:
|
||||
//SEG3 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
b1_from_bbegin:
|
||||
jmp b1
|
||||
//SEG4 @1
|
||||
b1:
|
||||
//SEG5 [2] call main [ ] ( )
|
||||
//SEG6 [4] phi from @1 to main [phi:@1->main]
|
||||
main_from_b1:
|
||||
jsr main
|
||||
//SEG7 [3] phi from @1 to @end [phi:@1->@end]
|
||||
bend_from_b1:
|
||||
jmp bend
|
||||
//SEG8 @end
|
||||
bend:
|
||||
//SEG9 main
|
||||
main: {
|
||||
.label SCREEN = $400
|
||||
jmp b1
|
||||
//SEG10 main::@1
|
||||
b1:
|
||||
//SEG11 [5] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 3) ← (byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3
|
||||
sta SCREEN+3
|
||||
jmp b1_1
|
||||
//SEG12 main::@1_1
|
||||
b1_1:
|
||||
//SEG13 [6] *((const byte*) main::SCREEN#0+++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1
|
||||
sta SCREEN+3+1
|
||||
jmp b1_2
|
||||
//SEG14 main::@1_2
|
||||
b1_2:
|
||||
//SEG15 [7] *((const byte*) main::SCREEN#0+++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1+1
|
||||
sta SCREEN+3+1+1
|
||||
jmp b1_3
|
||||
//SEG16 main::@1_3
|
||||
b1_3:
|
||||
//SEG17 [8] *((const byte*) main::SCREEN#0+++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1+1+1
|
||||
sta SCREEN+3+1+1+1
|
||||
jmp b1_4
|
||||
//SEG18 main::@1_4
|
||||
b1_4:
|
||||
//SEG19 [9] *((const byte*) main::SCREEN#0+++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1+1+1+1
|
||||
sta SCREEN+3+1+1+1+1
|
||||
jmp b1_5
|
||||
//SEG20 main::@1_5
|
||||
b1_5:
|
||||
//SEG21 [10] *((const byte*) main::SCREEN#0+++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1+1+1+1+1
|
||||
sta SCREEN+3+1+1+1+1+1
|
||||
jmp b1_6
|
||||
//SEG22 main::@1_6
|
||||
b1_6:
|
||||
//SEG23 [11] *((const byte*) main::SCREEN#0+++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1+1+1+1+1+1
|
||||
sta SCREEN+3+1+1+1+1+1+1
|
||||
jmp b1_7
|
||||
//SEG24 main::@1_7
|
||||
b1_7:
|
||||
//SEG25 [12] *((const byte*) main::SCREEN#0+++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1+1+1+1+1+1+1
|
||||
sta SCREEN+3+1+1+1+1+1+1+1
|
||||
jmp b1_8
|
||||
//SEG26 main::@1_8
|
||||
b1_8:
|
||||
//SEG27 [13] *((const byte*) main::SCREEN#0+++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1+1+1+1+1+1+1+1
|
||||
sta SCREEN+3+1+1+1+1+1+1+1+1
|
||||
jmp b1_9
|
||||
//SEG28 main::@1_9
|
||||
b1_9:
|
||||
//SEG29 [14] *((const byte*) main::SCREEN#0+++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1+1+1+1+1+1+1+1+1
|
||||
sta SCREEN+3+1+1+1+1+1+1+1+1+1
|
||||
jmp b1_10
|
||||
//SEG30 main::@1_10
|
||||
b1_10:
|
||||
//SEG31 [15] *((const byte*) main::SCREEN#0+++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1+1+1+1+1+1+1+1+1+1
|
||||
sta SCREEN+3+1+1+1+1+1+1+1+1+1+1
|
||||
jmp b2
|
||||
//SEG32 main::@2
|
||||
b2:
|
||||
//SEG33 [16] *((const byte*) main::SCREEN#0+++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1+1+1+1+1+1+1+1+1+1+1
|
||||
sta SCREEN+3+1+1+1+1+1+1+1+1+1+1+1
|
||||
jmp breturn
|
||||
//SEG34 main::@return
|
||||
breturn:
|
||||
//SEG35 [17] return [ ] ( main:2 [ ] )
|
||||
rts
|
||||
}
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Statement [5] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 3) ← (byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
Statement [6] *((const byte*) main::SCREEN#0+++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
Statement [7] *((const byte*) main::SCREEN#0+++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
Statement [8] *((const byte*) main::SCREEN#0+++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
Statement [9] *((const byte*) main::SCREEN#0+++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
Statement [10] *((const byte*) main::SCREEN#0+++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
Statement [11] *((const byte*) main::SCREEN#0+++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
Statement [12] *((const byte*) main::SCREEN#0+++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
Statement [13] *((const byte*) main::SCREEN#0+++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
Statement [14] *((const byte*) main::SCREEN#0+++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
Statement [15] *((const byte*) main::SCREEN#0+++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
Statement [16] *((const byte*) main::SCREEN#0+++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [main]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [main] best 156 combination
|
||||
Uplifting [] best 156 combination
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
//SEG0 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
//SEG1 Global Constants & labels
|
||||
//SEG2 @begin
|
||||
bbegin:
|
||||
//SEG3 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
b1_from_bbegin:
|
||||
jmp b1
|
||||
//SEG4 @1
|
||||
b1:
|
||||
//SEG5 [2] call main [ ] ( )
|
||||
//SEG6 [4] phi from @1 to main [phi:@1->main]
|
||||
main_from_b1:
|
||||
jsr main
|
||||
//SEG7 [3] phi from @1 to @end [phi:@1->@end]
|
||||
bend_from_b1:
|
||||
jmp bend
|
||||
//SEG8 @end
|
||||
bend:
|
||||
//SEG9 main
|
||||
main: {
|
||||
.label SCREEN = $400
|
||||
jmp b1
|
||||
//SEG10 main::@1
|
||||
b1:
|
||||
//SEG11 [5] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 3) ← (byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3
|
||||
sta SCREEN+3
|
||||
jmp b1_1
|
||||
//SEG12 main::@1_1
|
||||
b1_1:
|
||||
//SEG13 [6] *((const byte*) main::SCREEN#0+++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1
|
||||
sta SCREEN+3+1
|
||||
jmp b1_2
|
||||
//SEG14 main::@1_2
|
||||
b1_2:
|
||||
//SEG15 [7] *((const byte*) main::SCREEN#0+++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1+1
|
||||
sta SCREEN+3+1+1
|
||||
jmp b1_3
|
||||
//SEG16 main::@1_3
|
||||
b1_3:
|
||||
//SEG17 [8] *((const byte*) main::SCREEN#0+++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1+1+1
|
||||
sta SCREEN+3+1+1+1
|
||||
jmp b1_4
|
||||
//SEG18 main::@1_4
|
||||
b1_4:
|
||||
//SEG19 [9] *((const byte*) main::SCREEN#0+++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1+1+1+1
|
||||
sta SCREEN+3+1+1+1+1
|
||||
jmp b1_5
|
||||
//SEG20 main::@1_5
|
||||
b1_5:
|
||||
//SEG21 [10] *((const byte*) main::SCREEN#0+++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1+1+1+1+1
|
||||
sta SCREEN+3+1+1+1+1+1
|
||||
jmp b1_6
|
||||
//SEG22 main::@1_6
|
||||
b1_6:
|
||||
//SEG23 [11] *((const byte*) main::SCREEN#0+++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1+1+1+1+1+1
|
||||
sta SCREEN+3+1+1+1+1+1+1
|
||||
jmp b1_7
|
||||
//SEG24 main::@1_7
|
||||
b1_7:
|
||||
//SEG25 [12] *((const byte*) main::SCREEN#0+++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1+1+1+1+1+1+1
|
||||
sta SCREEN+3+1+1+1+1+1+1+1
|
||||
jmp b1_8
|
||||
//SEG26 main::@1_8
|
||||
b1_8:
|
||||
//SEG27 [13] *((const byte*) main::SCREEN#0+++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1+1+1+1+1+1+1+1
|
||||
sta SCREEN+3+1+1+1+1+1+1+1+1
|
||||
jmp b1_9
|
||||
//SEG28 main::@1_9
|
||||
b1_9:
|
||||
//SEG29 [14] *((const byte*) main::SCREEN#0+++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1+1+1+1+1+1+1+1+1
|
||||
sta SCREEN+3+1+1+1+1+1+1+1+1+1
|
||||
jmp b1_10
|
||||
//SEG30 main::@1_10
|
||||
b1_10:
|
||||
//SEG31 [15] *((const byte*) main::SCREEN#0+++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1+1+1+1+1+1+1+1+1+1
|
||||
sta SCREEN+3+1+1+1+1+1+1+1+1+1+1
|
||||
jmp b2
|
||||
//SEG32 main::@2
|
||||
b2:
|
||||
//SEG33 [16] *((const byte*) main::SCREEN#0+++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1+1+1+1+1+1+1+1+1+1+1
|
||||
sta SCREEN+3+1+1+1+1+1+1+1+1+1+1+1
|
||||
jmp breturn
|
||||
//SEG34 main::@return
|
||||
breturn:
|
||||
//SEG35 [17] return [ ] ( main:2 [ ] )
|
||||
rts
|
||||
}
|
||||
|
||||
ASSEMBLER OPTIMIZATIONS
|
||||
Removing instruction jmp b1
|
||||
Removing instruction jmp bend
|
||||
Removing instruction jmp b1
|
||||
Removing instruction jmp b1_1
|
||||
Removing instruction jmp b1_2
|
||||
Removing instruction jmp b1_3
|
||||
Removing instruction jmp b1_4
|
||||
Removing instruction jmp b1_5
|
||||
Removing instruction jmp b1_6
|
||||
Removing instruction jmp b1_7
|
||||
Removing instruction jmp b1_8
|
||||
Removing instruction jmp b1_9
|
||||
Removing instruction jmp b1_10
|
||||
Removing instruction jmp b2
|
||||
Removing instruction jmp breturn
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Removing instruction bbegin:
|
||||
Removing instruction b1_from_bbegin:
|
||||
Removing instruction main_from_b1:
|
||||
Removing instruction bend_from_b1:
|
||||
Succesful ASM optimization Pass5RedundantLabelElimination
|
||||
Removing instruction b1:
|
||||
Removing instruction bend:
|
||||
Removing instruction b1:
|
||||
Removing instruction b1_1:
|
||||
Removing instruction b1_2:
|
||||
Removing instruction b1_3:
|
||||
Removing instruction b1_4:
|
||||
Removing instruction b1_5:
|
||||
Removing instruction b1_6:
|
||||
Removing instruction b1_7:
|
||||
Removing instruction b1_8:
|
||||
Removing instruction b1_9:
|
||||
Removing instruction b1_10:
|
||||
Removing instruction b2:
|
||||
Removing instruction breturn:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
|
||||
FINAL SYMBOL TABLE
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(void()) main()
|
||||
(label) main::@1
|
||||
(label) main::@1_1
|
||||
(label) main::@1_10
|
||||
(label) main::@1_2
|
||||
(label) main::@1_3
|
||||
(label) main::@1_4
|
||||
(label) main::@1_5
|
||||
(label) main::@1_6
|
||||
(label) main::@1_7
|
||||
(label) main::@1_8
|
||||
(label) main::@1_9
|
||||
(label) main::@2
|
||||
(label) main::@return
|
||||
(byte*) main::SCREEN
|
||||
(const byte*) main::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) 1024
|
||||
(byte) main::a
|
||||
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 84
|
||||
|
||||
//SEG0 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
//SEG1 Global Constants & labels
|
||||
//SEG2 @begin
|
||||
//SEG3 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
//SEG4 @1
|
||||
//SEG5 [2] call main [ ] ( )
|
||||
//SEG6 [4] phi from @1 to main [phi:@1->main]
|
||||
jsr main
|
||||
//SEG7 [3] phi from @1 to @end [phi:@1->@end]
|
||||
//SEG8 @end
|
||||
//SEG9 main
|
||||
main: {
|
||||
.label SCREEN = $400
|
||||
//SEG10 main::@1
|
||||
//SEG11 [5] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 3) ← (byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3
|
||||
sta SCREEN+3
|
||||
//SEG12 main::@1_1
|
||||
//SEG13 [6] *((const byte*) main::SCREEN#0+++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1
|
||||
sta SCREEN+3+1
|
||||
//SEG14 main::@1_2
|
||||
//SEG15 [7] *((const byte*) main::SCREEN#0+++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1+1
|
||||
sta SCREEN+3+1+1
|
||||
//SEG16 main::@1_3
|
||||
//SEG17 [8] *((const byte*) main::SCREEN#0+++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1+1+1
|
||||
sta SCREEN+3+1+1+1
|
||||
//SEG18 main::@1_4
|
||||
//SEG19 [9] *((const byte*) main::SCREEN#0+++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1+1+1+1
|
||||
sta SCREEN+3+1+1+1+1
|
||||
//SEG20 main::@1_5
|
||||
//SEG21 [10] *((const byte*) main::SCREEN#0+++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1+1+1+1+1
|
||||
sta SCREEN+3+1+1+1+1+1
|
||||
//SEG22 main::@1_6
|
||||
//SEG23 [11] *((const byte*) main::SCREEN#0+++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1+1+1+1+1+1
|
||||
sta SCREEN+3+1+1+1+1+1+1
|
||||
//SEG24 main::@1_7
|
||||
//SEG25 [12] *((const byte*) main::SCREEN#0+++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1+1+1+1+1+1+1
|
||||
sta SCREEN+3+1+1+1+1+1+1+1
|
||||
//SEG26 main::@1_8
|
||||
//SEG27 [13] *((const byte*) main::SCREEN#0+++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1+1+1+1+1+1+1+1
|
||||
sta SCREEN+3+1+1+1+1+1+1+1+1
|
||||
//SEG28 main::@1_9
|
||||
//SEG29 [14] *((const byte*) main::SCREEN#0+++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1+1+1+1+1+1+1+1+1
|
||||
sta SCREEN+3+1+1+1+1+1+1+1+1+1
|
||||
//SEG30 main::@1_10
|
||||
//SEG31 [15] *((const byte*) main::SCREEN#0+++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1+1+1+1+1+1+1+1+1+1
|
||||
sta SCREEN+3+1+1+1+1+1+1+1+1+1+1
|
||||
//SEG32 main::@2
|
||||
//SEG33 [16] *((const byte*) main::SCREEN#0+++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3) ← ++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 3 [ ] ( main:2 [ ] ) -- _deref_pbuc1=vbuc2
|
||||
lda #3+1+1+1+1+1+1+1+1+1+1+1
|
||||
sta SCREEN+3+1+1+1+1+1+1+1+1+1+1+1
|
||||
//SEG34 main::@return
|
||||
//SEG35 [17] return [ ] ( main:2 [ ] )
|
||||
rts
|
||||
}
|
||||
|
@ -0,0 +1,21 @@
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(void()) main()
|
||||
(label) main::@1
|
||||
(label) main::@1_1
|
||||
(label) main::@1_10
|
||||
(label) main::@1_2
|
||||
(label) main::@1_3
|
||||
(label) main::@1_4
|
||||
(label) main::@1_5
|
||||
(label) main::@1_6
|
||||
(label) main::@1_7
|
||||
(label) main::@1_8
|
||||
(label) main::@1_9
|
||||
(label) main::@2
|
||||
(label) main::@return
|
||||
(byte*) main::SCREEN
|
||||
(const byte*) main::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) 1024
|
||||
(byte) main::a
|
||||
|
@ -0,0 +1,63 @@
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
jsr main
|
||||
main: {
|
||||
.label SCREEN = $400
|
||||
ldx #0
|
||||
b2:
|
||||
txa
|
||||
sta SCREEN+0*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1)*$28,x
|
||||
inx
|
||||
cpx #$28
|
||||
bne b2
|
||||
rts
|
||||
}
|
@ -0,0 +1,97 @@
|
||||
@begin: scope:[] from
|
||||
[0] phi() [ ] ( )
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi() [ ] ( )
|
||||
[2] call main [ ] ( )
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi() [ ] ( )
|
||||
main: scope:[main] from @1
|
||||
[4] phi() [ ] ( main:2 [ ] )
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@3
|
||||
[5] (byte) main::x#4 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@3/(byte) main::x#1 ) [ main::x#4 ] ( main:2 [ main::x#4 ] )
|
||||
to:main::@2
|
||||
main::@2: scope:[main] from main::@1
|
||||
[6] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#4) ← (byte) main::x#4 [ main::x#4 ] ( main:2 [ main::x#4 ] )
|
||||
to:main::@2_1
|
||||
main::@2_1: scope:[main] from main::@2
|
||||
[7] *((const byte*) main::SCREEN#0+++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#4) ← (byte) main::x#4 [ main::x#4 ] ( main:2 [ main::x#4 ] )
|
||||
to:main::@2_2
|
||||
main::@2_2: scope:[main] from main::@2_1
|
||||
[8] *((const byte*) main::SCREEN#0+++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#4) ← (byte) main::x#4 [ main::x#4 ] ( main:2 [ main::x#4 ] )
|
||||
to:main::@2_3
|
||||
main::@2_3: scope:[main] from main::@2_2
|
||||
[9] *((const byte*) main::SCREEN#0+++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#4) ← (byte) main::x#4 [ main::x#4 ] ( main:2 [ main::x#4 ] )
|
||||
to:main::@2_4
|
||||
main::@2_4: scope:[main] from main::@2_3
|
||||
[10] *((const byte*) main::SCREEN#0+++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#4) ← (byte) main::x#4 [ main::x#4 ] ( main:2 [ main::x#4 ] )
|
||||
to:main::@2_5
|
||||
main::@2_5: scope:[main] from main::@2_4
|
||||
[11] *((const byte*) main::SCREEN#0+++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#4) ← (byte) main::x#4 [ main::x#4 ] ( main:2 [ main::x#4 ] )
|
||||
to:main::@2_6
|
||||
main::@2_6: scope:[main] from main::@2_5
|
||||
[12] *((const byte*) main::SCREEN#0+++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#4) ← (byte) main::x#4 [ main::x#4 ] ( main:2 [ main::x#4 ] )
|
||||
to:main::@2_7
|
||||
main::@2_7: scope:[main] from main::@2_6
|
||||
[13] *((const byte*) main::SCREEN#0+++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#4) ← (byte) main::x#4 [ main::x#4 ] ( main:2 [ main::x#4 ] )
|
||||
to:main::@2_8
|
||||
main::@2_8: scope:[main] from main::@2_7
|
||||
[14] *((const byte*) main::SCREEN#0+++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#4) ← (byte) main::x#4 [ main::x#4 ] ( main:2 [ main::x#4 ] )
|
||||
to:main::@2_9
|
||||
main::@2_9: scope:[main] from main::@2_8
|
||||
[15] *((const byte*) main::SCREEN#0+++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#4) ← (byte) main::x#4 [ main::x#4 ] ( main:2 [ main::x#4 ] )
|
||||
to:main::@2_10
|
||||
main::@2_10: scope:[main] from main::@2_9
|
||||
[16] *((const byte*) main::SCREEN#0+++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#4) ← (byte) main::x#4 [ main::x#4 ] ( main:2 [ main::x#4 ] )
|
||||
to:main::@2_11
|
||||
main::@2_11: scope:[main] from main::@2_10
|
||||
[17] *((const byte*) main::SCREEN#0+++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#4) ← (byte) main::x#4 [ main::x#4 ] ( main:2 [ main::x#4 ] )
|
||||
to:main::@2_12
|
||||
main::@2_12: scope:[main] from main::@2_11
|
||||
[18] *((const byte*) main::SCREEN#0+++++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#4) ← (byte) main::x#4 [ main::x#4 ] ( main:2 [ main::x#4 ] )
|
||||
to:main::@2_13
|
||||
main::@2_13: scope:[main] from main::@2_12
|
||||
[19] *((const byte*) main::SCREEN#0+++++++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#4) ← (byte) main::x#4 [ main::x#4 ] ( main:2 [ main::x#4 ] )
|
||||
to:main::@2_14
|
||||
main::@2_14: scope:[main] from main::@2_13
|
||||
[20] *((const byte*) main::SCREEN#0+++++++++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#4) ← (byte) main::x#4 [ main::x#4 ] ( main:2 [ main::x#4 ] )
|
||||
to:main::@2_15
|
||||
main::@2_15: scope:[main] from main::@2_14
|
||||
[21] *((const byte*) main::SCREEN#0+++++++++++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#4) ← (byte) main::x#4 [ main::x#4 ] ( main:2 [ main::x#4 ] )
|
||||
to:main::@2_16
|
||||
main::@2_16: scope:[main] from main::@2_15
|
||||
[22] *((const byte*) main::SCREEN#0+++++++++++++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#4) ← (byte) main::x#4 [ main::x#4 ] ( main:2 [ main::x#4 ] )
|
||||
to:main::@2_17
|
||||
main::@2_17: scope:[main] from main::@2_16
|
||||
[23] *((const byte*) main::SCREEN#0+++++++++++++++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#4) ← (byte) main::x#4 [ main::x#4 ] ( main:2 [ main::x#4 ] )
|
||||
to:main::@2_18
|
||||
main::@2_18: scope:[main] from main::@2_17
|
||||
[24] *((const byte*) main::SCREEN#0+++++++++++++++++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#4) ← (byte) main::x#4 [ main::x#4 ] ( main:2 [ main::x#4 ] )
|
||||
to:main::@2_19
|
||||
main::@2_19: scope:[main] from main::@2_18
|
||||
[25] *((const byte*) main::SCREEN#0+++++++++++++++++++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#4) ← (byte) main::x#4 [ main::x#4 ] ( main:2 [ main::x#4 ] )
|
||||
to:main::@2_20
|
||||
main::@2_20: scope:[main] from main::@2_19
|
||||
[26] *((const byte*) main::SCREEN#0+++++++++++++++++++++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#4) ← (byte) main::x#4 [ main::x#4 ] ( main:2 [ main::x#4 ] )
|
||||
to:main::@2_21
|
||||
main::@2_21: scope:[main] from main::@2_20
|
||||
[27] *((const byte*) main::SCREEN#0+++++++++++++++++++++++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#4) ← (byte) main::x#4 [ main::x#4 ] ( main:2 [ main::x#4 ] )
|
||||
to:main::@2_22
|
||||
main::@2_22: scope:[main] from main::@2_21
|
||||
[28] *((const byte*) main::SCREEN#0+++++++++++++++++++++++++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#4) ← (byte) main::x#4 [ main::x#4 ] ( main:2 [ main::x#4 ] )
|
||||
to:main::@2_23
|
||||
main::@2_23: scope:[main] from main::@2_22
|
||||
[29] *((const byte*) main::SCREEN#0+++++++++++++++++++++++++++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#4) ← (byte) main::x#4 [ main::x#4 ] ( main:2 [ main::x#4 ] )
|
||||
to:main::@2_24
|
||||
main::@2_24: scope:[main] from main::@2_23
|
||||
[30] *((const byte*) main::SCREEN#0+++++++++++++++++++++++++++++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#4) ← (byte) main::x#4 [ main::x#4 ] ( main:2 [ main::x#4 ] )
|
||||
to:main::@3
|
||||
main::@3: scope:[main] from main::@2_24
|
||||
[31] (byte) main::x#1 ← ++ (byte) main::x#4 [ main::x#1 ] ( main:2 [ main::x#1 ] )
|
||||
[32] if((byte) main::x#1!=(byte/signed byte/word/signed word/dword/signed dword) 40) goto main::@1 [ main::x#1 ] ( main:2 [ main::x#1 ] )
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@3
|
||||
[33] return [ ] ( main:2 [ ] )
|
||||
to:@return
|
2061
src/test/java/dk/camelot64/kickc/test/ref/unroll-screenfill-for.log
Normal file
2061
src/test/java/dk/camelot64/kickc/test/ref/unroll-screenfill-for.log
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,40 @@
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(void()) main()
|
||||
(label) main::@1
|
||||
(label) main::@2
|
||||
(label) main::@2_1
|
||||
(label) main::@2_10
|
||||
(label) main::@2_11
|
||||
(label) main::@2_12
|
||||
(label) main::@2_13
|
||||
(label) main::@2_14
|
||||
(label) main::@2_15
|
||||
(label) main::@2_16
|
||||
(label) main::@2_17
|
||||
(label) main::@2_18
|
||||
(label) main::@2_19
|
||||
(label) main::@2_2
|
||||
(label) main::@2_20
|
||||
(label) main::@2_21
|
||||
(label) main::@2_22
|
||||
(label) main::@2_23
|
||||
(label) main::@2_24
|
||||
(label) main::@2_3
|
||||
(label) main::@2_4
|
||||
(label) main::@2_5
|
||||
(label) main::@2_6
|
||||
(label) main::@2_7
|
||||
(label) main::@2_8
|
||||
(label) main::@2_9
|
||||
(label) main::@3
|
||||
(label) main::@return
|
||||
(byte*) main::SCREEN
|
||||
(const byte*) main::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) 1024
|
||||
(byte) main::line
|
||||
(byte) main::x
|
||||
(byte) main::x#1 reg byte x 16.5
|
||||
(byte) main::x#4 reg byte x 22.00000000000001
|
||||
|
||||
reg byte x [ main::x#4 main::x#1 ]
|
@ -0,0 +1,63 @@
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
jsr main
|
||||
main: {
|
||||
.label SCREEN = $400
|
||||
ldx #0
|
||||
b3:
|
||||
txa
|
||||
sta SCREEN+0*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1)*$28,x
|
||||
txa
|
||||
sta SCREEN+(0+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1)*$28,x
|
||||
inx
|
||||
cpx #$28
|
||||
bne b3
|
||||
rts
|
||||
}
|
@ -0,0 +1,97 @@
|
||||
@begin: scope:[] from
|
||||
[0] phi() [ ] ( )
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi() [ ] ( )
|
||||
[2] call main [ ] ( )
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi() [ ] ( )
|
||||
main: scope:[main] from @1
|
||||
[4] phi() [ ] ( main:2 [ ] )
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@4
|
||||
[5] (byte) main::x#5 ← phi( main/(byte/signed byte/word/signed word/dword/signed dword) 0 main::@4/(byte) main::x#1 ) [ main::x#5 ] ( main:2 [ main::x#5 ] )
|
||||
to:main::@3
|
||||
main::@3: scope:[main] from main::@1
|
||||
[6] *((const byte*) main::SCREEN#0+(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#5) ← (byte) main::x#5 [ main::x#5 ] ( main:2 [ main::x#5 ] )
|
||||
to:main::@3_1
|
||||
main::@3_1: scope:[main] from main::@3
|
||||
[7] *((const byte*) main::SCREEN#0+++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#5) ← (byte) main::x#5 [ main::x#5 ] ( main:2 [ main::x#5 ] )
|
||||
to:main::@3_2
|
||||
main::@3_2: scope:[main] from main::@3_1
|
||||
[8] *((const byte*) main::SCREEN#0+++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#5) ← (byte) main::x#5 [ main::x#5 ] ( main:2 [ main::x#5 ] )
|
||||
to:main::@3_3
|
||||
main::@3_3: scope:[main] from main::@3_2
|
||||
[9] *((const byte*) main::SCREEN#0+++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#5) ← (byte) main::x#5 [ main::x#5 ] ( main:2 [ main::x#5 ] )
|
||||
to:main::@3_4
|
||||
main::@3_4: scope:[main] from main::@3_3
|
||||
[10] *((const byte*) main::SCREEN#0+++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#5) ← (byte) main::x#5 [ main::x#5 ] ( main:2 [ main::x#5 ] )
|
||||
to:main::@3_5
|
||||
main::@3_5: scope:[main] from main::@3_4
|
||||
[11] *((const byte*) main::SCREEN#0+++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#5) ← (byte) main::x#5 [ main::x#5 ] ( main:2 [ main::x#5 ] )
|
||||
to:main::@3_6
|
||||
main::@3_6: scope:[main] from main::@3_5
|
||||
[12] *((const byte*) main::SCREEN#0+++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#5) ← (byte) main::x#5 [ main::x#5 ] ( main:2 [ main::x#5 ] )
|
||||
to:main::@3_7
|
||||
main::@3_7: scope:[main] from main::@3_6
|
||||
[13] *((const byte*) main::SCREEN#0+++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#5) ← (byte) main::x#5 [ main::x#5 ] ( main:2 [ main::x#5 ] )
|
||||
to:main::@3_8
|
||||
main::@3_8: scope:[main] from main::@3_7
|
||||
[14] *((const byte*) main::SCREEN#0+++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#5) ← (byte) main::x#5 [ main::x#5 ] ( main:2 [ main::x#5 ] )
|
||||
to:main::@3_9
|
||||
main::@3_9: scope:[main] from main::@3_8
|
||||
[15] *((const byte*) main::SCREEN#0+++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#5) ← (byte) main::x#5 [ main::x#5 ] ( main:2 [ main::x#5 ] )
|
||||
to:main::@3_10
|
||||
main::@3_10: scope:[main] from main::@3_9
|
||||
[16] *((const byte*) main::SCREEN#0+++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#5) ← (byte) main::x#5 [ main::x#5 ] ( main:2 [ main::x#5 ] )
|
||||
to:main::@3_11
|
||||
main::@3_11: scope:[main] from main::@3_10
|
||||
[17] *((const byte*) main::SCREEN#0+++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#5) ← (byte) main::x#5 [ main::x#5 ] ( main:2 [ main::x#5 ] )
|
||||
to:main::@3_12
|
||||
main::@3_12: scope:[main] from main::@3_11
|
||||
[18] *((const byte*) main::SCREEN#0+++++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#5) ← (byte) main::x#5 [ main::x#5 ] ( main:2 [ main::x#5 ] )
|
||||
to:main::@3_13
|
||||
main::@3_13: scope:[main] from main::@3_12
|
||||
[19] *((const byte*) main::SCREEN#0+++++++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#5) ← (byte) main::x#5 [ main::x#5 ] ( main:2 [ main::x#5 ] )
|
||||
to:main::@3_14
|
||||
main::@3_14: scope:[main] from main::@3_13
|
||||
[20] *((const byte*) main::SCREEN#0+++++++++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#5) ← (byte) main::x#5 [ main::x#5 ] ( main:2 [ main::x#5 ] )
|
||||
to:main::@3_15
|
||||
main::@3_15: scope:[main] from main::@3_14
|
||||
[21] *((const byte*) main::SCREEN#0+++++++++++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#5) ← (byte) main::x#5 [ main::x#5 ] ( main:2 [ main::x#5 ] )
|
||||
to:main::@3_16
|
||||
main::@3_16: scope:[main] from main::@3_15
|
||||
[22] *((const byte*) main::SCREEN#0+++++++++++++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#5) ← (byte) main::x#5 [ main::x#5 ] ( main:2 [ main::x#5 ] )
|
||||
to:main::@3_17
|
||||
main::@3_17: scope:[main] from main::@3_16
|
||||
[23] *((const byte*) main::SCREEN#0+++++++++++++++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#5) ← (byte) main::x#5 [ main::x#5 ] ( main:2 [ main::x#5 ] )
|
||||
to:main::@3_18
|
||||
main::@3_18: scope:[main] from main::@3_17
|
||||
[24] *((const byte*) main::SCREEN#0+++++++++++++++++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#5) ← (byte) main::x#5 [ main::x#5 ] ( main:2 [ main::x#5 ] )
|
||||
to:main::@3_19
|
||||
main::@3_19: scope:[main] from main::@3_18
|
||||
[25] *((const byte*) main::SCREEN#0+++++++++++++++++++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#5) ← (byte) main::x#5 [ main::x#5 ] ( main:2 [ main::x#5 ] )
|
||||
to:main::@3_20
|
||||
main::@3_20: scope:[main] from main::@3_19
|
||||
[26] *((const byte*) main::SCREEN#0+++++++++++++++++++++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#5) ← (byte) main::x#5 [ main::x#5 ] ( main:2 [ main::x#5 ] )
|
||||
to:main::@3_21
|
||||
main::@3_21: scope:[main] from main::@3_20
|
||||
[27] *((const byte*) main::SCREEN#0+++++++++++++++++++++++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#5) ← (byte) main::x#5 [ main::x#5 ] ( main:2 [ main::x#5 ] )
|
||||
to:main::@3_22
|
||||
main::@3_22: scope:[main] from main::@3_21
|
||||
[28] *((const byte*) main::SCREEN#0+++++++++++++++++++++++++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#5) ← (byte) main::x#5 [ main::x#5 ] ( main:2 [ main::x#5 ] )
|
||||
to:main::@3_23
|
||||
main::@3_23: scope:[main] from main::@3_22
|
||||
[29] *((const byte*) main::SCREEN#0+++++++++++++++++++++++++++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#5) ← (byte) main::x#5 [ main::x#5 ] ( main:2 [ main::x#5 ] )
|
||||
to:main::@3_24
|
||||
main::@3_24: scope:[main] from main::@3_23
|
||||
[30] *((const byte*) main::SCREEN#0+++++++++++++++++++++++++++++++++++++++++++++++++(byte/signed byte/word/signed word/dword/signed dword) 0*(byte/signed byte/word/signed word/dword/signed dword) 40 + (byte) main::x#5) ← (byte) main::x#5 [ main::x#5 ] ( main:2 [ main::x#5 ] )
|
||||
to:main::@4
|
||||
main::@4: scope:[main] from main::@3_24
|
||||
[31] (byte) main::x#1 ← ++ (byte) main::x#5 [ main::x#1 ] ( main:2 [ main::x#1 ] )
|
||||
[32] if((byte) main::x#1!=(byte/signed byte/word/signed word/dword/signed dword) 40) goto main::@1 [ main::x#1 ] ( main:2 [ main::x#1 ] )
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@4
|
||||
[33] return [ ] ( main:2 [ ] )
|
||||
to:@return
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,40 @@
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(void()) main()
|
||||
(label) main::@1
|
||||
(label) main::@3
|
||||
(label) main::@3_1
|
||||
(label) main::@3_10
|
||||
(label) main::@3_11
|
||||
(label) main::@3_12
|
||||
(label) main::@3_13
|
||||
(label) main::@3_14
|
||||
(label) main::@3_15
|
||||
(label) main::@3_16
|
||||
(label) main::@3_17
|
||||
(label) main::@3_18
|
||||
(label) main::@3_19
|
||||
(label) main::@3_2
|
||||
(label) main::@3_20
|
||||
(label) main::@3_21
|
||||
(label) main::@3_22
|
||||
(label) main::@3_23
|
||||
(label) main::@3_24
|
||||
(label) main::@3_3
|
||||
(label) main::@3_4
|
||||
(label) main::@3_5
|
||||
(label) main::@3_6
|
||||
(label) main::@3_7
|
||||
(label) main::@3_8
|
||||
(label) main::@3_9
|
||||
(label) main::@4
|
||||
(label) main::@return
|
||||
(byte*) main::SCREEN
|
||||
(const byte*) main::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) 1024
|
||||
(byte) main::line
|
||||
(byte) main::x
|
||||
(byte) main::x#1 reg byte x 16.5
|
||||
(byte) main::x#5 reg byte x 22.00000000000001
|
||||
|
||||
reg byte x [ main::x#5 main::x#1 ]
|
@ -0,0 +1,10 @@
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
jsr main
|
||||
main: {
|
||||
.label SCREEN = $400
|
||||
b2:
|
||||
inc SCREEN
|
||||
jmp b2
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
@begin: scope:[] from
|
||||
[0] phi() [ ] ( )
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi() [ ] ( )
|
||||
[2] call main [ ] ( )
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi() [ ] ( )
|
||||
main: scope:[main] from @1
|
||||
[4] phi() [ ] ( main:2 [ ] )
|
||||
to:main::@2
|
||||
main::@2: scope:[main] from main main::@2
|
||||
[5] *((const byte*) main::SCREEN#0) ← ++ *((const byte*) main::SCREEN#0) [ ] ( main:2 [ ] )
|
||||
to:main::@2
|
357
src/test/java/dk/camelot64/kickc/test/ref/unusedblockproblem.log
Normal file
357
src/test/java/dk/camelot64/kickc/test/ref/unusedblockproblem.log
Normal file
@ -0,0 +1,357 @@
|
||||
PARSING src/test/java/dk/camelot64/kickc/test/kc/unusedblockproblem.kc
|
||||
// Problem with eliminating unused blocks/vars after the infinite loop (symbol line#2 not removed from symbol table)
|
||||
|
||||
void main() {
|
||||
byte* SCREEN = $400;
|
||||
while(true) {
|
||||
(*SCREEN)++;
|
||||
}
|
||||
for(byte line: 0..24) {
|
||||
SCREEN[line] = line;
|
||||
}
|
||||
}
|
||||
Adding pre/post-modifier *((byte*) main::SCREEN) ← ++ *((byte*) main::SCREEN)
|
||||
SYMBOLS
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(void()) main()
|
||||
(bool~) main::$0
|
||||
(label) main::@1
|
||||
(label) main::@2
|
||||
(label) main::@3
|
||||
(label) main::@4
|
||||
(label) main::@5
|
||||
(label) main::@6
|
||||
(label) main::@7
|
||||
(label) main::@8
|
||||
(label) main::@return
|
||||
(byte*) main::SCREEN
|
||||
(byte) main::line
|
||||
|
||||
Promoting word/signed word/dword/signed dword to byte* in main::SCREEN ← ((byte*)) 1024
|
||||
INITIAL CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
to:@1
|
||||
main: scope:[main] from
|
||||
(byte*) main::SCREEN ← ((byte*)) (word/signed word/dword/signed dword) 1024
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@2
|
||||
if(true) goto main::@2
|
||||
to:main::@5
|
||||
main::@2: scope:[main] from main::@1 main::@6
|
||||
*((byte*) main::SCREEN) ← ++ *((byte*) main::SCREEN)
|
||||
to:main::@1
|
||||
main::@5: scope:[main] from main::@1
|
||||
to:main::@3
|
||||
main::@3: scope:[main] from main::@5 main::@7
|
||||
(byte) main::line ← (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
to:main::@4
|
||||
main::@6: scope:[main] from
|
||||
to:main::@2
|
||||
main::@7: scope:[main] from
|
||||
to:main::@3
|
||||
main::@4: scope:[main] from main::@3 main::@4
|
||||
*((byte*) main::SCREEN + (byte) main::line) ← (byte) main::line
|
||||
(byte) main::line ← (byte) main::line + rangenext(0,24)
|
||||
(bool~) main::$0 ← (byte) main::line != rangelast(0,24)
|
||||
if((bool~) main::$0) goto main::@4
|
||||
to:main::@8
|
||||
main::@8: scope:[main] from main::@4
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@8
|
||||
return
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
|
||||
Removing empty block main::@5
|
||||
Removing empty block main::@6
|
||||
Removing empty block main::@7
|
||||
Removing empty block main::@8
|
||||
PROCEDURE MODIFY VARIABLE ANALYSIS
|
||||
|
||||
Completing Phi functions...
|
||||
Completing Phi functions...
|
||||
|
||||
CONTROL FLOW GRAPH SSA WITH ASSIGNMENT CALL & RETURN
|
||||
@begin: scope:[] from
|
||||
to:@1
|
||||
main: scope:[main] from @1
|
||||
(byte*) main::SCREEN#0 ← ((byte*)) (word/signed word/dword/signed dword) 1024
|
||||
to:main::@1
|
||||
main::@1: scope:[main] from main main::@2
|
||||
(byte*) main::SCREEN#3 ← phi( main/(byte*) main::SCREEN#0 main::@2/(byte*) main::SCREEN#1 )
|
||||
if(true) goto main::@2
|
||||
to:main::@3
|
||||
main::@2: scope:[main] from main::@1
|
||||
(byte*) main::SCREEN#1 ← phi( main::@1/(byte*) main::SCREEN#3 )
|
||||
*((byte*) main::SCREEN#1) ← ++ *((byte*) main::SCREEN#1)
|
||||
to:main::@1
|
||||
main::@3: scope:[main] from main::@1
|
||||
(byte*) main::SCREEN#4 ← phi( main::@1/(byte*) main::SCREEN#3 )
|
||||
(byte) main::line#0 ← (byte/signed byte/word/signed word/dword/signed dword) 0
|
||||
to:main::@4
|
||||
main::@4: scope:[main] from main::@3 main::@4
|
||||
(byte*) main::SCREEN#2 ← phi( main::@3/(byte*) main::SCREEN#4 main::@4/(byte*) main::SCREEN#2 )
|
||||
(byte) main::line#2 ← phi( main::@3/(byte) main::line#0 main::@4/(byte) main::line#1 )
|
||||
*((byte*) main::SCREEN#2 + (byte) main::line#2) ← (byte) main::line#2
|
||||
(byte) main::line#1 ← (byte) main::line#2 + rangenext(0,24)
|
||||
(bool~) main::$0 ← (byte) main::line#1 != rangelast(0,24)
|
||||
if((bool~) main::$0) goto main::@4
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main::@4
|
||||
return
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
call main
|
||||
to:@2
|
||||
@2: scope:[] from @1
|
||||
to:@end
|
||||
@end: scope:[] from @2
|
||||
|
||||
SYMBOL TABLE SSA
|
||||
(label) @1
|
||||
(label) @2
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(void()) main()
|
||||
(bool~) main::$0
|
||||
(label) main::@1
|
||||
(label) main::@2
|
||||
(label) main::@3
|
||||
(label) main::@4
|
||||
(label) main::@return
|
||||
(byte*) main::SCREEN
|
||||
(byte*) main::SCREEN#0
|
||||
(byte*) main::SCREEN#1
|
||||
(byte*) main::SCREEN#2
|
||||
(byte*) main::SCREEN#3
|
||||
(byte*) main::SCREEN#4
|
||||
(byte) main::line
|
||||
(byte) main::line#0
|
||||
(byte) main::line#1
|
||||
(byte) main::line#2
|
||||
|
||||
OPTIMIZING CONTROL FLOW GRAPH
|
||||
Culled Empty Block (label) @2
|
||||
Succesful SSA optimization Pass2CullEmptyBlocks
|
||||
Alias (byte*) main::SCREEN#1 = (byte*) main::SCREEN#3 (byte*) main::SCREEN#4
|
||||
Succesful SSA optimization Pass2AliasElimination
|
||||
Self Phi Eliminated (byte*) main::SCREEN#1
|
||||
Self Phi Eliminated (byte*) main::SCREEN#2
|
||||
Succesful SSA optimization Pass2SelfPhiElimination
|
||||
Redundant Phi (byte*) main::SCREEN#1 (byte*) main::SCREEN#0
|
||||
Redundant Phi (byte*) main::SCREEN#2 (byte*) main::SCREEN#1
|
||||
Succesful SSA optimization Pass2RedundantPhiElimination
|
||||
Simple Condition (bool~) main::$0 if((byte) main::line#1!=rangelast(0,24)) goto main::@4
|
||||
Succesful SSA optimization Pass2ConditionalJumpSimplification
|
||||
Constant (const byte*) main::SCREEN#0 = ((byte*))1024
|
||||
Constant (const byte) main::line#0 = 0
|
||||
Succesful SSA optimization Pass2ConstantIdentification
|
||||
if() condition always true - replacing block destination if(true) goto main::@2
|
||||
Succesful SSA optimization Pass2ConstantIfs
|
||||
Eliminating variable (byte) main::line#2 from unused block main::@4
|
||||
Eliminating variable (byte) main::line#1 and from unused block main::@4
|
||||
Removing PHI-reference to removed block (main::@3) in block main::@4
|
||||
Removing unused block main::@3
|
||||
Removing unused block main::@4
|
||||
Removing unused block main::@return
|
||||
Succesful SSA optimization Pass2EliminateUnusedBlocks
|
||||
Culled Empty Block (label) main::@1
|
||||
Succesful SSA optimization Pass2CullEmptyBlocks
|
||||
Eliminating unused constant (const byte) main::line#0
|
||||
Succesful SSA optimization PassNEliminateUnusedVars
|
||||
OPTIMIZING CONTROL FLOW GRAPH
|
||||
Block Sequence Planned @begin @1 @end main main::@2
|
||||
Block Sequence Planned @begin @1 @end main main::@2
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @1
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of main
|
||||
CALL GRAPH
|
||||
Calls in [] to main:2
|
||||
|
||||
Propagating live ranges...
|
||||
Created 0 initial phi equivalence classes
|
||||
Coalesced down to 0 phi equivalence classes
|
||||
Block Sequence Planned @begin @1 @end main main::@2
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @1
|
||||
Adding NOP phi() at start of @end
|
||||
Adding NOP phi() at start of main
|
||||
Propagating live ranges...
|
||||
|
||||
FINAL CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
[0] phi() [ ] ( )
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi() [ ] ( )
|
||||
[2] call main [ ] ( )
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi() [ ] ( )
|
||||
main: scope:[main] from @1
|
||||
[4] phi() [ ] ( main:2 [ ] )
|
||||
to:main::@2
|
||||
main::@2: scope:[main] from main main::@2
|
||||
[5] *((const byte*) main::SCREEN#0) ← ++ *((const byte*) main::SCREEN#0) [ ] ( main:2 [ ] )
|
||||
to:main::@2
|
||||
|
||||
DOMINATORS
|
||||
@begin dominated by @begin
|
||||
@1 dominated by @1 @begin
|
||||
@end dominated by @1 @begin @end
|
||||
main dominated by @1 @begin main
|
||||
main::@2 dominated by @1 @begin main::@2 main
|
||||
|
||||
NATURAL LOOPS
|
||||
Found back edge: Loop head: main::@2 tails: main::@2 blocks: null
|
||||
Populated: Loop head: main::@2 tails: main::@2 blocks: main::@2
|
||||
Loop head: main::@2 tails: main::@2 blocks: main::@2
|
||||
|
||||
NATURAL LOOPS WITH DEPTH
|
||||
Found 0 loops in scope []
|
||||
Found 1 loops in scope [main]
|
||||
Loop head: main::@2 tails: main::@2 blocks: main::@2
|
||||
Loop head: main::@2 tails: main::@2 blocks: main::@2 depth: 1
|
||||
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
(void()) main()
|
||||
(byte*) main::SCREEN
|
||||
(byte) main::line
|
||||
|
||||
Initial phi equivalence classes
|
||||
Complete equivalence classes
|
||||
|
||||
INITIAL ASM
|
||||
//SEG0 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
//SEG1 Global Constants & labels
|
||||
//SEG2 @begin
|
||||
bbegin:
|
||||
//SEG3 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
b1_from_bbegin:
|
||||
jmp b1
|
||||
//SEG4 @1
|
||||
b1:
|
||||
//SEG5 [2] call main [ ] ( )
|
||||
//SEG6 [4] phi from @1 to main [phi:@1->main]
|
||||
main_from_b1:
|
||||
jsr main
|
||||
//SEG7 [3] phi from @1 to @end [phi:@1->@end]
|
||||
bend_from_b1:
|
||||
jmp bend
|
||||
//SEG8 @end
|
||||
bend:
|
||||
//SEG9 main
|
||||
main: {
|
||||
.label SCREEN = $400
|
||||
jmp b2
|
||||
//SEG10 main::@2
|
||||
b2:
|
||||
//SEG11 [5] *((const byte*) main::SCREEN#0) ← ++ *((const byte*) main::SCREEN#0) [ ] ( main:2 [ ] ) -- _deref_pbuc1=_inc__deref_pbuc1
|
||||
inc SCREEN
|
||||
jmp b2
|
||||
}
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [main]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [main] best 132 combination
|
||||
Uplifting [] best 132 combination
|
||||
|
||||
ASSEMBLER BEFORE OPTIMIZATION
|
||||
//SEG0 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
//SEG1 Global Constants & labels
|
||||
//SEG2 @begin
|
||||
bbegin:
|
||||
//SEG3 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
b1_from_bbegin:
|
||||
jmp b1
|
||||
//SEG4 @1
|
||||
b1:
|
||||
//SEG5 [2] call main [ ] ( )
|
||||
//SEG6 [4] phi from @1 to main [phi:@1->main]
|
||||
main_from_b1:
|
||||
jsr main
|
||||
//SEG7 [3] phi from @1 to @end [phi:@1->@end]
|
||||
bend_from_b1:
|
||||
jmp bend
|
||||
//SEG8 @end
|
||||
bend:
|
||||
//SEG9 main
|
||||
main: {
|
||||
.label SCREEN = $400
|
||||
jmp b2
|
||||
//SEG10 main::@2
|
||||
b2:
|
||||
//SEG11 [5] *((const byte*) main::SCREEN#0) ← ++ *((const byte*) main::SCREEN#0) [ ] ( main:2 [ ] ) -- _deref_pbuc1=_inc__deref_pbuc1
|
||||
inc SCREEN
|
||||
jmp b2
|
||||
}
|
||||
|
||||
ASSEMBLER OPTIMIZATIONS
|
||||
Removing instruction jmp b1
|
||||
Removing instruction jmp bend
|
||||
Removing instruction jmp b2
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
Removing instruction bbegin:
|
||||
Removing instruction b1_from_bbegin:
|
||||
Removing instruction main_from_b1:
|
||||
Removing instruction bend_from_b1:
|
||||
Succesful ASM optimization Pass5RedundantLabelElimination
|
||||
Removing instruction b1:
|
||||
Removing instruction bend:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
|
||||
FINAL SYMBOL TABLE
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(void()) main()
|
||||
(label) main::@2
|
||||
(byte*) main::SCREEN
|
||||
(const byte*) main::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) 1024
|
||||
(byte) main::line
|
||||
|
||||
|
||||
|
||||
FINAL ASSEMBLER
|
||||
Score: 96
|
||||
|
||||
//SEG0 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
//SEG1 Global Constants & labels
|
||||
//SEG2 @begin
|
||||
//SEG3 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
//SEG4 @1
|
||||
//SEG5 [2] call main [ ] ( )
|
||||
//SEG6 [4] phi from @1 to main [phi:@1->main]
|
||||
jsr main
|
||||
//SEG7 [3] phi from @1 to @end [phi:@1->@end]
|
||||
//SEG8 @end
|
||||
//SEG9 main
|
||||
main: {
|
||||
.label SCREEN = $400
|
||||
//SEG10 main::@2
|
||||
b2:
|
||||
//SEG11 [5] *((const byte*) main::SCREEN#0) ← ++ *((const byte*) main::SCREEN#0) [ ] ( main:2 [ ] ) -- _deref_pbuc1=_inc__deref_pbuc1
|
||||
inc SCREEN
|
||||
jmp b2
|
||||
}
|
||||
|
@ -0,0 +1,9 @@
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(void()) main()
|
||||
(label) main::@2
|
||||
(byte*) main::SCREEN
|
||||
(const byte*) main::SCREEN#0 SCREEN = ((byte*))(word/signed word/dword/signed dword) 1024
|
||||
(byte) main::line
|
||||
|
Loading…
x
Reference in New Issue
Block a user