diff --git a/src/main/java/dk/camelot64/kickc/model/iterator/ReplaceableValue.java b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValue.java similarity index 77% rename from src/main/java/dk/camelot64/kickc/model/iterator/ReplaceableValue.java rename to src/main/java/dk/camelot64/kickc/model/iterator/ProgramValue.java index fc08cb3fb..b2c70f3e3 100644 --- a/src/main/java/dk/camelot64/kickc/model/iterator/ReplaceableValue.java +++ b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValue.java @@ -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) { diff --git a/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValueHandler.java b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValueHandler.java new file mode 100644 index 000000000..7fe244e05 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValueHandler.java @@ -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 stmtIt, ControlFlowBlock currentBlock); + +} diff --git a/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValueIterator.java b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValueIterator.java new file mode 100644 index 000000000..dadf6a6a3 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/model/iterator/ProgramValueIterator.java @@ -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 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 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 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 getSubValues(RValue value) { + ArrayList 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; + } + +} diff --git a/src/main/java/dk/camelot64/kickc/model/iterator/Replacer.java b/src/main/java/dk/camelot64/kickc/model/iterator/Replacer.java deleted file mode 100644 index 18215ae75..000000000 --- a/src/main/java/dk/camelot64/kickc/model/iterator/Replacer.java +++ /dev/null @@ -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 stmtIt, ControlFlowBlock currentBlock); -} diff --git a/src/main/java/dk/camelot64/kickc/model/iterator/ValueReplacer.java b/src/main/java/dk/camelot64/kickc/model/iterator/ValueReplacer.java deleted file mode 100644 index dc6c999fd..000000000 --- a/src/main/java/dk/camelot64/kickc/model/iterator/ValueReplacer.java +++ /dev/null @@ -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 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 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 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 getSubValues(RValue value) { - ArrayList 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 getAllVariables(boolean includeSubScopes) { - Collection vars = new ArrayList<>(); + public Collection getAllSymbolVariables(boolean includeSubScopes) { + Collection 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 getAllConstants(boolean includeSubScopes) { - Collection 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 getAllVariables(boolean includeSubScopes) { + Collection symbolVariables = getAllSymbolVariables(includeSubScopes); + Collection vars = new ArrayList<>(); + symbolVariables.stream(). + filter(symbolVariable -> (symbolVariable instanceof Variable)). + forEach(symbolVariable -> vars.add((Variable) symbolVariable)); + return vars; + } - } + public Collection getAllConstants(boolean includeSubScopes) { + Collection symbolVariables = getAllSymbolVariables(includeSubScopes); + Collection vars = new ArrayList<>(); + symbolVariables.stream(). + filter(symbolVariable -> (symbolVariable instanceof ConstantVar)). + forEach(symbolVariable -> vars.add((ConstantVar) symbolVariable)); return vars; } diff --git a/src/main/java/dk/camelot64/kickc/passes/AliasReplacer.java b/src/main/java/dk/camelot64/kickc/passes/AliasReplacer.java index 6256c2c5c..dd3707ec1 100644 --- a/src/main/java/dk/camelot64/kickc/passes/AliasReplacer.java +++ b/src/main/java/dk/camelot64/kickc/passes/AliasReplacer.java @@ -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 stmtIt, ControlFlowBlock currentBlock) { - if(replaceable.get() != null) { - RValue replacement = getReplacement(replaceable.get(), aliases); + public void execute(ProgramValue programValue, Statement currentStmt, ListIterator 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; } } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1ExtractInlineStrings.java b/src/main/java/dk/camelot64/kickc/passes/Pass1ExtractInlineStrings.java index 338131830..bde3c3ace 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass1ExtractInlineStrings.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass1ExtractInlineStrings.java @@ -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 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; diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1GenerateSingleStaticAssignmentForm.java b/src/main/java/dk/camelot64/kickc/passes/Pass1GenerateSingleStaticAssignmentForm.java index 84e61bdd1..62e484011 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass1GenerateSingleStaticAssignmentForm.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass1GenerateSingleStaticAssignmentForm.java @@ -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 blockVersions = new LinkedHashMap<>(); // New phi functions introduced in the block to create versions of variables. Map 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) { diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1ProcedureInline.java b/src/main/java/dk/camelot64/kickc/passes/Pass1ProcedureInline.java index e50342a85..b17d74724 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass1ProcedureInline.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass1ProcedureInline.java @@ -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 stmtIt, ControlFlowBlock currentBlock) { - RValue rValue = replaceable.get(); + public void execute(ProgramValue programValue, Statement currentStmt, ListIterator 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()))); } } } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1ResolveForwardReferences.java b/src/main/java/dk/camelot64/kickc/passes/Pass1ResolveForwardReferences.java index ab72f67e4..95b57cfcd 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass1ResolveForwardReferences.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass1ResolveForwardReferences.java @@ -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()); diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2AssertRValues.java b/src/main/java/dk/camelot64/kickc/passes/Pass2AssertRValues.java index 69e4b6dd4..18bfeed1c 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2AssertRValues.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2AssertRValues.java @@ -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()); } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantAdditionElimination.java b/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantAdditionElimination.java index 0272258b7..1034cd2c4 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantAdditionElimination.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantAdditionElimination.java @@ -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(); diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantInlining.java b/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantInlining.java index 9fbd3a8dd..6307a7242 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantInlining.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantInlining.java @@ -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 inline) { - Collection 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 inline) { + ProgramValueIterator.execute(getScope(), new AliasReplacer(inline)); + } + /** * Find all unnamed constants $1 = VIC+$20 * diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2FixInlineConstructors.java b/src/main/java/dk/camelot64/kickc/passes/Pass2FixInlineConstructors.java index 90ee1d7f3..51114999c 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2FixInlineConstructors.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2FixInlineConstructors.java @@ -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 stmtIt, ControlFlowBlock currentBlock) { - RValue rValue = replaceable.get(); + public void execute(ProgramValue programValue, Statement currentStmt, ListIterator 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; } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2RangeResolving.java b/src/main/java/dk/camelot64/kickc/passes/Pass2RangeResolving.java index 3fe447174..830ced048 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2RangeResolving.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2RangeResolving.java @@ -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) { diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2SsaOptimization.java b/src/main/java/dk/camelot64/kickc/passes/Pass2SsaOptimization.java index d02fbc865..39a7ecf34 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2SsaOptimization.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2SsaOptimization.java @@ -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 aliases) { - AliasReplacer replacer = new AliasReplacer(aliases); - ValueReplacer.executeAll(getGraph(), replacer); + ProgramValueIterator.execute(getGraph(), new AliasReplacer(aliases)); } /** diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass3AssertRValues.java b/src/main/java/dk/camelot64/kickc/passes/Pass3AssertRValues.java index 5254ab80d..2c4e58ce8 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass3AssertRValues.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass3AssertRValues.java @@ -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" +