mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-12-20 07:30:00 +00:00
Added unnamed constant inlining
This commit is contained in:
parent
ccfa6bdbf3
commit
1a9ae72668
@ -136,6 +136,7 @@ public class Compiler {
|
|||||||
List<Pass2SsaOptimization> optimizations = new ArrayList<>();
|
List<Pass2SsaOptimization> optimizations = new ArrayList<>();
|
||||||
optimizations.add(new Pass2CullEmptyBlocks(program));
|
optimizations.add(new Pass2CullEmptyBlocks(program));
|
||||||
optimizations.add(new Pass2ConstantIdentification(program));
|
optimizations.add(new Pass2ConstantIdentification(program));
|
||||||
|
optimizations.add(new Pass2ConstantInlining(program));
|
||||||
|
|
||||||
//optimizations.add(new Pass2ConstantPropagation(program));
|
//optimizations.add(new Pass2ConstantPropagation(program));
|
||||||
//optimizations.add(new Pass2ConstantAdditionElimination(program));
|
//optimizations.add(new Pass2ConstantAdditionElimination(program));
|
||||||
|
@ -4,6 +4,7 @@ import dk.camelot64.kickc.NumberParser;
|
|||||||
import dk.camelot64.kickc.asm.parser.Asm6502BaseVisitor;
|
import dk.camelot64.kickc.asm.parser.Asm6502BaseVisitor;
|
||||||
import dk.camelot64.kickc.asm.parser.Asm6502Parser;
|
import dk.camelot64.kickc.asm.parser.Asm6502Parser;
|
||||||
import dk.camelot64.kickc.icl.*;
|
import dk.camelot64.kickc.icl.*;
|
||||||
|
import dk.camelot64.kickc.passes.Pass1TypeInference;
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -331,6 +332,19 @@ public class AsmFragment {
|
|||||||
bindings.put(name, value);
|
bindings.put(name, value);
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
} else if(value instanceof ConstantValue) {
|
||||||
|
SymbolType type = Pass1TypeInference.inferType(program.getScope(), (ConstantValue) value);
|
||||||
|
if (SymbolTypeBasic.BYTE.equals(type)) {
|
||||||
|
String name = "coby" + nextConstByteIdx++;
|
||||||
|
bindings.put(name, value);
|
||||||
|
return name;
|
||||||
|
} else if (SymbolTypeBasic.WORD.equals(type)) {
|
||||||
|
String name = "cowo" + nextConstByteIdx++;
|
||||||
|
bindings.put(name, value);
|
||||||
|
return name;
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Unhandled constant type " + type);
|
||||||
|
}
|
||||||
} else if (value instanceof Label) {
|
} else if (value instanceof Label) {
|
||||||
String name = "la" + nextLabelIdx++;
|
String name = "la" + nextLabelIdx++;
|
||||||
bindings.put(name, value);
|
bindings.put(name, value);
|
||||||
@ -439,6 +453,9 @@ public class AsmFragment {
|
|||||||
} else if (constant instanceof ConstantVar) {
|
} else if (constant instanceof ConstantVar) {
|
||||||
ConstantVar constantVar = (ConstantVar) constant;
|
ConstantVar constantVar = (ConstantVar) constant;
|
||||||
return getAsmParameter(constantVar);
|
return getAsmParameter(constantVar);
|
||||||
|
} else if (constant instanceof ConstantRef) {
|
||||||
|
ConstantVar constantVar = program.getScope().getConstant((ConstantRef) constant);
|
||||||
|
return getAsmParameter(constantVar);
|
||||||
} else if (constant instanceof ConstantUnary) {
|
} else if (constant instanceof ConstantUnary) {
|
||||||
ConstantUnary unary = (ConstantUnary) constant;
|
ConstantUnary unary = (ConstantUnary) constant;
|
||||||
return unary.getOperator().toString() + toAsm(unary.getOperand());
|
return unary.getOperator().toString() + toAsm(unary.getOperand());
|
||||||
|
@ -42,13 +42,13 @@ public class Pass1TypeInference {
|
|||||||
if (operator == null || assignment.getrValue1() == null) {
|
if (operator == null || assignment.getrValue1() == null) {
|
||||||
// Copy operation or Unary operation
|
// Copy operation or Unary operation
|
||||||
RValue rValue = assignment.getrValue2();
|
RValue rValue = assignment.getrValue2();
|
||||||
SymbolType subType = inferType(rValue);
|
SymbolType subType = inferType(programScope, rValue);
|
||||||
SymbolType type = inferType(operator, subType);
|
SymbolType type = inferType(operator, subType);
|
||||||
symbol.setTypeInferred(type);
|
symbol.setTypeInferred(type);
|
||||||
} else {
|
} else {
|
||||||
// Binary operation
|
// Binary operation
|
||||||
SymbolType type1 = inferType(assignment.getrValue1());
|
SymbolType type1 = inferType(programScope, assignment.getrValue1());
|
||||||
SymbolType type2 = inferType(assignment.getrValue2());
|
SymbolType type2 = inferType(programScope, assignment.getrValue2());
|
||||||
SymbolType type = inferType(type1, operator, type2);
|
SymbolType type = inferType(type1, operator, type2);
|
||||||
symbol.setTypeInferred(type);
|
symbol.setTypeInferred(type);
|
||||||
}
|
}
|
||||||
@ -156,11 +156,14 @@ public class Pass1TypeInference {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public SymbolType inferType(RValue rValue) {
|
public static SymbolType inferType(ProgramScope programScope, RValue rValue) {
|
||||||
SymbolType type = null;
|
SymbolType type = null;
|
||||||
if (rValue instanceof VariableRef) {
|
if (rValue instanceof VariableRef) {
|
||||||
Variable variable = programScope.getVariable((VariableRef) rValue);
|
Variable variable = programScope.getVariable((VariableRef) rValue);
|
||||||
type = variable.getType();
|
type = variable.getType();
|
||||||
|
} else if (rValue instanceof ConstantRef) {
|
||||||
|
ConstantVar constVar = programScope.getConstant((ConstantRef) rValue);
|
||||||
|
type = constVar.getType();
|
||||||
} else if (rValue instanceof Symbol) {
|
} else if (rValue instanceof Symbol) {
|
||||||
Symbol rSymbol = (Symbol) rValue;
|
Symbol rSymbol = (Symbol) rValue;
|
||||||
type = rSymbol.getType();
|
type = rSymbol.getType();
|
||||||
@ -171,6 +174,15 @@ public class Pass1TypeInference {
|
|||||||
type = SymbolTypeBasic.STRING;
|
type = SymbolTypeBasic.STRING;
|
||||||
} else if (rValue instanceof ConstantBool) {
|
} else if (rValue instanceof ConstantBool) {
|
||||||
type = SymbolTypeBasic.BOOLEAN;
|
type = SymbolTypeBasic.BOOLEAN;
|
||||||
|
} else if (rValue instanceof ConstantUnary) {
|
||||||
|
ConstantUnary constUnary = (ConstantUnary) rValue;
|
||||||
|
SymbolType subType = inferType(programScope, constUnary.getOperand());
|
||||||
|
return inferType(constUnary.getOperator(), subType);
|
||||||
|
} else if (rValue instanceof ConstantBinary) {
|
||||||
|
ConstantBinary constBin = (ConstantBinary) rValue;
|
||||||
|
SymbolType leftType = inferType(programScope, constBin.getLeft());
|
||||||
|
SymbolType rightType = inferType(programScope, constBin.getRight());
|
||||||
|
return inferType(leftType, constBin.getOperator(), rightType);
|
||||||
}
|
}
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
throw new RuntimeException("Cannot infer type for " + rValue);
|
throw new RuntimeException("Cannot infer type for " + rValue);
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package dk.camelot64.kickc.passes;
|
package dk.camelot64.kickc.passes;
|
||||||
|
|
||||||
import dk.camelot64.kickc.CompileLog;
|
|
||||||
import dk.camelot64.kickc.icl.*;
|
import dk.camelot64.kickc.icl.*;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@ -32,7 +31,7 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
|
|||||||
}
|
}
|
||||||
getLog().append("Alias " + str);
|
getLog().append("Alias " + str);
|
||||||
}
|
}
|
||||||
deleteVariables(aliases.getSymbolsToRemove());
|
deleteSymbols(aliases.getSymbolsToRemove());
|
||||||
return (aliases.size() > 0);
|
return (aliases.size() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package dk.camelot64.kickc.passes;
|
package dk.camelot64.kickc.passes;
|
||||||
|
|
||||||
import dk.camelot64.kickc.CompileLog;
|
|
||||||
import dk.camelot64.kickc.icl.*;
|
import dk.camelot64.kickc.icl.*;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -25,7 +24,7 @@ public class Pass2ConditionalJumpSimplification extends Pass2SsaOptimization {
|
|||||||
final Map<RValue, List<Statement>> usages = getAllUsages();
|
final Map<RValue, List<Statement>> usages = getAllUsages();
|
||||||
final List<VariableRef> simpleConditionVars = getSimpleConditions(assignments, usages);
|
final List<VariableRef> simpleConditionVars = getSimpleConditions(assignments, usages);
|
||||||
removeAssignments(simpleConditionVars);
|
removeAssignments(simpleConditionVars);
|
||||||
deleteVariables(simpleConditionVars);
|
deleteSymbols(simpleConditionVars);
|
||||||
return (simpleConditionVars.size()>0);
|
return (simpleConditionVars.size()>0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
package dk.camelot64.kickc.passes;
|
||||||
|
|
||||||
|
import dk.camelot64.kickc.icl.ConstantRef;
|
||||||
|
import dk.camelot64.kickc.icl.ConstantValue;
|
||||||
|
import dk.camelot64.kickc.icl.ConstantVar;
|
||||||
|
import dk.camelot64.kickc.icl.Program;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/** Compiler Pass consolidating unnamed constants into the place using them (instructions or the definition of another constant value) */
|
||||||
|
public class Pass2ConstantInlining extends Pass2SsaOptimization {
|
||||||
|
|
||||||
|
public Pass2ConstantInlining(Program program) {
|
||||||
|
super(program);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Consolidate unnamed constants into other constants value
|
||||||
|
* @return true optimization was performed. false if no optimization was possible.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean optimize() {
|
||||||
|
Map<ConstantRef, ConstantValue> unnamedConstants = findUnnamedConstants();
|
||||||
|
|
||||||
|
// Replace all usages of the unnamed constants
|
||||||
|
replaceVariables(unnamedConstants);
|
||||||
|
// Remove from symbol table
|
||||||
|
deleteSymbols(unnamedConstants.keySet());
|
||||||
|
|
||||||
|
for (ConstantRef constantRef : unnamedConstants.keySet()) {
|
||||||
|
getLog().append("Constant inlined " + constantRef.toString()+" = "+unnamedConstants.get(constantRef).toString(getProgram()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return unnamedConstants.size()>0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<ConstantRef, ConstantValue> findUnnamedConstants() {
|
||||||
|
Map<ConstantRef, ConstantValue> unnamed = new HashMap<>();
|
||||||
|
Collection<ConstantVar> allConstants = getProgram().getScope().getAllConstants(true);
|
||||||
|
for (ConstantVar constant : allConstants) {
|
||||||
|
if(constant.getRef().isIntermediate()) {
|
||||||
|
unnamed.put(constant.getRef(), constant.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return unnamed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,5 @@
|
|||||||
package dk.camelot64.kickc.passes;
|
package dk.camelot64.kickc.passes;
|
||||||
|
|
||||||
import dk.camelot64.kickc.CompileLog;
|
|
||||||
import dk.camelot64.kickc.icl.*;
|
import dk.camelot64.kickc.icl.*;
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
@ -25,7 +24,7 @@ public class Pass2RedundantPhiElimination extends Pass2SsaOptimization {
|
|||||||
RValue alias = aliases.get(var);
|
RValue alias = aliases.get(var);
|
||||||
getLog().append("Redundant Phi " + var.toString(getProgram()) + " " + alias.toString(getProgram()));
|
getLog().append("Redundant Phi " + var.toString(getProgram()) + " " + alias.toString(getProgram()));
|
||||||
}
|
}
|
||||||
deleteVariables(aliases.keySet());
|
deleteSymbols(aliases.keySet());
|
||||||
return aliases.size()>0;
|
return aliases.size()>0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ public abstract class Pass2SsaOptimization {
|
|||||||
*
|
*
|
||||||
* @param aliases Variables that have alias values.
|
* @param aliases Variables that have alias values.
|
||||||
*/
|
*/
|
||||||
public void replaceVariables(final Map<VariableRef, ? extends RValue> aliases) {
|
public void replaceVariables(final Map<? extends SymbolRef, ? extends RValue> aliases) {
|
||||||
ControlFlowGraphBaseVisitor<Void> visitor = new ControlFlowGraphBaseVisitor<Void>() {
|
ControlFlowGraphBaseVisitor<Void> visitor = new ControlFlowGraphBaseVisitor<Void>() {
|
||||||
@Override
|
@Override
|
||||||
public Void visitAssignment(StatementAssignment assignment) {
|
public Void visitAssignment(StatementAssignment assignment) {
|
||||||
@ -177,7 +177,7 @@ public abstract class Pass2SsaOptimization {
|
|||||||
* @param rValue The RValue to find an alias for
|
* @param rValue The RValue to find an alias for
|
||||||
* @return The alias to use. Null if no alias exists.
|
* @return The alias to use. Null if no alias exists.
|
||||||
*/
|
*/
|
||||||
private static RValue getAlias(Map<VariableRef, ? extends RValue> aliases, RValue rValue) {
|
private static RValue getAlias(Map<? extends SymbolRef, ? extends RValue> aliases, RValue rValue) {
|
||||||
RValue alias = aliases.get(rValue);
|
RValue alias = aliases.get(rValue);
|
||||||
while (aliases.get(alias) != null) {
|
while (aliases.get(alias) != null) {
|
||||||
alias = aliases.get(alias);
|
alias = aliases.get(alias);
|
||||||
@ -276,20 +276,9 @@ public abstract class Pass2SsaOptimization {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void deleteSymbols(Collection<? extends SymbolRef> symbols) {
|
||||||
* Remove symbols from the symbol table
|
for (SymbolRef symbolRef : symbols) {
|
||||||
*
|
Symbol symbol = getSymbols().getSymbol(symbolRef.getFullName());
|
||||||
* @param symbols The symbols to remove
|
|
||||||
*/
|
|
||||||
public void deleteSymbols(Collection<? extends Symbol> symbols) {
|
|
||||||
for (Symbol symbol : symbols) {
|
|
||||||
symbol.getScope().remove(symbol);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void deleteVariables(Collection<? extends VariableRef> symbols) {
|
|
||||||
for (VariableRef variableRef : symbols) {
|
|
||||||
Symbol symbol = getSymbols().getSymbol(variableRef.getFullName());
|
|
||||||
symbol.getScope().remove(symbol);
|
symbol.getScope().remove(symbol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ public class Pass2UnaryNotSimplification extends Pass2SsaOptimization {
|
|||||||
final Map<LValue, StatementAssignment> assignments = getAllAssignments();
|
final Map<LValue, StatementAssignment> assignments = getAllAssignments();
|
||||||
final List<VariableRef> unusedComparisons = optimizeUnaryNots(assignments, usages);
|
final List<VariableRef> unusedComparisons = optimizeUnaryNots(assignments, usages);
|
||||||
removeAssignments(unusedComparisons);
|
removeAssignments(unusedComparisons);
|
||||||
deleteVariables(unusedComparisons);
|
deleteSymbols(unusedComparisons);
|
||||||
return (unusedComparisons.size() > 0);
|
return (unusedComparisons.size() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package dk.camelot64.kickc.passes;
|
package dk.camelot64.kickc.passes;
|
||||||
|
|
||||||
import dk.camelot64.kickc.CompileLog;
|
|
||||||
import dk.camelot64.kickc.icl.*;
|
import dk.camelot64.kickc.icl.*;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -37,7 +36,7 @@ public class Pass3PhiMemCoalesce extends Pass2SsaOptimization {
|
|||||||
phiMemCoalescer.visitGraph(getGraph());
|
phiMemCoalescer.visitGraph(getGraph());
|
||||||
removeAssignments(phiMemCoalescer.getRemove());
|
removeAssignments(phiMemCoalescer.getRemove());
|
||||||
replaceVariables(phiMemCoalescer.getReplace());
|
replaceVariables(phiMemCoalescer.getReplace());
|
||||||
deleteVariables(phiMemCoalescer.getRemove());
|
deleteSymbols(phiMemCoalescer.getRemove());
|
||||||
getLog().append("Coalesced down to " + phiEquivalenceClasses.size() + " phi equivalence classes");
|
getLog().append("Coalesced down to " + phiEquivalenceClasses.size() + " phi equivalence classes");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -82,20 +82,59 @@ public class Pass4CodeGeneration {
|
|||||||
* Add constant declarations for all scope constants
|
* Add constant declarations for all scope constants
|
||||||
*
|
*
|
||||||
* @param asm The ASM program
|
* @param asm The ASM program
|
||||||
* @param scope The scope
|
* @param scopeRef The scope
|
||||||
*/
|
*/
|
||||||
private void addConstants(AsmProgram asm, ScopeRef currentScope) {
|
private void addConstants(AsmProgram asm, ScopeRef scopeRef) {
|
||||||
Collection<ConstantVar> scopeConstants = program.getScope().getScope(currentScope).getAllConstants(false);
|
Scope scope = program.getScope().getScope(scopeRef);
|
||||||
|
Collection<ConstantVar> scopeConstants = scope.getAllConstants(false);
|
||||||
Set<String> added = new LinkedHashSet<>();
|
Set<String> added = new LinkedHashSet<>();
|
||||||
for (ConstantVar scopeConstant : scopeConstants) {
|
for (ConstantVar scopeConstant : scopeConstants) {
|
||||||
String asmName = scopeConstant.getLocalName(); // scopeConstant.getAsmName()
|
String asmName = scopeConstant.getLocalName(); // scopeConstant.getAsmName()
|
||||||
if (asmName != null && !added.contains(asmName)) {
|
if (asmName != null && !added.contains(asmName)) {
|
||||||
asm.addConstant(asmName.replace("#","_").replace("$","_"), scopeConstant.getValue().toString(program));
|
asm.addConstant(asmName.replace("#", "_").replace("$", "_"), getConstantValueAsm(scopeConstant.getValue(), false));
|
||||||
added.add(asmName);
|
added.add(asmName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get ASM code for a constant value
|
||||||
|
*
|
||||||
|
* @param value The constant value
|
||||||
|
* @param subOperator is this generated inside another operator (needing a parenthesis)
|
||||||
|
*
|
||||||
|
* @return The ASM string representing the constant value
|
||||||
|
*/
|
||||||
|
private String getConstantValueAsm(Constant value, boolean subOperator) {
|
||||||
|
if (value instanceof ConstantRef) {
|
||||||
|
value = program.getScope().getConstant((ConstantRef) value);
|
||||||
|
}
|
||||||
|
if (value instanceof ConstantVar) {
|
||||||
|
String asmName = ((ConstantVar) value).getLocalName(); // xxx.getAsmName()
|
||||||
|
return asmName.replace("#", "_").replace("$", "_");
|
||||||
|
} else if (value instanceof ConstantInteger) {
|
||||||
|
return String.format("$%x", ((ConstantInteger) value).getNumber());
|
||||||
|
} else if (value instanceof ConstantUnary) {
|
||||||
|
ConstantUnary unary = (ConstantUnary) value;
|
||||||
|
return
|
||||||
|
(subOperator ? "(" : "") +
|
||||||
|
unary.getOperator().getOperator() +
|
||||||
|
getConstantValueAsm(unary.getOperand(), true) +
|
||||||
|
(subOperator ? ")" : "");
|
||||||
|
} else if (value instanceof ConstantBinary) {
|
||||||
|
ConstantBinary binary = (ConstantBinary) value;
|
||||||
|
return
|
||||||
|
(subOperator ? "(" : "") +
|
||||||
|
getConstantValueAsm(binary.getLeft(), true) +
|
||||||
|
binary.getOperator().getOperator() +
|
||||||
|
getConstantValueAsm(binary.getRight(), true) +
|
||||||
|
(subOperator ? ")" : "");
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Constant type not supported " + value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add label declarations for all scope variables assigned to ZP registers
|
* Add label declarations for all scope variables assigned to ZP registers
|
||||||
*
|
*
|
||||||
@ -111,7 +150,7 @@ public class Pass4CodeGeneration {
|
|||||||
Registers.RegisterZp registerZp = (Registers.RegisterZp) register;
|
Registers.RegisterZp registerZp = (Registers.RegisterZp) register;
|
||||||
String asmName = scopeVar.getAsmName();
|
String asmName = scopeVar.getAsmName();
|
||||||
if (asmName != null && !added.contains(asmName)) {
|
if (asmName != null && !added.contains(asmName)) {
|
||||||
asm.addLabelDecl(asmName.replace("#","_").replace("$","_"), registerZp.getZp());
|
asm.addLabelDecl(asmName.replace("#", "_").replace("$", "_"), registerZp.getZp());
|
||||||
added.add(asmName);
|
added.add(asmName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -280,7 +319,7 @@ public class Pass4CodeGeneration {
|
|||||||
}
|
}
|
||||||
transition.setGenerated(true);
|
transition.setGenerated(true);
|
||||||
} else {
|
} else {
|
||||||
program.getLog().append("Already generated transition from "+fromBlock.getLabel()+" to "+toBlock.getLabel()+ " - not generating it again!");
|
program.getLog().append("Already generated transition from " + fromBlock.getLabel() + " to " + toBlock.getLabel() + " - not generating it again!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,7 +396,7 @@ public class Pass4CodeGeneration {
|
|||||||
private PhiTransition findTransition(ControlFlowBlock fromBlock) {
|
private PhiTransition findTransition(ControlFlowBlock fromBlock) {
|
||||||
PhiTransition transition = new PhiTransition(fromBlock);
|
PhiTransition transition = new PhiTransition(fromBlock);
|
||||||
boolean isCallTransition = toBlock.getLabel().equals(fromBlock.getCallSuccessor());
|
boolean isCallTransition = toBlock.getLabel().equals(fromBlock.getCallSuccessor());
|
||||||
if(!isCallTransition) {
|
if (!isCallTransition) {
|
||||||
// If the transition is not a call - then attempt to join with other equal transition(s)
|
// If the transition is not a call - then attempt to join with other equal transition(s)
|
||||||
for (PhiTransition candidate : transitions.values()) {
|
for (PhiTransition candidate : transitions.values()) {
|
||||||
if (candidate.equalAssignments(transition)) {
|
if (candidate.equalAssignments(transition)) {
|
||||||
|
@ -2,7 +2,7 @@ const byte* SCREEN = $0400;
|
|||||||
const byte STAR = 81;
|
const byte STAR = 81;
|
||||||
|
|
||||||
byte* VIC = $d000;
|
byte* VIC = $d000;
|
||||||
byte* BGCOL = VIC+$21;
|
byte* BGCOL = VIC+$10*2+1;
|
||||||
byte RED = 2;
|
byte RED = 2;
|
||||||
|
|
||||||
main();
|
main();
|
||||||
|
Loading…
Reference in New Issue
Block a user