From f9449997cb8d56e66de7ca0ac36047d8b965bd52 Mon Sep 17 00:00:00 2001 From: Jesper Gravgaard Date: Sat, 21 Jul 2018 23:29:11 +0900 Subject: [PATCH] Refacing ValueReplacer --- .../model/iterator/ReplaceableValue.java | 469 ++++++++++++++ .../kickc/model/iterator/Replacer.java | 19 + .../kickc/model/iterator/ValueReplacer.java | 125 ++++ .../camelot64/kickc/passes/AliasReplacer.java | 7 +- .../passes/Pass1ExtractInlineStrings.java | 1 + ...ss1GenerateSingleStaticAssignmentForm.java | 23 +- .../kickc/passes/Pass1ProcedureInline.java | 7 +- .../passes/Pass1ResolveForwardReferences.java | 1 + .../kickc/passes/Pass2AssertRValues.java | 1 + .../Pass2ConstantAdditionElimination.java | 13 +- .../passes/Pass2FixInlineConstructors.java | 7 +- .../kickc/passes/Pass2RangeResolving.java | 1 + .../kickc/passes/Pass2SsaOptimization.java | 1 + .../kickc/passes/Pass3AssertRValues.java | 1 + .../camelot64/kickc/passes/ValueReplacer.java | 603 ------------------ 15 files changed, 653 insertions(+), 626 deletions(-) create mode 100644 src/main/java/dk/camelot64/kickc/model/iterator/ReplaceableValue.java create mode 100644 src/main/java/dk/camelot64/kickc/model/iterator/Replacer.java create mode 100644 src/main/java/dk/camelot64/kickc/model/iterator/ValueReplacer.java delete mode 100644 src/main/java/dk/camelot64/kickc/passes/ValueReplacer.java diff --git a/src/main/java/dk/camelot64/kickc/model/iterator/ReplaceableValue.java b/src/main/java/dk/camelot64/kickc/model/iterator/ReplaceableValue.java new file mode 100644 index 000000000..ff7064391 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/model/iterator/ReplaceableValue.java @@ -0,0 +1,469 @@ +package dk.camelot64.kickc.model.iterator; + +import dk.camelot64.kickc.model.statements.*; +import dk.camelot64.kickc.model.values.*; + +import java.util.Collection; + +/** + * Interface representing an RValue that can be replaced. + * The value may have sub-values that can also be replaced. + */ +public abstract class ReplaceableValue { + + public abstract RValue get(); + + public abstract void set(RValue value); + + /** Replaceable value inside a array filled expression. */ + public static class ArrayFilledSize extends ReplaceableValue { + private final ArrayFilled array; + + ArrayFilledSize(ArrayFilled array) { + this.array = array; + } + + @Override + public RValue get() { + return array.getSize(); + } + + @Override + public void set(RValue val) { + array.setSize(val); + } + + } + + /** Replaceable value inside a constant array filled expression. */ + public static class ConstantArrayFilledSize extends ReplaceableValue { + private final ConstantArrayFilled array; + + ConstantArrayFilledSize(ConstantArrayFilled array) { + this.array = array; + } + + @Override + public RValue get() { + return array.getSize(); + } + + @Override + public void set(RValue val) { + array.setSize((ConstantValue) val); + } + + } + + /** Replaceable value inside a constant unary expression. */ + public static class ConstantUnaryValue extends ReplaceableValue { + private final ConstantUnary unary; + + ConstantUnaryValue(ConstantUnary unary) { + this.unary = unary; + } + + @Override + public RValue get() { + return unary.getOperand(); + } + + @Override + public void set(RValue val) { + unary.setOperand((ConstantValue) val); + } + + } + + /** Replaceable left value inside a constant binary expression. */ + public static class ConstantBinaryLeft extends ReplaceableValue { + private final ConstantBinary binary; + + ConstantBinaryLeft(ConstantBinary binary) { + this.binary = binary; + } + + @Override + public RValue get() { + return binary.getLeft(); + } + + @Override + public void set(RValue val) { + binary.setLeft((ConstantValue) val); + } + + } + + /** Replaceable right value inside a constant binary expression. */ + public static class ConstantBinaryRight extends ReplaceableValue { + private final ConstantBinary binary; + + ConstantBinaryRight(ConstantBinary range) { + this.binary = range; + } + + @Override + public RValue get() { + return binary.getRight(); + } + + @Override + public void set(RValue val) { + binary.setRight((ConstantValue) val); + } + + } + + /** + * Replaceable first value inside a ranged comparison value. + */ + public static class RangeFirst extends ReplaceableValue { + private final RangeValue range; + + RangeFirst(RangeValue range) { + this.range = range; + } + + @Override + public RValue get() { + return range.getRangeFirst(); + } + + @Override + public void set(RValue val) { + range.setRangeFirst(val); + } + + } + + /** + * Replaceable last value inside inside a ranged comparison value. + */ + public static class RangeLast extends ReplaceableValue { + private final RangeValue range; + + RangeLast(RangeValue range) { + this.range = range; + } + + @Override + public RValue get() { + return range.getRangeLast(); + } + + @Override + public void set(RValue val) { + range.setRangeLast(val); + } + + } + + /** + * Replaceable LValue as part of an assignment statement (or a call). + */ + public static class LValue extends ReplaceableValue { + private final StatementLValue statement; + + public LValue(StatementLValue statement) { + this.statement = statement; + } + + @Override + public RValue get() { + return statement.getlValue(); + } + + @Override + public void set(RValue value) { + statement.setlValue((dk.camelot64.kickc.model.values.LValue) value); + } + + } + + /** + * Replaceable pointer inside a pointer dererence value. + */ + public static class Pointer extends ReplaceableValue { + private final PointerDereference pointer; + + Pointer(PointerDereference pointer) { + this.pointer = pointer; + } + + @Override + public RValue get() { + return pointer.getPointer(); + } + + @Override + public void set(RValue val) { + pointer.setPointer(val); + } + + } + + /** + * Replaceable value inside a noop cast. + */ + public static class CastValue extends ReplaceableValue { + private final dk.camelot64.kickc.model.values.CastValue castValue; + + + public CastValue(dk.camelot64.kickc.model.values.CastValue castValue) { + this.castValue = castValue; + } + + @Override + public RValue get() { + return castValue.getValue(); + } + + @Override + public void set(RValue val) { + castValue.setValue(val); + } + + } + + /** + * Replaceable value inside a constant noop cast. + */ + public static class ConstantCastValue extends ReplaceableValue { + private final dk.camelot64.kickc.model.values.ConstantCastValue castValue; + + + public ConstantCastValue(dk.camelot64.kickc.model.values.ConstantCastValue castValue) { + this.castValue = castValue; + } + + @Override + public RValue get() { + return castValue.getValue(); + } + + @Override + public void set(RValue val) { + castValue.setValue((ConstantValue) val); + } + + } + + /** + * Replaceable pointer inside a variable pointer. + */ + public static class VarPointer extends ReplaceableValue { + private final ConstantVarPointer varPointer; + + + public VarPointer(ConstantVarPointer varPointer) { + this.varPointer = varPointer; + } + + @Override + public RValue get() { + return varPointer.getToVar(); + } + + @Override + public void set(RValue val) { + varPointer.setToVar((VariableRef) val); + } + + } + + public static class ListElement extends ReplaceableValue { + private ValueList list; + private int idx; + + public ListElement(ValueList list, int idx) { + this.list = list; + this.idx = idx; + } + + @Override + public RValue get() { + return list.getList().get(idx); + } + + @Override + public void set(RValue value) { + list.getList().set(idx, value); + } + + } + + /** + * Replaceable pointer index inside a indexed pointer dererence value. + */ + public static class PointerIndex extends ReplaceableValue { + private final PointerDereferenceIndexed pointer; + + PointerIndex(PointerDereferenceIndexed pointer) { + this.pointer = pointer; + } + + @Override + public RValue get() { + return pointer.getIndex(); + } + + @Override + public void set(RValue val) { + pointer.setIndex(val); + } + + } + + public static class RValue1 extends ReplaceableValue { + private final StatementAssignment statement; + + public RValue1(StatementAssignment statement) { + this.statement = statement; + } + + @Override + public RValue get() { + return statement.getrValue1(); + } + + @Override + public void set(RValue value) { + statement.setrValue1(value); + } + } + + public static class RValue2 extends ReplaceableValue { + private final StatementAssignment statement; + + public RValue2(StatementAssignment statement) { + this.statement = statement; + } + + @Override + public RValue get() { + return statement.getrValue2(); + } + + @Override + public void set(RValue value) { + statement.setrValue2(value); + } + } + + public static class CallParameter extends ReplaceableValue { + private final StatementCall call; + private final int i; + + public CallParameter(StatementCall call, int i) { + this.call = call; + this.i = i; + } + + @Override + public RValue get() { + return call.getParameters().get(i); + } + + @Override + public void set(RValue value) { + call.getParameters().set(i, value); + } + } + + public static class CondRValue1 extends ReplaceableValue { + private final StatementConditionalJump statement; + + public CondRValue1(StatementConditionalJump statement) { + this.statement = statement; + } + + @Override + public RValue get() { + return statement.getrValue1(); + } + + @Override + public void set(RValue value) { + statement.setrValue1(value); + } + } + + public static class CondRValue2 extends ReplaceableValue { + private final StatementConditionalJump statement; + + public CondRValue2(StatementConditionalJump statement) { + this.statement = statement; + } + + @Override + public RValue get() { + return statement.getrValue2(); + } + + @Override + public void set(RValue value) { + statement.setrValue2(value); + } + } + + public static class Return extends ReplaceableValue { + private final StatementReturn statement; + + public Return(StatementReturn statement) { + this.statement = statement; + } + + @Override + public RValue get() { + return statement.getValue(); + } + + @Override + public void set(RValue value) { + statement.setValue(value); + } + } + + public static class PhiValue extends ReplaceableValue { + private final StatementPhiBlock.PhiVariable phiVariable; + private final int i; + + public PhiValue(StatementPhiBlock.PhiVariable phiVariable, int i) { + this.phiVariable = phiVariable; + this.i = i; + } + + @Override + public RValue get() { + return phiVariable.getValues().get(i).getrValue(); + } + + @Override + public void set(RValue value) { + phiVariable.getValues().get(i).setrValue(value); + } + } + + /** + * Replaceable LValue as part of an assignment statement (or a call). + */ + public static class PhiVariable extends ReplaceableValue { + private final StatementPhiBlock.PhiVariable phiVariable; + + public PhiVariable(StatementPhiBlock.PhiVariable phiVariable) { + this.phiVariable = phiVariable; + } + + @Override + public RValue get() { + return phiVariable.getVariable(); + } + + @Override + public void set(RValue value) { + phiVariable.setVariable((VariableRef) value); + } + + } +} diff --git a/src/main/java/dk/camelot64/kickc/model/iterator/Replacer.java b/src/main/java/dk/camelot64/kickc/model/iterator/Replacer.java new file mode 100644 index 000000000..18215ae75 --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/model/iterator/Replacer.java @@ -0,0 +1,19 @@ +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 new file mode 100644 index 000000000..312cf7f3b --- /dev/null +++ b/src/main/java/dk/camelot64/kickc/model/iterator/ValueReplacer.java @@ -0,0 +1,125 @@ +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()) { + 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) { + executeAll(new ReplaceableValue.LValue((StatementLValue) statement), replacer, statement, statementsIt, block); + executeAll(new ReplaceableValue.RValue1((StatementAssignment) statement), replacer, statement, statementsIt, block); + executeAll(new ReplaceableValue.RValue2((StatementAssignment) statement), replacer, statement, statementsIt, block); + } else if(statement instanceof StatementCall) { + executeAll(new ReplaceableValue.LValue((StatementLValue) statement), replacer, statement, statementsIt, block); + 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); + } + } + } 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()) { + executeAll(new ReplaceableValue.PhiVariable(phiVariable), replacer, statement, statementsIt, block); + int size = phiVariable.getValues().size(); + for(int i = 0; i < size; i++) { + executeAll(new ReplaceableValue.PhiValue(phiVariable, i), 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); + } + } + + public 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 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; + } + +} diff --git a/src/main/java/dk/camelot64/kickc/passes/AliasReplacer.java b/src/main/java/dk/camelot64/kickc/passes/AliasReplacer.java index 05c2e3d8b..eda6229b7 100644 --- a/src/main/java/dk/camelot64/kickc/passes/AliasReplacer.java +++ b/src/main/java/dk/camelot64/kickc/passes/AliasReplacer.java @@ -1,6 +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.values.*; import dk.camelot64.kickc.model.statements.Statement; @@ -9,7 +12,7 @@ import java.util.ListIterator; import java.util.Map; /** A {@link ValueReplacer} that replaces symbols with their alias. */ -public class AliasReplacer implements ValueReplacer.Replacer { +public class AliasReplacer implements Replacer { private Map aliases; @@ -99,7 +102,7 @@ public class AliasReplacer implements ValueReplacer.Replacer { * @param replaceable The replaceable value */ @Override - public void execute(ValueReplacer.ReplaceableValue replaceable, Statement currentStmt, ListIterator stmtIt, ControlFlowBlock currentBlock) { + public void execute(ReplaceableValue replaceable, Statement currentStmt, ListIterator stmtIt, ControlFlowBlock currentBlock) { if(replaceable.get() != null) { RValue replacement = getReplacement(replaceable.get(), aliases); if(replacement != null) { diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1ExtractInlineStrings.java b/src/main/java/dk/camelot64/kickc/passes/Pass1ExtractInlineStrings.java index 8d2d20888..338131830 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass1ExtractInlineStrings.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass1ExtractInlineStrings.java @@ -1,6 +1,7 @@ package dk.camelot64.kickc.passes; import dk.camelot64.kickc.model.*; +import dk.camelot64.kickc.model.iterator.ValueReplacer; import dk.camelot64.kickc.model.values.ConstantString; import dk.camelot64.kickc.model.values.RValue; import dk.camelot64.kickc.model.statements.StatementCall; diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1GenerateSingleStaticAssignmentForm.java b/src/main/java/dk/camelot64/kickc/passes/Pass1GenerateSingleStaticAssignmentForm.java index 388f68edd..c66222836 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass1GenerateSingleStaticAssignmentForm.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass1GenerateSingleStaticAssignmentForm.java @@ -1,7 +1,8 @@ package dk.camelot64.kickc.passes; import dk.camelot64.kickc.model.*; -import dk.camelot64.kickc.model.values.LValue; +import dk.camelot64.kickc.model.iterator.ReplaceableValue; +import dk.camelot64.kickc.model.iterator.ValueReplacer; import dk.camelot64.kickc.model.values.LabelRef; import dk.camelot64.kickc.model.values.RValue; import dk.camelot64.kickc.model.values.VariableRef; @@ -47,7 +48,7 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base { for(Statement statement : block.getStatements()) { if(statement instanceof StatementLValue) { StatementLValue statementLValue = (StatementLValue) statement; - LValue lValue = statementLValue.getlValue(); + dk.camelot64.kickc.model.values.LValue lValue = statementLValue.getlValue(); if(lValue instanceof VariableRef) { VariableRef lValueRef = (VariableRef) lValue; Variable assignedVar = getScope().getVariable(lValueRef); @@ -81,7 +82,7 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base { * @param blockNewPhis New phi functions introduced in the block to create versions of variables. */ private void execute( - ValueReplacer.ReplaceableValue replaceableValue, + ReplaceableValue replaceableValue, Map blockVersions, Map blockNewPhis) { RValue value = replaceableValue.get(); @@ -89,7 +90,7 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base { if(version != null) { replaceableValue.set(version.getRef()); } - for(ValueReplacer.ReplaceableValue subValue : replaceableValue.getSubValues()) { + for(ReplaceableValue subValue : ValueReplacer.getSubValues(replaceableValue.get())) { execute(subValue, blockVersions, blockNewPhis); } } @@ -105,17 +106,17 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base { Map blockNewPhis = new LinkedHashMap<>(); for(Statement statement : block.getStatements()) { if(statement instanceof StatementReturn) { - execute(new ValueReplacer.ReplaceableReturn((StatementReturn) statement), blockVersions, blockNewPhis); + execute(new ReplaceableValue.Return((StatementReturn) statement), blockVersions, blockNewPhis); } else if(statement instanceof StatementConditionalJump) { - execute(new ValueReplacer.ReplaceableCondRValue2((StatementConditionalJump) statement), blockVersions, blockNewPhis); + execute(new ReplaceableValue.CondRValue2((StatementConditionalJump) statement), blockVersions, blockNewPhis); } else if(statement instanceof StatementAssignment) { StatementAssignment assignment = (StatementAssignment) statement; - execute(new ValueReplacer.ReplaceableRValue1(assignment), blockVersions, blockNewPhis); - execute(new ValueReplacer.ReplaceableRValue2(assignment), blockVersions, blockNewPhis); - execute(new ValueReplacer.ReplaceableLValue(assignment), blockVersions, blockNewPhis); + execute(new ReplaceableValue.RValue1(assignment), blockVersions, blockNewPhis); + execute(new ReplaceableValue.RValue2(assignment), blockVersions, blockNewPhis); + execute(new ReplaceableValue.LValue(assignment), blockVersions, blockNewPhis); // Update map of versions encountered in the block - LValue lValue = assignment.getlValue(); + dk.camelot64.kickc.model.values.LValue lValue = assignment.getlValue(); if(lValue instanceof VariableRef) { VariableRef lValueRef = (VariableRef) lValue; Variable variable = getScope().getVariable(lValueRef); @@ -260,7 +261,7 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base { return symbolMap; } - private void addSymbolToMap(Map> symbolMap, ControlFlowBlock block, LValue lValue) { + private void addSymbolToMap(Map> symbolMap, ControlFlowBlock block, dk.camelot64.kickc.model.values.LValue lValue) { if(lValue instanceof VariableRef) { Variable lValueVar = getScope().getVariable((VariableRef) lValue); if(lValueVar instanceof VariableVersion) { diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1ProcedureInline.java b/src/main/java/dk/camelot64/kickc/passes/Pass1ProcedureInline.java index 4b5e1c7d4..e50342a85 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass1ProcedureInline.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass1ProcedureInline.java @@ -3,6 +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.statements.*; import dk.camelot64.kickc.model.symbols.*; import dk.camelot64.kickc.model.types.SymbolType; @@ -197,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 ValueReplacer.Replacer { + private class RValueInliner implements Replacer { /** The scope where the precedure is being inlined into. */ private final Scope callScope; @@ -213,7 +216,7 @@ public class Pass1ProcedureInline extends Pass1Base { } @Override - public void execute(ValueReplacer.ReplaceableValue replaceable, Statement currentStmt, ListIterator stmtIt, ControlFlowBlock currentBlock) { + public void execute(ReplaceableValue replaceable, Statement currentStmt, ListIterator stmtIt, ControlFlowBlock currentBlock) { RValue rValue = replaceable.get(); if(rValue instanceof VariableRef) { VariableRef procVarRef = (VariableRef) rValue; diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass1ResolveForwardReferences.java b/src/main/java/dk/camelot64/kickc/passes/Pass1ResolveForwardReferences.java index 17a8e425a..ab72f67e4 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass1ResolveForwardReferences.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass1ResolveForwardReferences.java @@ -2,6 +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.symbols.Scope; import dk.camelot64.kickc.model.symbols.Variable; import dk.camelot64.kickc.model.values.ForwardVariableRef; diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2AssertRValues.java b/src/main/java/dk/camelot64/kickc/passes/Pass2AssertRValues.java index 66e2b1452..69e4b6dd4 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2AssertRValues.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2AssertRValues.java @@ -2,6 +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.values.ForwardVariableRef; import dk.camelot64.kickc.model.values.RValue; import dk.camelot64.kickc.model.values.VariableRef; diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantAdditionElimination.java b/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantAdditionElimination.java index 8f2f57231..0272258b7 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantAdditionElimination.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2ConstantAdditionElimination.java @@ -1,6 +1,7 @@ package dk.camelot64.kickc.passes; import dk.camelot64.kickc.model.*; +import dk.camelot64.kickc.model.iterator.ReplaceableValue; import dk.camelot64.kickc.model.operators.Operator; import dk.camelot64.kickc.model.operators.Operators; import dk.camelot64.kickc.model.values.*; @@ -45,13 +46,13 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization { if(statement instanceof StatementAssignment) { StatementAssignment assignment = (StatementAssignment) statement; if(assignment.getlValue() instanceof PointerDereferenceIndexed) { - optimized |= optimizePointerDereferenceIndexed(new ValueReplacer.ReplaceableLValue(assignment)); + optimized |= optimizePointerDereferenceIndexed(new ReplaceableValue.LValue(assignment)); } if(assignment.getrValue1() instanceof PointerDereferenceIndexed) { - optimized |= optimizePointerDereferenceIndexed(new ValueReplacer.ReplaceableRValue1(assignment)); + optimized |= optimizePointerDereferenceIndexed(new ReplaceableValue.RValue1(assignment)); } if(assignment.getrValue2() instanceof PointerDereferenceIndexed) { - optimized |= optimizePointerDereferenceIndexed(new ValueReplacer.ReplaceableRValue2(assignment)); + optimized |= optimizePointerDereferenceIndexed(new ReplaceableValue.RValue2(assignment)); } Operator operator = assignment.getOperator(); @@ -68,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 ValueReplacer.ReplaceableCondRValue1(jump)); + optimized |= optimizePointerDereferenceIndexed(new ReplaceableValue.CondRValue1(jump)); } if(jump.getrValue2() instanceof PointerDereferenceIndexed) { - optimized |= optimizePointerDereferenceIndexed(new ValueReplacer.ReplaceableCondRValue2(jump)); + optimized |= optimizePointerDereferenceIndexed(new ReplaceableValue.CondRValue2(jump)); } } } @@ -79,7 +80,7 @@ public class Pass2ConstantAdditionElimination extends Pass2SsaOptimization { return optimized; } - private boolean optimizePointerDereferenceIndexed(ValueReplacer.ReplaceableValue value) { + private boolean optimizePointerDereferenceIndexed(ReplaceableValue 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/Pass2FixInlineConstructors.java b/src/main/java/dk/camelot64/kickc/passes/Pass2FixInlineConstructors.java index 47c086009..90ee1d7f3 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2FixInlineConstructors.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2FixInlineConstructors.java @@ -1,6 +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.operators.Operator; import dk.camelot64.kickc.model.operators.Operators; import dk.camelot64.kickc.model.values.RValue; @@ -62,7 +65,7 @@ public class Pass2FixInlineConstructors extends Pass2SsaOptimization { } - private abstract class InlineConstructor implements ValueReplacer.Replacer { + private abstract class InlineConstructor implements Replacer { private SymbolTypeInteger constructType; private Operator constructOperator; private boolean optimized; @@ -79,7 +82,7 @@ public class Pass2FixInlineConstructors extends Pass2SsaOptimization { } @Override - public void execute(ValueReplacer.ReplaceableValue replaceable, Statement currentStmt, ListIterator stmtIt, ControlFlowBlock currentBlock) { + public void execute(ReplaceableValue replaceable, Statement currentStmt, ListIterator stmtIt, ControlFlowBlock currentBlock) { RValue rValue = replaceable.get(); if(rValue instanceof ValueList) { ValueList list = (ValueList) rValue; diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2RangeResolving.java b/src/main/java/dk/camelot64/kickc/passes/Pass2RangeResolving.java index 4f3f58a11..3fe447174 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2RangeResolving.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2RangeResolving.java @@ -2,6 +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.operators.Operators; import dk.camelot64.kickc.model.statements.StatementAssignment; import dk.camelot64.kickc.model.types.SymbolType; diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass2SsaOptimization.java b/src/main/java/dk/camelot64/kickc/passes/Pass2SsaOptimization.java index e44b1ef93..d02fbc865 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass2SsaOptimization.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass2SsaOptimization.java @@ -1,6 +1,7 @@ package dk.camelot64.kickc.passes; import dk.camelot64.kickc.model.*; +import dk.camelot64.kickc.model.iterator.ValueReplacer; import dk.camelot64.kickc.model.values.*; import dk.camelot64.kickc.model.statements.*; import dk.camelot64.kickc.model.symbols.Symbol; diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass3AssertRValues.java b/src/main/java/dk/camelot64/kickc/passes/Pass3AssertRValues.java index 981267ecb..5254ab80d 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass3AssertRValues.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass3AssertRValues.java @@ -2,6 +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.values.RValue; import dk.camelot64.kickc.model.values.RangeValue; import dk.camelot64.kickc.model.values.ValueList; diff --git a/src/main/java/dk/camelot64/kickc/passes/ValueReplacer.java b/src/main/java/dk/camelot64/kickc/passes/ValueReplacer.java deleted file mode 100644 index 5386e4d56..000000000 --- a/src/main/java/dk/camelot64/kickc/passes/ValueReplacer.java +++ /dev/null @@ -1,603 +0,0 @@ -package dk.camelot64.kickc.passes; - -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()) { - 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) { - executeAll(new ReplaceableLValue((StatementLValue) statement), replacer, statement, statementsIt, block); - executeAll(new ReplaceableRValue1((StatementAssignment) statement), replacer, statement, statementsIt, block); - executeAll(new ReplaceableRValue2((StatementAssignment) statement), replacer, statement, statementsIt, block); - } else if(statement instanceof StatementCall) { - executeAll(new ReplaceableLValue((StatementLValue) statement), replacer, statement, statementsIt, block); - StatementCall call = (StatementCall) statement; - if(call.getParameters() != null) { - int size = call.getParameters().size(); - for(int i = 0; i < size; i++) { - executeAll(new ReplaceableCallParameter(call, i), replacer, statement, statementsIt, block); - } - } - } else if(statement instanceof StatementConditionalJump) { - executeAll(new ReplaceableCondRValue1((StatementConditionalJump) statement), replacer, statement, statementsIt, block); - executeAll(new ReplaceableCondRValue2((StatementConditionalJump) statement), replacer, statement, statementsIt, block); - } else if(statement instanceof StatementReturn) { - executeAll(new ReplaceableReturn((StatementReturn) statement), replacer, statement, statementsIt, block); - } else if(statement instanceof StatementPhiBlock) { - for(StatementPhiBlock.PhiVariable phiVariable : ((StatementPhiBlock) statement).getPhiVariables()) { - executeAll(new ReplaceablePhiVariable(phiVariable), replacer, statement, statementsIt, block); - int size = phiVariable.getValues().size(); - for(int i = 0; i < size; i++) { - executeAll(new ReplaceablePhiValue(phiVariable, i), 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 : replaceable.getSubValues()) { - executeAll(subValue, replacer, currentStmt, stmtIt, currentBlock); - } - } - - /** 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); - } - - /** - * Interface representing an RValue that can be replaced. - * The value may have sub-values that can also be replaced. - */ - public static abstract class ReplaceableValue { - - public abstract RValue get(); - - public abstract void set(RValue value); - - public Collection getSubValues() { - RValue value = get(); - ArrayList subValues = new ArrayList<>(); - if(value instanceof PointerDereferenceIndexed) { - subValues.add(new ReplaceablePointer((PointerDereference) value)); - subValues.add(new ReplaceablePointerIndex((PointerDereferenceIndexed) value)); - } else if(value instanceof PointerDereferenceSimple) { - subValues.add(new ReplaceablePointer((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 ReplaceableListElement(valueList, i)); - } - } else if(value instanceof CastValue) { - subValues.add(new ReplaceableCastValue((CastValue) value)); - } else if(value instanceof ConstantCastValue) { - subValues.add(new ReplaceableConstantCastValue((ConstantCastValue) value)); - } else if(value instanceof ConstantVarPointer) { - subValues.add(new ReplaceableVarPointer((ConstantVarPointer) value)); - } else if(value instanceof RangeValue) { - subValues.add(new ReplaceableRangeFirst((RangeValue) value)); - subValues.add(new ReplaceableRangeLast((RangeValue) value)); - } else if(value instanceof ConstantBinary) { - subValues.add(new ReplaceableConstantBinaryLeft((ConstantBinary) value)); - subValues.add(new ReplaceableConstantBinaryRight((ConstantBinary) value)); - } else if(value instanceof ConstantUnary) { - subValues.add(new ReplaceableConstantUnaryValue((ConstantUnary) value)); - } else if(value instanceof ArrayFilled) { - subValues.add(new ReplaceableArrayFilledSize((ArrayFilled) value)); - } else if(value instanceof ConstantArrayFilled) { - subValues.add(new ReplaceableConstantArrayFilledSize((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; - } - - } - - /** Replaceable value inside a array filled expression. */ - public static class ReplaceableArrayFilledSize extends ReplaceableValue { - private final ArrayFilled array; - - ReplaceableArrayFilledSize(ArrayFilled array) { - this.array = array; - } - - @Override - public RValue get() { - return array.getSize(); - } - - @Override - public void set(RValue val) { - array.setSize(val); - } - - } - - /** Replaceable value inside a constant array filled expression. */ - public static class ReplaceableConstantArrayFilledSize extends ReplaceableValue { - private final ConstantArrayFilled array; - - ReplaceableConstantArrayFilledSize(ConstantArrayFilled array) { - this.array = array; - } - - @Override - public RValue get() { - return array.getSize(); - } - - @Override - public void set(RValue val) { - array.setSize((ConstantValue) val); - } - - } - - /** Replaceable value inside a constant unary expression. */ - public static class ReplaceableConstantUnaryValue extends ReplaceableValue { - private final ConstantUnary unary; - - ReplaceableConstantUnaryValue(ConstantUnary unary) { - this.unary = unary; - } - - @Override - public RValue get() { - return unary.getOperand(); - } - - @Override - public void set(RValue val) { - unary.setOperand((ConstantValue) val); - } - - } - - /** Replaceable left value inside a constant binary expression. */ - public static class ReplaceableConstantBinaryLeft extends ReplaceableValue { - private final ConstantBinary binary; - - ReplaceableConstantBinaryLeft(ConstantBinary binary) { - this.binary = binary; - } - - @Override - public RValue get() { - return binary.getLeft(); - } - - @Override - public void set(RValue val) { - binary.setLeft((ConstantValue) val); - } - - } - - /** Replaceable right value inside a constant binary expression. */ - public static class ReplaceableConstantBinaryRight extends ReplaceableValue { - private final ConstantBinary binary; - - ReplaceableConstantBinaryRight(ConstantBinary range) { - this.binary = range; - } - - @Override - public RValue get() { - return binary.getRight(); - } - - @Override - public void set(RValue val) { - binary.setRight((ConstantValue) val); - } - - } - - /** - * Replaceable first value inside a ranged comparison value. - */ - public static class ReplaceableRangeFirst extends ReplaceableValue { - private final RangeValue range; - - ReplaceableRangeFirst(RangeValue range) { - this.range = range; - } - - @Override - public RValue get() { - return range.getRangeFirst(); - } - - @Override - public void set(RValue val) { - range.setRangeFirst(val); - } - - } - - /** - * Replaceable last value inside inside a ranged comparison value. - */ - public static class ReplaceableRangeLast extends ReplaceableValue { - private final RangeValue range; - - ReplaceableRangeLast(RangeValue range) { - this.range = range; - } - - @Override - public RValue get() { - return range.getRangeLast(); - } - - @Override - public void set(RValue val) { - range.setRangeLast(val); - } - - } - - /** - * Replaceable LValue as part of an assignment statement (or a call). - */ - public static class ReplaceableLValue extends ReplaceableValue { - private final StatementLValue statement; - - public ReplaceableLValue(StatementLValue statement) { - this.statement = statement; - } - - @Override - public RValue get() { - return statement.getlValue(); - } - - @Override - public void set(RValue value) { - statement.setlValue((LValue) value); - } - - } - - /** - * Replaceable pointer inside a pointer dererence value. - */ - public static class ReplaceablePointer extends ReplaceableValue { - private final PointerDereference pointer; - - ReplaceablePointer(PointerDereference pointer) { - this.pointer = pointer; - } - - @Override - public RValue get() { - return pointer.getPointer(); - } - - @Override - public void set(RValue val) { - pointer.setPointer(val); - } - - } - - /** - * Replaceable value inside a noop cast. - */ - public static class ReplaceableCastValue extends ReplaceableValue { - private final CastValue castValue; - - - public ReplaceableCastValue(CastValue castValue) { - this.castValue = castValue; - } - - @Override - public RValue get() { - return castValue.getValue(); - } - - @Override - public void set(RValue val) { - castValue.setValue(val); - } - - } - - /** - * Replaceable value inside a constant noop cast. - */ - public static class ReplaceableConstantCastValue extends ReplaceableValue { - private final ConstantCastValue castValue; - - - public ReplaceableConstantCastValue(ConstantCastValue castValue) { - this.castValue = castValue; - } - - @Override - public RValue get() { - return castValue.getValue(); - } - - @Override - public void set(RValue val) { - castValue.setValue((ConstantValue) val); - } - - } - - /** - * Replaceable pointer inside a variable pointer. - */ - public static class ReplaceableVarPointer extends ReplaceableValue { - private final ConstantVarPointer varPointer; - - - public ReplaceableVarPointer(ConstantVarPointer varPointer) { - this.varPointer = varPointer; - } - - @Override - public RValue get() { - return varPointer.getToVar(); - } - - @Override - public void set(RValue val) { - varPointer.setToVar((VariableRef) val); - } - - } - - public static class ReplaceableListElement extends ReplaceableValue { - private ValueList list; - private int idx; - - public ReplaceableListElement(ValueList list, int idx) { - this.list = list; - this.idx = idx; - } - - @Override - public RValue get() { - return list.getList().get(idx); - } - - @Override - public void set(RValue value) { - list.getList().set(idx, value); - } - - } - - /** - * Replaceable pointer index inside a indexed pointer dererence value. - */ - public static class ReplaceablePointerIndex extends ReplaceableValue { - private final PointerDereferenceIndexed pointer; - - ReplaceablePointerIndex(PointerDereferenceIndexed pointer) { - this.pointer = pointer; - } - - @Override - public RValue get() { - return pointer.getIndex(); - } - - @Override - public void set(RValue val) { - pointer.setIndex(val); - } - - } - - public static class ReplaceableRValue1 extends ReplaceableValue { - private final StatementAssignment statement; - - public ReplaceableRValue1(StatementAssignment statement) { - this.statement = statement; - } - - @Override - public RValue get() { - return statement.getrValue1(); - } - - @Override - public void set(RValue value) { - statement.setrValue1(value); - } - } - - public static class ReplaceableRValue2 extends ReplaceableValue { - private final StatementAssignment statement; - - public ReplaceableRValue2(StatementAssignment statement) { - this.statement = statement; - } - - @Override - public RValue get() { - return statement.getrValue2(); - } - - @Override - public void set(RValue value) { - statement.setrValue2(value); - } - } - - public static class ReplaceableCallParameter extends ReplaceableValue { - private final StatementCall call; - private final int i; - - public ReplaceableCallParameter(StatementCall call, int i) { - this.call = call; - this.i = i; - } - - @Override - public RValue get() { - return call.getParameters().get(i); - } - - @Override - public void set(RValue value) { - call.getParameters().set(i, value); - } - } - - public static class ReplaceableCondRValue1 extends ReplaceableValue { - private final StatementConditionalJump statement; - - public ReplaceableCondRValue1(StatementConditionalJump statement) { - this.statement = statement; - } - - @Override - public RValue get() { - return statement.getrValue1(); - } - - @Override - public void set(RValue value) { - statement.setrValue1(value); - } - } - - public static class ReplaceableCondRValue2 extends ReplaceableValue { - private final StatementConditionalJump statement; - - public ReplaceableCondRValue2(StatementConditionalJump statement) { - this.statement = statement; - } - - @Override - public RValue get() { - return statement.getrValue2(); - } - - @Override - public void set(RValue value) { - statement.setrValue2(value); - } - } - - public static class ReplaceableReturn extends ReplaceableValue { - private final StatementReturn statement; - - public ReplaceableReturn(StatementReturn statement) { - this.statement = statement; - } - - @Override - public RValue get() { - return statement.getValue(); - } - - @Override - public void set(RValue value) { - statement.setValue(value); - } - } - - public static class ReplaceablePhiValue extends ReplaceableValue { - private final StatementPhiBlock.PhiVariable phiVariable; - private final int i; - - public ReplaceablePhiValue(StatementPhiBlock.PhiVariable phiVariable, int i) { - this.phiVariable = phiVariable; - this.i = i; - } - - @Override - public RValue get() { - return phiVariable.getValues().get(i).getrValue(); - } - - @Override - public void set(RValue value) { - phiVariable.getValues().get(i).setrValue(value); - } - } - - /** - * Replaceable LValue as part of an assignment statement (or a call). - */ - public static class ReplaceablePhiVariable extends ReplaceableValue { - private final StatementPhiBlock.PhiVariable phiVariable; - - public ReplaceablePhiVariable(StatementPhiBlock.PhiVariable phiVariable) { - this.phiVariable = phiVariable; - } - - @Override - public RValue get() { - return phiVariable.getVariable(); - } - - @Override - public void set(RValue value) { - phiVariable.setVariable((VariableRef) value); - } - - } -}