1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2025-02-05 21:30:52 +00:00

Renamed ValueReplacer classes to ValueIterator to better illustrate the generic nature.

This commit is contained in:
Jesper Gravgaard 2018-07-22 16:02:51 +09:00
parent a14fa4dec3
commit f17422a564
18 changed files with 372 additions and 327 deletions

View File

@ -6,16 +6,20 @@ import dk.camelot64.kickc.model.types.SymbolTypeArray;
import dk.camelot64.kickc.model.values.*;
/**
* Interface representing an RValue that can be replaced.
* The value may have sub-values that can also be replaced.
* An RValue in the program being iterated by {@link ProgramValueIterator}.
*
* The RValue can be inspected using get() and replaced inside the model using set(val).
*
* The context of the RValue can be determined from the sub-class containing it plus the parameters to the ProgramValueHandler.
*
*/
public abstract class ReplaceableValue {
public abstract class ProgramValue {
public abstract RValue get();
public abstract void set(RValue value);
public static class ConstantVariableValue extends ReplaceableValue {
public static class ConstantVariableValue extends ProgramValue {
private final ConstantVar constantVar;
public ConstantVariableValue(ConstantVar constantVar) {
@ -34,8 +38,8 @@ public abstract class ReplaceableValue {
}
/** Replaceable size inside a fixed size array. */
public static class TypeArraySize extends ReplaceableValue {
/** Size inside a fixed size array. */
public static class TypeArraySize extends ProgramValue {
private final SymbolTypeArray array;
public TypeArraySize(SymbolTypeArray array) {
@ -54,8 +58,8 @@ public abstract class ReplaceableValue {
}
/** Replaceable value inside a array filled expression. */
public static class ArrayFilledSize extends ReplaceableValue {
/** Value inside a array filled expression. */
public static class ArrayFilledSize extends ProgramValue {
private final ArrayFilled array;
ArrayFilledSize(ArrayFilled array) {
@ -74,8 +78,8 @@ public abstract class ReplaceableValue {
}
/** Replaceable value inside a constant array filled expression. */
public static class ConstantArrayFilledSize extends ReplaceableValue {
/** Value inside a constant array filled expression. */
public static class ConstantArrayFilledSize extends ProgramValue {
private final ConstantArrayFilled array;
ConstantArrayFilledSize(ConstantArrayFilled array) {
@ -94,8 +98,8 @@ public abstract class ReplaceableValue {
}
/** Replaceable value inside a constant unary expression. */
public static class ConstantUnaryValue extends ReplaceableValue {
/** Value inside a constant unary expression. */
public static class ConstantUnaryValue extends ProgramValue {
private final ConstantUnary unary;
ConstantUnaryValue(ConstantUnary unary) {
@ -114,8 +118,8 @@ public abstract class ReplaceableValue {
}
/** Replaceable left value inside a constant binary expression. */
public static class ConstantBinaryLeft extends ReplaceableValue {
/** Left value inside a constant binary expression. */
public static class ConstantBinaryLeft extends ProgramValue {
private final ConstantBinary binary;
ConstantBinaryLeft(ConstantBinary binary) {
@ -134,8 +138,8 @@ public abstract class ReplaceableValue {
}
/** Replaceable right value inside a constant binary expression. */
public static class ConstantBinaryRight extends ReplaceableValue {
/** Right value inside a constant binary expression. */
public static class ConstantBinaryRight extends ProgramValue {
private final ConstantBinary binary;
ConstantBinaryRight(ConstantBinary range) {
@ -155,9 +159,9 @@ public abstract class ReplaceableValue {
}
/**
* Replaceable first value inside a ranged comparison value.
* First value inside a ranged comparison value.
*/
public static class RangeFirst extends ReplaceableValue {
public static class RangeFirst extends ProgramValue {
private final RangeValue range;
RangeFirst(RangeValue range) {
@ -177,9 +181,9 @@ public abstract class ReplaceableValue {
}
/**
* Replaceable last value inside inside a ranged comparison value.
* Last value inside inside a ranged comparison value.
*/
public static class RangeLast extends ReplaceableValue {
public static class RangeLast extends ProgramValue {
private final RangeValue range;
RangeLast(RangeValue range) {
@ -199,9 +203,9 @@ public abstract class ReplaceableValue {
}
/**
* Replaceable LValue as part of an assignment statement (or a call).
* LValue as part of an assignment statement (or a call).
*/
public static class LValue extends ReplaceableValue {
public static class LValue extends ProgramValue {
private final StatementLValue statement;
public LValue(StatementLValue statement) {
@ -221,9 +225,9 @@ public abstract class ReplaceableValue {
}
/**
* Replaceable pointer inside a pointer dererence value.
* Pointer inside a pointer dererence value.
*/
public static class Pointer extends ReplaceableValue {
public static class Pointer extends ProgramValue {
private final PointerDereference pointer;
Pointer(PointerDereference pointer) {
@ -243,9 +247,9 @@ public abstract class ReplaceableValue {
}
/**
* Replaceable value inside a noop cast.
* Value inside a noop cast.
*/
public static class CastValue extends ReplaceableValue {
public static class CastValue extends ProgramValue {
private final dk.camelot64.kickc.model.values.CastValue castValue;
@ -266,9 +270,9 @@ public abstract class ReplaceableValue {
}
/**
* Replaceable value inside a constant noop cast.
* Value inside a constant noop cast.
*/
public static class ConstantCastValue extends ReplaceableValue {
public static class ConstantCastValue extends ProgramValue {
private final dk.camelot64.kickc.model.values.ConstantCastValue castValue;
@ -289,9 +293,9 @@ public abstract class ReplaceableValue {
}
/**
* Replaceable pointer inside a variable pointer.
* Pointer inside a variable pointer.
*/
public static class VarPointer extends ReplaceableValue {
public static class VarPointer extends ProgramValue {
private final ConstantVarPointer varPointer;
@ -311,7 +315,7 @@ public abstract class ReplaceableValue {
}
public static class ConstantArrayElement extends ReplaceableValue {
public static class ConstantArrayElement extends ProgramValue {
private final ConstantArrayList arrayList;
private final int idx;
@ -331,7 +335,7 @@ public abstract class ReplaceableValue {
}
}
public static class ListElement extends ReplaceableValue {
public static class ListElement extends ProgramValue {
private ValueList list;
private int idx;
@ -353,9 +357,9 @@ public abstract class ReplaceableValue {
}
/**
* Replaceable pointer index inside a indexed pointer dererence value.
* Pointer index inside a indexed pointer dererence value.
*/
public static class PointerIndex extends ReplaceableValue {
public static class PointerIndex extends ProgramValue {
private final PointerDereferenceIndexed pointer;
PointerIndex(PointerDereferenceIndexed pointer) {
@ -374,7 +378,7 @@ public abstract class ReplaceableValue {
}
public static class RValue1 extends ReplaceableValue {
public static class RValue1 extends ProgramValue {
private final StatementAssignment statement;
public RValue1(StatementAssignment statement) {
@ -392,7 +396,7 @@ public abstract class ReplaceableValue {
}
}
public static class RValue2 extends ReplaceableValue {
public static class RValue2 extends ProgramValue {
private final StatementAssignment statement;
public RValue2(StatementAssignment statement) {
@ -410,7 +414,7 @@ public abstract class ReplaceableValue {
}
}
public static class CallParameter extends ReplaceableValue {
public static class CallParameter extends ProgramValue {
private final StatementCall call;
private final int i;
@ -430,7 +434,7 @@ public abstract class ReplaceableValue {
}
}
public static class CondRValue1 extends ReplaceableValue {
public static class CondRValue1 extends ProgramValue {
private final StatementConditionalJump statement;
public CondRValue1(StatementConditionalJump statement) {
@ -448,7 +452,7 @@ public abstract class ReplaceableValue {
}
}
public static class CondRValue2 extends ReplaceableValue {
public static class CondRValue2 extends ProgramValue {
private final StatementConditionalJump statement;
public CondRValue2(StatementConditionalJump statement) {
@ -466,7 +470,7 @@ public abstract class ReplaceableValue {
}
}
public static class Return extends ReplaceableValue {
public static class Return extends ProgramValue {
private final StatementReturn statement;
public Return(StatementReturn statement) {
@ -484,7 +488,7 @@ public abstract class ReplaceableValue {
}
}
public static class PhiValue extends ReplaceableValue {
public static class PhiValue extends ProgramValue {
private final StatementPhiBlock.PhiVariable phiVariable;
private final int i;
@ -505,9 +509,9 @@ public abstract class ReplaceableValue {
}
/**
* Replaceable LValue as part of an assignment statement (or a call).
* LValue as part of an assignment statement (or a call).
*/
public static class PhiVariable extends ReplaceableValue {
public static class PhiVariable extends ProgramValue {
private final StatementPhiBlock.PhiVariable phiVariable;
public PhiVariable(StatementPhiBlock.PhiVariable phiVariable) {
@ -526,8 +530,8 @@ public abstract class ReplaceableValue {
}
/** A generic replaceable value. */
public static class GenericValue extends ReplaceableValue {
/** A generic Value. */
public static class GenericValue extends ProgramValue {
private ConstantValue constantValue;
public GenericValue(ConstantValue constantValue) {

View File

@ -0,0 +1,24 @@
package dk.camelot64.kickc.model.iterator;
import dk.camelot64.kickc.model.ControlFlowBlock;
import dk.camelot64.kickc.model.statements.Statement;
import java.util.ListIterator;
/** A handler that performs some action for RValues in the program.
* A {@link }ProgramValueIterator} can be used to iterate all RValues in a part of the program.
* The Handler then receives all program values one at a time. The Handler has the option of replacing the value with another. After the handler is executed all sub-values are recursed.
* The execute() method furthermore receives some extra parameters with information about the context of the passed value.
*/
public interface ProgramValueHandler {
/**
* Handle a single RValue
*
* @param programValue The programValue value
* @param currentStmt The statement iterator - just past the current statement that the value is a part of. Current statment can be retrieved by calling
* @param stmtIt The statement iterator - just past the current statement. Can be used for modifying the control flow block.
* @param currentBlock The current block that the value is a part of
*/
void execute(ProgramValue programValue, Statement currentStmt, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock);
}

View File

@ -0,0 +1,194 @@
package dk.camelot64.kickc.model.iterator;
import dk.camelot64.kickc.model.ControlFlowBlock;
import dk.camelot64.kickc.model.ControlFlowGraph;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.statements.*;
import dk.camelot64.kickc.model.symbols.ConstantVar;
import dk.camelot64.kickc.model.symbols.ProgramScope;
import dk.camelot64.kickc.model.symbols.SymbolVariable;
import dk.camelot64.kickc.model.types.SymbolTypeArray;
import dk.camelot64.kickc.model.values.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.ListIterator;
/**
* Capable of iterating the different structures of a Program (graph, block, statement, symboltable, symbol).
* Creates appropriate ProgramValues and passes them to a ProgramValueHandler.
* Iteration might be guided (eg. filtering some types of the structure to iterate at call-time or guided by a return value from the ProgramValueHandler)
*/
public class ProgramValueIterator {
/**
* Execute a handler on all values in the entire program (both in the control flow graph and the symbol table.)
*
* @param program The program
* @param handler The handler to execute
*/
public static void execute(Program program, ProgramValueHandler handler) {
execute(program.getScope(), handler);
execute(program.getGraph(), handler);
}
/**
* Execute a handler on all values in the program scope
*
* @param programScope The program scope
* @param handler The handler to execute
*/
public static void execute(ProgramScope programScope, ProgramValueHandler handler) {
for(SymbolVariable symbolVariable : programScope.getAllSymbolVariables(true)) {
execute(symbolVariable, handler);
}
}
/**
* Execute a programValueHandler on all values in a variable symbol (variable or constant).
*
* @param symbolVariable The symbol variable
* @param programValueHandler The programValueHandler to execute
*/
private static void execute(SymbolVariable symbolVariable, ProgramValueHandler programValueHandler) {
if(symbolVariable.getType() instanceof SymbolTypeArray) {
execute(new ProgramValue.TypeArraySize((SymbolTypeArray) symbolVariable.getType()), programValueHandler, null, null, null);
}
if(symbolVariable instanceof ConstantVar) {
execute(new ProgramValue.ConstantVariableValue((ConstantVar) symbolVariable), programValueHandler, null, null, null);
}
}
/**
* Execute a handler on all values in the program control flow graph
*
* @param graph The program control flow graph
* @param handler The handler to execute
*/
public static void execute(ControlFlowGraph graph, ProgramValueHandler handler) {
for(ControlFlowBlock block : graph.getAllBlocks()) {
execute(block, handler);
}
}
/**
* Execute a handler on all values in a block of the control flow graph
*
* @param block The control flow graph block
* @param handler The handler to execute
*/
public static void execute(ControlFlowBlock block, ProgramValueHandler handler) {
ListIterator<Statement> statementsIt = block.getStatements().listIterator();
while(statementsIt.hasNext()) {
Statement statement = statementsIt.next();
execute(statement, handler, statementsIt, block);
}
}
/**
* Execute a handler on all values in a statement
*
* @param statement The statement
* @param handler The handler to execute
*/
public static void execute(Statement statement, ProgramValueHandler handler, ListIterator<Statement> statementsIt, ControlFlowBlock block) {
if(statement instanceof StatementAssignment) {
// The sequence RValue1, RValue2, LValue is important - as it is essential for {@link dk.camelot64.kickc.passes.Pass1GenerateSingleStaticAssignmentForm} to create the correct SSA
execute(new ProgramValue.RValue1((StatementAssignment) statement), handler, statement, statementsIt, block);
execute(new ProgramValue.RValue2((StatementAssignment) statement), handler, statement, statementsIt, block);
execute(new ProgramValue.LValue((StatementLValue) statement), handler, statement, statementsIt, block);
} else if(statement instanceof StatementCall) {
StatementCall call = (StatementCall) statement;
if(call.getParameters() != null) {
int size = call.getParameters().size();
for(int i = 0; i < size; i++) {
execute(new ProgramValue.CallParameter(call, i), handler, statement, statementsIt, block);
}
}
execute(new ProgramValue.LValue((StatementLValue) statement), handler, statement, statementsIt, block);
} else if(statement instanceof StatementConditionalJump) {
execute(new ProgramValue.CondRValue1((StatementConditionalJump) statement), handler, statement, statementsIt, block);
execute(new ProgramValue.CondRValue2((StatementConditionalJump) statement), handler, statement, statementsIt, block);
} else if(statement instanceof StatementReturn) {
execute(new ProgramValue.Return((StatementReturn) statement), handler, statement, statementsIt, block);
} else if(statement instanceof StatementPhiBlock) {
for(StatementPhiBlock.PhiVariable phiVariable : ((StatementPhiBlock) statement).getPhiVariables()) {
int size = phiVariable.getValues().size();
for(int i = 0; i < size; i++) {
execute(new ProgramValue.PhiValue(phiVariable, i), handler, statement, statementsIt, block);
}
execute(new ProgramValue.PhiVariable(phiVariable), handler, statement, statementsIt, block);
}
}
}
/**
* Execute the a handler on a value and all sub-values of the value.
*
* @param programValue The programValue value
* @param handler The value handler
*/
public static void execute(ProgramValue programValue, ProgramValueHandler handler, Statement currentStmt, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock) {
handler.execute(programValue, currentStmt, stmtIt, currentBlock);
for(ProgramValue subValue : getSubValues(programValue.get())) {
execute(subValue, handler, currentStmt, stmtIt, currentBlock);
}
}
/**
* Get the sub values for an RValue.
*
* @param value The RValue
* @return The sub-values of the RValue (only one level down, recursion is needed to get all contained sub-values)
*/
private static Collection<ProgramValue> getSubValues(RValue value) {
ArrayList<ProgramValue> subValues = new ArrayList<>();
if(value instanceof PointerDereferenceIndexed) {
subValues.add(new ProgramValue.Pointer((PointerDereference) value));
subValues.add(new ProgramValue.PointerIndex((PointerDereferenceIndexed) value));
} else if(value instanceof PointerDereferenceSimple) {
subValues.add(new ProgramValue.Pointer((PointerDereference) value));
} else if(value instanceof ValueList) {
ValueList valueList = (ValueList) value;
int size = valueList.getList().size();
for(int i = 0; i < size; i++) {
subValues.add(new ProgramValue.ListElement(valueList, i));
}
} else if(value instanceof ConstantArrayList) {
ConstantArrayList constantArrayList = (ConstantArrayList) value;
int size = constantArrayList.getElements().size();
for(int i = 0; i < size; i++) {
subValues.add(new ProgramValue.ConstantArrayElement(constantArrayList, i));
}
} else if(value instanceof CastValue) {
subValues.add(new ProgramValue.CastValue((CastValue) value));
} else if(value instanceof ConstantCastValue) {
subValues.add(new ProgramValue.ConstantCastValue((ConstantCastValue) value));
} else if(value instanceof ConstantVarPointer) {
subValues.add(new ProgramValue.VarPointer((ConstantVarPointer) value));
} else if(value instanceof RangeValue) {
subValues.add(new ProgramValue.RangeFirst((RangeValue) value));
subValues.add(new ProgramValue.RangeLast((RangeValue) value));
} else if(value instanceof ConstantBinary) {
subValues.add(new ProgramValue.ConstantBinaryLeft((ConstantBinary) value));
subValues.add(new ProgramValue.ConstantBinaryRight((ConstantBinary) value));
} else if(value instanceof ConstantUnary) {
subValues.add(new ProgramValue.ConstantUnaryValue((ConstantUnary) value));
} else if(value instanceof ArrayFilled) {
subValues.add(new ProgramValue.ArrayFilledSize((ArrayFilled) value));
} else if(value instanceof ConstantArrayFilled) {
subValues.add(new ProgramValue.ConstantArrayFilledSize((ConstantArrayFilled) value));
} else if(value == null ||
value instanceof VariableRef ||
value instanceof ConstantLiteral ||
value instanceof ConstantRef ||
value instanceof LvalueIntermediate
) {
// No sub values
} else {
throw new RuntimeException("Unhandled value type " + value.getClass());
}
return subValues;
}
}

View File

@ -1,19 +0,0 @@
package dk.camelot64.kickc.model.iterator;
import dk.camelot64.kickc.model.ControlFlowBlock;
import dk.camelot64.kickc.model.statements.Statement;
import java.util.ListIterator;
/** A replacer that receives a replaceable value and has the potential to replace the value or recurse into sub-values. */
public interface Replacer {
/**
* Execute replacement of a replaceable value.
*
* @param replaceable The replaceable value
* @param currentStmt The statement iterator - just past the current statement that the value is a part of. Current statment can be retrieved by calling
* @param stmtIt The statement iterator - just past the current statement. Can be used for modifying the control flow block.
* @param currentBlock The current block that the value is a part of
*/
void execute(ReplaceableValue replaceable, Statement currentStmt, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock);
}

View File

@ -1,147 +0,0 @@
package dk.camelot64.kickc.model.iterator;
import dk.camelot64.kickc.model.*;
import dk.camelot64.kickc.model.values.*;
import dk.camelot64.kickc.model.statements.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.ListIterator;
/**
* A replacer capable to alias all usages of a variable (or constant var) with a suitable replacement
*/
public class ValueReplacer {
/**
* Execute a replacer on all replaceable values in the program control flow graph
*
* @param graph The program control flow graph
* @param replacer The replacer to execute
*/
public static void executeAll(ControlFlowGraph graph, Replacer replacer) {
for(ControlFlowBlock block : graph.getAllBlocks()) {
executeAll(block, replacer);
}
}
/**
* Execute a replacer on all replaceable values in a block of the control flow graph
*
* @param block The control flow graph block
* @param replacer The replacer to execute
*/
public static void executeAll(ControlFlowBlock block, Replacer replacer) {
ListIterator<Statement> statementsIt = block.getStatements().listIterator();
while(statementsIt.hasNext()) {
Statement statement = statementsIt.next();
executeAll(statement, replacer, statementsIt, block);
}
}
/**
* Execute a replacer on all replaceable values in a statement
*
* @param statement The statement
* @param replacer The replacer to execute
*/
public static void executeAll(Statement statement, Replacer replacer, ListIterator<Statement> statementsIt, ControlFlowBlock block) {
if(statement instanceof StatementAssignment) {
// The sequence RValue1, RValue2, LValue is important - as it is essential for {@link dk.camelot64.kickc.passes.Pass1GenerateSingleStaticAssignmentForm} to create the correct SSA
executeAll(new ReplaceableValue.RValue1((StatementAssignment) statement), replacer, statement, statementsIt, block);
executeAll(new ReplaceableValue.RValue2((StatementAssignment) statement), replacer, statement, statementsIt, block);
executeAll(new ReplaceableValue.LValue((StatementLValue) statement), replacer, statement, statementsIt, block);
} else if(statement instanceof StatementCall) {
StatementCall call = (StatementCall) statement;
if(call.getParameters() != null) {
int size = call.getParameters().size();
for(int i = 0; i < size; i++) {
executeAll(new ReplaceableValue.CallParameter(call, i), replacer, statement, statementsIt, block);
}
}
executeAll(new ReplaceableValue.LValue((StatementLValue) statement), replacer, statement, statementsIt, block);
} else if(statement instanceof StatementConditionalJump) {
executeAll(new ReplaceableValue.CondRValue1((StatementConditionalJump) statement), replacer, statement, statementsIt, block);
executeAll(new ReplaceableValue.CondRValue2((StatementConditionalJump) statement), replacer, statement, statementsIt, block);
} else if(statement instanceof StatementReturn) {
executeAll(new ReplaceableValue.Return((StatementReturn) statement), replacer, statement, statementsIt, block);
} else if(statement instanceof StatementPhiBlock) {
for(StatementPhiBlock.PhiVariable phiVariable : ((StatementPhiBlock) statement).getPhiVariables()) {
int size = phiVariable.getValues().size();
for(int i = 0; i < size; i++) {
executeAll(new ReplaceableValue.PhiValue(phiVariable, i), replacer, statement, statementsIt, block);
}
executeAll(new ReplaceableValue.PhiVariable(phiVariable), replacer, statement, statementsIt, block);
}
}
}
/**
* Execute the a replacer on a replaceable value and all sub-values of the value.
*
* @param replaceable The replaceable value
* @param replacer The value replacer
*/
public static void executeAll(ReplaceableValue replaceable, Replacer replacer, Statement currentStmt, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock) {
replacer.execute(replaceable, currentStmt, stmtIt, currentBlock);
for(ReplaceableValue subValue : getSubValues(replaceable.get())) {
executeAll(subValue, replacer, currentStmt, stmtIt, currentBlock);
}
}
/**
* Get the sub values for an RValue.
* @param value The RValue
* @return The sub-values of the RValue (only one level down, recursion is needed to get all contained sub-values)
*/
private static Collection<ReplaceableValue> getSubValues(RValue value) {
ArrayList<ReplaceableValue> subValues = new ArrayList<>();
if(value instanceof PointerDereferenceIndexed) {
subValues.add(new ReplaceableValue.Pointer((PointerDereference) value));
subValues.add(new ReplaceableValue.PointerIndex((PointerDereferenceIndexed) value));
} else if(value instanceof PointerDereferenceSimple) {
subValues.add(new ReplaceableValue.Pointer((PointerDereference) value));
} else if(value instanceof ValueList) {
ValueList valueList = (ValueList) value;
int size = valueList.getList().size();
for(int i = 0; i < size; i++) {
subValues.add(new ReplaceableValue.ListElement(valueList, i));
}
} else if(value instanceof ConstantArrayList) {
ConstantArrayList constantArrayList = (ConstantArrayList) value;
int size = constantArrayList.getElements().size();
for(int i=0;i<size;i++) {
subValues.add(new ReplaceableValue.ConstantArrayElement(constantArrayList, i));
}
} else if(value instanceof CastValue) {
subValues.add(new ReplaceableValue.CastValue((CastValue) value));
} else if(value instanceof ConstantCastValue) {
subValues.add(new ReplaceableValue.ConstantCastValue((ConstantCastValue) value));
} else if(value instanceof ConstantVarPointer) {
subValues.add(new ReplaceableValue.VarPointer((ConstantVarPointer) value));
} else if(value instanceof RangeValue) {
subValues.add(new ReplaceableValue.RangeFirst((RangeValue) value));
subValues.add(new ReplaceableValue.RangeLast((RangeValue) value));
} else if(value instanceof ConstantBinary) {
subValues.add(new ReplaceableValue.ConstantBinaryLeft((ConstantBinary) value));
subValues.add(new ReplaceableValue.ConstantBinaryRight((ConstantBinary) value));
} else if(value instanceof ConstantUnary) {
subValues.add(new ReplaceableValue.ConstantUnaryValue((ConstantUnary) value));
} else if(value instanceof ArrayFilled) {
subValues.add(new ReplaceableValue.ArrayFilledSize((ArrayFilled) value));
} else if(value instanceof ConstantArrayFilled) {
subValues.add(new ReplaceableValue.ConstantArrayFilledSize((ConstantArrayFilled) value));
} else if( value == null ||
value instanceof VariableRef ||
value instanceof ConstantLiteral ||
value instanceof ConstantRef ||
value instanceof LvalueIntermediate
) {
// No sub values
} else {
throw new RuntimeException("Unhandled value type " + value.getClass());
}
return subValues;
}
}

View File

@ -1,8 +1,10 @@
package dk.camelot64.kickc.model.symbols;
import dk.camelot64.kickc.model.*;
import dk.camelot64.kickc.model.values.*;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.Registers;
import dk.camelot64.kickc.model.VariableRegisterWeights;
import dk.camelot64.kickc.model.types.SymbolType;
import dk.camelot64.kickc.model.values.*;
import java.util.*;
@ -185,33 +187,35 @@ public abstract class Scope implements Symbol {
return getConstant(constantRef.getFullName());
}
public Collection<Variable> getAllVariables(boolean includeSubScopes) {
Collection<Variable> vars = new ArrayList<>();
public Collection<SymbolVariable> getAllSymbolVariables(boolean includeSubScopes) {
Collection<SymbolVariable> vars = new ArrayList<>();
for(Symbol symbol : symbols.values()) {
if(symbol instanceof Variable) {
vars.add((Variable) symbol);
if(symbol instanceof SymbolVariable) {
vars.add((SymbolVariable) symbol);
}
if(includeSubScopes && symbol instanceof Scope) {
Scope subScope = (Scope) symbol;
vars.addAll(subScope.getAllVariables(true));
vars.addAll(subScope.getAllSymbolVariables(true));
}
}
return vars;
}
public Collection<ConstantVar> getAllConstants(boolean includeSubScopes) {
Collection<ConstantVar> vars = new ArrayList<>();
for(Symbol symbol : symbols.values()) {
if(symbol instanceof ConstantVar) {
vars.add((ConstantVar) symbol);
}
if(includeSubScopes && symbol instanceof Scope) {
Scope subScope = (Scope) symbol;
vars.addAll(subScope.getAllConstants(true));
}
public Collection<Variable> getAllVariables(boolean includeSubScopes) {
Collection<SymbolVariable> symbolVariables = getAllSymbolVariables(includeSubScopes);
Collection<Variable> vars = new ArrayList<>();
symbolVariables.stream().
filter(symbolVariable -> (symbolVariable instanceof Variable)).
forEach(symbolVariable -> vars.add((Variable) symbolVariable));
return vars;
}
}
public Collection<ConstantVar> getAllConstants(boolean includeSubScopes) {
Collection<SymbolVariable> symbolVariables = getAllSymbolVariables(includeSubScopes);
Collection<ConstantVar> vars = new ArrayList<>();
symbolVariables.stream().
filter(symbolVariable -> (symbolVariable instanceof ConstantVar)).
forEach(symbolVariable -> vars.add((ConstantVar) symbolVariable));
return vars;
}

View File

@ -1,9 +1,9 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.ControlFlowBlock;
import dk.camelot64.kickc.model.iterator.ReplaceableValue;
import dk.camelot64.kickc.model.iterator.Replacer;
import dk.camelot64.kickc.model.iterator.ValueReplacer;
import dk.camelot64.kickc.model.iterator.ProgramValue;
import dk.camelot64.kickc.model.iterator.ProgramValueHandler;
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
import dk.camelot64.kickc.model.statements.Statement;
import dk.camelot64.kickc.model.values.RValue;
import dk.camelot64.kickc.model.values.SymbolRef;
@ -11,8 +11,8 @@ import dk.camelot64.kickc.model.values.SymbolRef;
import java.util.ListIterator;
import java.util.Map;
/** A {@link ValueReplacer} that replaces symbols with their alias. */
public class AliasReplacer implements Replacer {
/** A {@link ProgramValueIterator} that replaces symbols with their alias. */
public class AliasReplacer implements ProgramValueHandler {
/** true if anything has ben replaced. */
@ -31,16 +31,16 @@ public class AliasReplacer implements Replacer {
}
/**
* Execute alias replacement on a replaceable value
* Execute alias replacement on a value
*
* @param replaceable The replaceable value
* @param programValue The value
*/
@Override
public void execute(ReplaceableValue replaceable, Statement currentStmt, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock) {
if(replaceable.get() != null) {
RValue replacement = getReplacement(replaceable.get(), aliases);
public void execute(ProgramValue programValue, Statement currentStmt, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock) {
if(programValue.get() != null) {
RValue replacement = getReplacement(programValue.get(), aliases);
if(replacement != null) {
replaceable.set(replacement);
programValue.set(replacement);
this.replaced = true;
}
}

View File

@ -1,7 +1,7 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.*;
import dk.camelot64.kickc.model.iterator.ValueReplacer;
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
import dk.camelot64.kickc.model.values.ConstantString;
import dk.camelot64.kickc.model.values.RValue;
import dk.camelot64.kickc.model.statements.StatementCall;
@ -23,15 +23,15 @@ public class Pass1ExtractInlineStrings extends Pass1Base {
@Override
public boolean step() {
ValueReplacer.executeAll(getGraph(), (replaceable, currentStmt, stmtIt, currentBlock) -> {
ProgramValueIterator.execute(getGraph(), (programValue, currentStmt, stmtIt, currentBlock) -> {
String nameHint = null;
if(currentStmt instanceof StatementCall) {
StatementCall call = (StatementCall) currentStmt;
List<RValue> parameters = call.getParameters();
for(int i = 0; i < parameters.size(); i++) {
RValue parameter = parameters.get(i);
if(parameter.equals(replaceable.get())) {
// The replaceable value is the parameter - use the parameter name as name hint
if(parameter.equals(programValue.get())) {
// The programValue value is the parameter - use the parameter name as name hint
Procedure procedure = Pass1ExtractInlineStrings.this.getProgram().getScope().getProcedure(call.getProcedure());
nameHint = procedure.getParameterNames().get(i);
break;
@ -39,10 +39,10 @@ public class Pass1ExtractInlineStrings extends Pass1Base {
}
}
Scope blockScope = Pass1ExtractInlineStrings.this.getProgram().getScope().getScope(currentBlock.getScope());
RValue value = replaceable.get();
RValue value = programValue.get();
if(value instanceof ConstantString) {
ConstantVar strConst = Pass1ExtractInlineStrings.this.createStringConstantVar(blockScope, (ConstantString) replaceable.get(), nameHint);
replaceable.set(strConst.getRef());
ConstantVar strConst = Pass1ExtractInlineStrings.this.createStringConstantVar(blockScope, (ConstantString) programValue.get(), nameHint);
programValue.set(strConst.getRef());
}
});
return false;

View File

@ -3,8 +3,8 @@ package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.model.ControlFlowBlock;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.iterator.ReplaceableValue;
import dk.camelot64.kickc.model.iterator.ValueReplacer;
import dk.camelot64.kickc.model.iterator.ProgramValue;
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
import dk.camelot64.kickc.model.statements.Statement;
import dk.camelot64.kickc.model.statements.StatementAssignment;
import dk.camelot64.kickc.model.statements.StatementLValue;
@ -89,14 +89,14 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base {
Map<VariableUnversioned, VariableVersion> blockVersions = new LinkedHashMap<>();
// New phi functions introduced in the block to create versions of variables.
Map<VariableUnversioned, VariableVersion> blockNewPhis = new LinkedHashMap<>();
ValueReplacer.executeAll(block, (replaceable, currentStmt, stmtIt, currentBlock) -> {
RValue value = replaceable.get();
ProgramValueIterator.execute(block, (programValue, currentStmt, stmtIt, currentBlock) -> {
RValue value = programValue.get();
VariableVersion version = findOrCreateVersion(value, blockVersions, blockNewPhis);
if(version != null) {
replaceable.set(version.getRef());
programValue.set(version.getRef());
}
// Update map of versions encountered in the block
if(currentStmt instanceof StatementAssignment && replaceable instanceof ReplaceableValue.LValue) {
if(currentStmt instanceof StatementAssignment && programValue instanceof ProgramValue.LValue) {
StatementAssignment assignment = (StatementAssignment) currentStmt;
LValue lValue = assignment.getlValue();
if(lValue instanceof VariableRef) {

View File

@ -3,9 +3,9 @@ package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.model.ControlFlowBlock;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.iterator.ReplaceableValue;
import dk.camelot64.kickc.model.iterator.Replacer;
import dk.camelot64.kickc.model.iterator.ValueReplacer;
import dk.camelot64.kickc.model.iterator.ProgramValue;
import dk.camelot64.kickc.model.iterator.ProgramValueHandler;
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
import dk.camelot64.kickc.model.statements.*;
import dk.camelot64.kickc.model.symbols.*;
import dk.camelot64.kickc.model.types.SymbolType;
@ -191,7 +191,7 @@ public class Pass1ProcedureInline extends Pass1Base {
throw new CompileError("Statement type of Inline function not handled " + procStatement, procStatement.getSource());
}
if(inlinedStatement!=null) {
ValueReplacer.executeAll(inlinedStatement, new RValueInliner(procedure, serial, callScope), null, null);
ProgramValueIterator.execute(inlinedStatement, new RValueInliner(procedure, serial, callScope), null, null);
}
return inlinedStatement;
}
@ -200,7 +200,7 @@ public class Pass1ProcedureInline extends Pass1Base {
* Ensures that all VariableRefs pointing to variables in the procedure being inlined are converted to refs to the new inlined variables
* Also copies all intermediate RValue objects to ensure they are not references to objects from the original statements in the procedure being inlined
*/
private class RValueInliner implements Replacer {
private class RValueInliner implements ProgramValueHandler {
/** The scope where the precedure is being inlined into. */
private final Scope callScope;
@ -216,24 +216,24 @@ public class Pass1ProcedureInline extends Pass1Base {
}
@Override
public void execute(ReplaceableValue replaceable, Statement currentStmt, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock) {
RValue rValue = replaceable.get();
public void execute(ProgramValue programValue, Statement currentStmt, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock) {
RValue rValue = programValue.get();
if(rValue instanceof VariableRef) {
VariableRef procVarRef = (VariableRef) rValue;
Variable procVar = Pass1ProcedureInline.this.getScope().getVariable(procVarRef);
if(procVar.getScope().equals(procedure)) {
String inlineSymbolName = Pass1ProcedureInline.this.getInlineSymbolName(procedure, procVar, serial);
Variable inlineVar = callScope.getVariable(inlineSymbolName);
replaceable.set(inlineVar.getRef());
programValue.set(inlineVar.getRef());
}
} else if(rValue instanceof PointerDereferenceSimple) {
replaceable.set(new PointerDereferenceSimple(((PointerDereferenceSimple) rValue).getPointer()));
programValue.set(new PointerDereferenceSimple(((PointerDereferenceSimple) rValue).getPointer()));
} else if(rValue instanceof PointerDereferenceIndexed) {
replaceable.set(new PointerDereferenceIndexed(((PointerDereferenceIndexed) rValue).getPointer(), ((PointerDereferenceIndexed) rValue).getIndex()));
programValue.set(new PointerDereferenceIndexed(((PointerDereferenceIndexed) rValue).getPointer(), ((PointerDereferenceIndexed) rValue).getIndex()));
} else if(rValue instanceof CastValue) {
replaceable.set(new CastValue(((CastValue) rValue).getToType(), ((CastValue) rValue).getValue()));
programValue.set(new CastValue(((CastValue) rValue).getToType(), ((CastValue) rValue).getValue()));
} else if(rValue instanceof ValueList) {
replaceable.set(new ValueList(new ArrayList<>(((ValueList) rValue).getList())));
programValue.set(new ValueList(new ArrayList<>(((ValueList) rValue).getList())));
}
}
}

View File

@ -2,7 +2,7 @@ package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.iterator.ValueReplacer;
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
import dk.camelot64.kickc.model.symbols.Scope;
import dk.camelot64.kickc.model.symbols.Variable;
import dk.camelot64.kickc.model.values.ForwardVariableRef;
@ -17,15 +17,15 @@ public class Pass1ResolveForwardReferences extends Pass1Base {
@Override
public boolean step() {
ValueReplacer.executeAll(getGraph(), (replaceable, currentStmt, stmtIt, currentBlock) -> {
RValue rValue = replaceable.get();
ProgramValueIterator.execute(getGraph(), (programValue, currentStmt, stmtIt, currentBlock) -> {
RValue rValue = programValue.get();
if(rValue instanceof ForwardVariableRef) {
String varName = ((ForwardVariableRef) rValue).getName();
Scope currentScope = getScope().getScope(currentBlock.getScope());
Variable variable = currentScope.getVariable(varName);
if(variable!=null) {
getLog().append("Resolved forward reference " + varName+" to "+variable.toString(getProgram()));
replaceable.set(variable.getRef());
programValue.set(variable.getRef());
} else {
getLog().append("ERROR! Unknown variable " + varName);
throw new CompileError("ERROR! Unknown variable " + varName, currentStmt.getSource());

View File

@ -2,7 +2,7 @@ package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.iterator.ValueReplacer;
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
import dk.camelot64.kickc.model.values.ForwardVariableRef;
import dk.camelot64.kickc.model.values.RValue;
import dk.camelot64.kickc.model.values.VariableRef;
@ -16,8 +16,8 @@ public class Pass2AssertRValues extends Pass2SsaAssertion {
@Override
public void check() throws AssertionFailed {
ValueReplacer.executeAll(getGraph(), (replaceable, currentStmt, stmtIt, currentBlock) -> {
RValue rValue = replaceable.get();
ProgramValueIterator.execute(getGraph(), (programValue, currentStmt, stmtIt, currentBlock) -> {
RValue rValue = programValue.get();
if(rValue instanceof ForwardVariableRef) {
throw new CompileError("No forward references allowed "+currentStmt.toString(getProgram(), false), currentStmt.getSource());
}

View File

@ -1,7 +1,7 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.*;
import dk.camelot64.kickc.model.iterator.ReplaceableValue;
import dk.camelot64.kickc.model.iterator.ProgramValue;
import dk.camelot64.kickc.model.operators.Operator;
import dk.camelot64.kickc.model.operators.Operators;
import dk.camelot64.kickc.model.values.*;
@ -46,13 +46,13 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
if(statement instanceof StatementAssignment) {
StatementAssignment assignment = (StatementAssignment) statement;
if(assignment.getlValue() instanceof PointerDereferenceIndexed) {
optimized |= optimizePointerDereferenceIndexed(new ReplaceableValue.LValue(assignment));
optimized |= optimizePointerDereferenceIndexed(new ProgramValue.LValue(assignment));
}
if(assignment.getrValue1() instanceof PointerDereferenceIndexed) {
optimized |= optimizePointerDereferenceIndexed(new ReplaceableValue.RValue1(assignment));
optimized |= optimizePointerDereferenceIndexed(new ProgramValue.RValue1(assignment));
}
if(assignment.getrValue2() instanceof PointerDereferenceIndexed) {
optimized |= optimizePointerDereferenceIndexed(new ReplaceableValue.RValue2(assignment));
optimized |= optimizePointerDereferenceIndexed(new ProgramValue.RValue2(assignment));
}
Operator operator = assignment.getOperator();
@ -69,10 +69,10 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
} else if(statement instanceof StatementConditionalJump) {
StatementConditionalJump jump = (StatementConditionalJump) statement;
if(jump.getrValue1() instanceof PointerDereferenceIndexed) {
optimized |= optimizePointerDereferenceIndexed(new ReplaceableValue.CondRValue1(jump));
optimized |= optimizePointerDereferenceIndexed(new ProgramValue.CondRValue1(jump));
}
if(jump.getrValue2() instanceof PointerDereferenceIndexed) {
optimized |= optimizePointerDereferenceIndexed(new ReplaceableValue.CondRValue2(jump));
optimized |= optimizePointerDereferenceIndexed(new ProgramValue.CondRValue2(jump));
}
}
}
@ -80,7 +80,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization {
return optimized;
}
private boolean optimizePointerDereferenceIndexed(ReplaceableValue value) {
private boolean optimizePointerDereferenceIndexed(ProgramValue value) {
PointerDereferenceIndexed pointerDereferenceIndexed = (PointerDereferenceIndexed) value.get();
if(pointerDereferenceIndexed.getPointer() instanceof ConstantValue && pointerDereferenceIndexed.getIndex() instanceof ConstantValue) {
ConstantValue ptrConstant = (ConstantValue) pointerDereferenceIndexed.getPointer();

View File

@ -1,9 +1,8 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.*;
import dk.camelot64.kickc.model.iterator.ReplaceableValue;
import dk.camelot64.kickc.model.iterator.ValueReplacer;
import dk.camelot64.kickc.model.types.SymbolTypeArray;
import dk.camelot64.kickc.model.iterator.ProgramValue;
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
import dk.camelot64.kickc.model.values.*;
import dk.camelot64.kickc.model.symbols.ConstantVar;
import dk.camelot64.kickc.model.symbols.ProgramScope;
@ -64,28 +63,6 @@ public class Pass2ConstantInlining extends Pass2SsaOptimization {
}
/**
* Replace any alias within the constant defintions inside the symbol table
*
* @param inline The replacements to make
*/
private void replaceInSymbolTable(Map<ConstantRef, ConstantValue> inline) {
Collection<ConstantVar> allConstants = getProgram().getScope().getAllConstants(true);
for(ConstantVar constantVar : allConstants) {
// First check if the type is an array - and replace inside the type if it is
SymbolType constantType = constantVar.getType();
if(constantType instanceof SymbolTypeArray) {
SymbolTypeArray arrayType = (SymbolTypeArray) constantType;
ReplaceableValue.TypeArraySize replaceableArrayType = new ReplaceableValue.TypeArraySize(arrayType);
ValueReplacer.executeAll(replaceableArrayType, new AliasReplacer(inline), null, null, null);
}
ReplaceableValue.ConstantVariableValue replaceableConstantVal = new ReplaceableValue.ConstantVariableValue(constantVar);
ValueReplacer.executeAll(replaceableConstantVal, new AliasReplacer(inline), null, null, null);
}
}
/**
* Replace any aliases within the constant values themselves
*
@ -97,16 +74,25 @@ public class Pass2ConstantInlining extends Pass2SsaOptimization {
replaced = false;
for(ConstantRef constantRef : inline.keySet()) {
ConstantValue constantValue = inline.get(constantRef);
ReplaceableValue.GenericValue replaceable = new ReplaceableValue.GenericValue(constantValue);
ProgramValue.GenericValue genericValue = new ProgramValue.GenericValue(constantValue);
AliasReplacer replacer = new AliasReplacer(inline);
ValueReplacer.executeAll(replaceable, replacer, null, null, null);
ProgramValueIterator.execute(genericValue, replacer, null, null, null);
if(replacer.isReplaced()) {
inline.put(constantRef, (ConstantValue) replaceable.get());
inline.put(constantRef, (ConstantValue) genericValue.get());
}
}
}
}
/**
* Replace any alias within the constant defintions inside the symbol table
*
* @param inline The replacements to make
*/
private void replaceInSymbolTable(Map<ConstantRef, ConstantValue> inline) {
ProgramValueIterator.execute(getScope(), new AliasReplacer(inline));
}
/**
* Find all unnamed constants $1 = VIC+$20
*

View File

@ -1,9 +1,9 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.*;
import dk.camelot64.kickc.model.iterator.ReplaceableValue;
import dk.camelot64.kickc.model.iterator.Replacer;
import dk.camelot64.kickc.model.iterator.ValueReplacer;
import dk.camelot64.kickc.model.iterator.ProgramValue;
import dk.camelot64.kickc.model.iterator.ProgramValueHandler;
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
import dk.camelot64.kickc.model.operators.Operator;
import dk.camelot64.kickc.model.operators.Operators;
import dk.camelot64.kickc.model.values.RValue;
@ -32,9 +32,9 @@ public class Pass2FixInlineConstructors extends Pass2SsaOptimization {
@Override
public boolean step() {
WordConstructor wordConstructor = new WordConstructor();
ValueReplacer.executeAll(getGraph(), wordConstructor);
ProgramValueIterator.execute(getGraph(), wordConstructor);
DWordConstructor dwordConstructor = new DWordConstructor();
ValueReplacer.executeAll(getGraph(), dwordConstructor);
ProgramValueIterator.execute(getGraph(), dwordConstructor);
return wordConstructor.isOptimized() || dwordConstructor.isOptimized();
}
@ -65,7 +65,7 @@ public class Pass2FixInlineConstructors extends Pass2SsaOptimization {
}
private abstract class InlineConstructor implements Replacer {
private abstract class InlineConstructor implements ProgramValueHandler {
private SymbolTypeInteger constructType;
private Operator constructOperator;
private boolean optimized;
@ -82,8 +82,8 @@ public class Pass2FixInlineConstructors extends Pass2SsaOptimization {
}
@Override
public void execute(ReplaceableValue replaceable, Statement currentStmt, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock) {
RValue rValue = replaceable.get();
public void execute(ProgramValue programValue, Statement currentStmt, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock) {
RValue rValue = programValue.get();
if(rValue instanceof ValueList) {
ValueList list = (ValueList) rValue;
if(list.getList().size() == 2) {
@ -117,7 +117,7 @@ public class Pass2FixInlineConstructors extends Pass2SsaOptimization {
// Move back before the current statement
stmtIt.next();
// Replace current value with the reference
replaceable.set(tmpVar.getRef());
programValue.set(tmpVar.getRef());
Pass2FixInlineConstructors.this.getLog().append("Fixing inline constructor with " + assignment.toString());
optimized = true;
}

View File

@ -2,7 +2,7 @@ package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.iterator.ValueReplacer;
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
import dk.camelot64.kickc.model.operators.Operators;
import dk.camelot64.kickc.model.statements.StatementAssignment;
import dk.camelot64.kickc.model.types.SymbolType;
@ -29,8 +29,8 @@ public class Pass2RangeResolving extends Pass2SsaOptimization {
public boolean step() {
boolean modified = false;
ValueReplacer.executeAll(getProgram().getGraph(), (replaceable, currentStmt, stmtIt, currentBlock) -> {
RValue value = replaceable.get();
ProgramValueIterator.execute(getProgram().getGraph(), (programValue, currentStmt, stmtIt, currentBlock) -> {
RValue value = programValue.get();
if(value instanceof RangeValue) {
RangeValue rangeValue = (RangeValue) value;
if(rangeValue.getRangeFirst() instanceof ConstantValue && rangeValue.getRangeLast() instanceof ConstantValue) {
@ -81,7 +81,7 @@ public class Pass2RangeResolving extends Pass2SsaOptimization {
beyondLastVal = new ConstantCastValue(type, beyondLastVal );
}
getLog().append("Resolved ranged comparison value "+currentStmt+" to "+beyondLastVal.toString(getProgram()));
replaceable.set(beyondLastVal);
programValue.set(beyondLastVal);
} else if(rangeValue instanceof RangeNext) {
StatementAssignment assignment = (StatementAssignment) currentStmt;
if(firstInt <= lastInt) {

View File

@ -1,7 +1,7 @@
package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.*;
import dk.camelot64.kickc.model.iterator.ValueReplacer;
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
import dk.camelot64.kickc.model.values.*;
import dk.camelot64.kickc.model.statements.*;
import dk.camelot64.kickc.model.symbols.Symbol;
@ -46,8 +46,7 @@ public abstract class Pass2SsaOptimization extends Pass1Base {
* @param aliases Variables that have alias values.
*/
public void replaceVariables(final Map<? extends SymbolRef, ? extends RValue> aliases) {
AliasReplacer replacer = new AliasReplacer(aliases);
ValueReplacer.executeAll(getGraph(), replacer);
ProgramValueIterator.execute(getGraph(), new AliasReplacer(aliases));
}
/**

View File

@ -2,7 +2,7 @@ package dk.camelot64.kickc.passes;
import dk.camelot64.kickc.model.CompileError;
import dk.camelot64.kickc.model.Program;
import dk.camelot64.kickc.model.iterator.ValueReplacer;
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
import dk.camelot64.kickc.model.values.RValue;
import dk.camelot64.kickc.model.values.RangeValue;
import dk.camelot64.kickc.model.values.ValueList;
@ -21,8 +21,8 @@ public class Pass3AssertRValues extends Pass2SsaAssertion {
@Override
public void check() throws AssertionFailed {
ValueReplacer.executeAll(getGraph(), (replaceable, currentStmt, stmtIt, currentBlock) -> {
RValue value = replaceable.get();
ProgramValueIterator.execute(getGraph(), (programValue, currentStmt, stmtIt, currentBlock) -> {
RValue value = programValue.get();
if(value instanceof ValueList) {
throw new CompileError(
"Error! Value list not resolved to word constructor or array initializer" +