package de.gaalop.tba.cfgImport.optimization; import de.gaalop.api.cfg.GetAllOutputBlades; import de.gaalop.api.dfg.DFGNodeType; import de.gaalop.api.dfg.DFGNodeTypeGetter; import de.gaalop.cfg.AssignmentNode; import de.gaalop.cfg.ColorNode; import de.gaalop.cfg.EmptyControlFlowVisitor; import de.gaalop.cfg.ExpressionStatement; import de.gaalop.cfg.SequentialNode; import de.gaalop.cfg.StartNode; import de.gaalop.cfg.StoreResultNode; import de.gaalop.dfg.Expression; import de.gaalop.dfg.MultivectorComponent; import de.gaalop.dfg.Variable; import de.gaalop.tba.UseAlgebra; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; /** * Removes assignments that consists only of one Variable as value, * and those target variable are not outputted * @author Christian Steinmetz */ public class OneExpressionRemoval extends EmptyControlFlowVisitor { private boolean graphModified = false; private HashSet<VariableComponent> tabuVariables = new HashSet<VariableComponent>(); private HashMap<VariableComponent, VariableComponent> mapOneExpressions = new HashMap<VariableComponent, VariableComponent>(); private DFGVisitorUsedVariables dfgVisitorusedVariables = new DFGVisitorUsedVariables(); private LinkedList<SequentialNode> nodeRemovals = new LinkedList<SequentialNode>(); private UseAlgebra usedAlgebra; public OneExpressionRemoval(UseAlgebra usedAlgebra) { this.usedAlgebra = usedAlgebra; } public LinkedList<SequentialNode> getNodeRemovals() { return nodeRemovals; } public boolean isGraphModified() { return graphModified; } private void setGraphModified() { graphModified = true; } @Override public void visit(StartNode node) { // mark output vars as tabu tabuVariables.addAll(GetAllOutputBlades.getAllOutputBlades(node.getGraph(), usedAlgebra)); // mark only evaluation vars as tabu int bladeCount = usedAlgebra.getBladeCount(); for (String var: node.getGraph().getPragmaOnlyEvaluateVariables()) for (int blade = 0; blade < bladeCount; blade++) tabuVariables.add(new VariableComponent(var, blade, null)); super.visit(node); } /** * Replace all expressions in a expression, that are listed in mapOneExpressions * @param value The value to search in * @return The result expression */ private Expression performExpressionReplacements(Expression value) { dfgVisitorusedVariables.getVariables().clear(); value.accept(dfgVisitorusedVariables); for (VariableComponent variable : dfgVisitorusedVariables.getVariables()) { if (mapOneExpressions.containsKey(variable)) { Expression toReplace = variable.getReferredExpression(); Expression replacement = mapOneExpressions.get(variable).getReferredExpression(); ExpressionReplacer replacer = new ExpressionReplacer(toReplace, replacement); value = replacer.replace(value); setGraphModified(); } } return value; } @Override public void visit(AssignmentNode node) { // replace all variables that are in mapOneExpressions Expression value = node.getValue(); node.setValue(performExpressionReplacements(value)); mapOneExpressions.remove(getVariableComponent(node.getVariable())); // if this is no output variable assignment if (!tabuVariables.contains(getVariableComponent(node.getVariable()))) { // if the value is only a Variable then put it in mapOneExpressions and remove this AssignmentNode DFGNodeType typeValue = DFGNodeTypeGetter.getTypeOfDFGNode(node.getValue()); if (typeValue == DFGNodeType.MultivectorComponent || typeValue == DFGNodeType.Variable) { mapOneExpressions.put( getVariableComponent(node.getVariable()), getVariableComponent(node.getValue())); setGraphModified(); nodeRemovals.add(node); } } super.visit(node); } /** * Returns the VariableComponent for a expression * @param expression The expression * @return The VariableComponent */ private VariableComponent getVariableComponent(Expression expression) { DFGNodeType typeValue = DFGNodeTypeGetter.getTypeOfDFGNode(expression); if (typeValue == DFGNodeType.MultivectorComponent) { MultivectorComponent comp = (MultivectorComponent) expression; return new VariableComponent(comp.getName(), comp.getBladeIndex(), expression); } if (typeValue == DFGNodeType.Variable) { Variable comp = (Variable) expression; return new VariableComponent(comp.getName(), 0, expression); } return null; } @Override public void visit(ColorNode node) { // replace all variables which are in mapOneExpressions node.setR(performExpressionReplacements(node.getR())); node.setG(performExpressionReplacements(node.getG())); node.setB(performExpressionReplacements(node.getB())); node.setAlpha(performExpressionReplacements(node.getAlpha())); super.visit(node); } @Override public void visit(ExpressionStatement node) { node.setExpression(performExpressionReplacements(node.getExpression())); super.visit(node); } @Override public void visit(StoreResultNode node) { node.setValue((Variable) performExpressionReplacements(node.getValue())); super.visit(node); } }