package de.gaalop.tba.cfgImport.optimization; import de.gaalop.cfg.AssignmentNode; import de.gaalop.cfg.BlockEndNode; import de.gaalop.cfg.BreakNode; import de.gaalop.cfg.ColorNode; import de.gaalop.cfg.ControlFlowVisitor; import de.gaalop.cfg.EndNode; import de.gaalop.cfg.ExpressionStatement; import de.gaalop.cfg.IfThenElseNode; import de.gaalop.cfg.LoopNode; import de.gaalop.cfg.Macro; import de.gaalop.cfg.SequentialNode; import de.gaalop.cfg.StartNode; import de.gaalop.cfg.StoreResultNode; import de.gaalop.tba.UseAlgebra; import java.util.HashMap; import java.util.LinkedList; /** * Visitor to optimize a ControlFlowGraph via variable usage analysis. * The graph is not modified here, only information for modifying is collected * @author Christian Steinmetz */ public class CFGVisitorUsedVariables implements ControlFlowVisitor { private VariableUsage variableUsage = new VariableUsage(); private DFGVisitorUsedVariables dfgVisitorusedVariables = new DFGVisitorUsedVariables(); private HashMap<String, LinkedList<Integer>> outputBlades; private UseAlgebra usedAlgebra; private LinkedList<SequentialNode> nodeRemovals = new LinkedList<SequentialNode>(); public CFGVisitorUsedVariables(HashMap<String, LinkedList<Integer>> outputBlades, UseAlgebra usedAlgebra) { this.outputBlades = outputBlades; this.usedAlgebra = usedAlgebra; } public LinkedList<SequentialNode> getNodeRemovals() { return nodeRemovals; } @Override public void visit(AssignmentNode node) { // get the target variable dfgVisitorusedVariables.getVariables().clear(); node.getVariable().accept(dfgVisitorusedVariables); VariableComponent variable = dfgVisitorusedVariables.getVariables().getFirst(); // Here is the optimization: Check, if the variable is used later. // If it isn't used later, then remove this node, because the assignment is unnecessary. if (!variableUsage.isUsed(variable)) { nodeRemovals.addFirst(node); } else { // variable definition variableUsage.addDefinition(variable); // value usage dfgVisitorusedVariables.getVariables().clear(); node.getValue().accept(dfgVisitorusedVariables); for (VariableComponent component : dfgVisitorusedVariables.getVariables()) { variableUsage.addUsage(component); } } } @Override public void visit(StoreResultNode node) { String name = node.getValue().getName(); if (outputBlades.containsKey(name)) { // only special blades are outputted for (Integer bladeIndex : outputBlades.get(name)) { variableUsage.addUsage(new VariableComponent(name, bladeIndex, node.getValue())); } } else { // all blades are outputted int bladeCount = usedAlgebra.getBladeCount(); for (int blade = 0; blade < bladeCount; blade++) { variableUsage.addUsage(new VariableComponent(name, blade, node.getValue())); } } } @Override public void visit(ExpressionStatement node) { // expression usage dfgVisitorusedVariables.getVariables().clear(); node.getExpression().accept(dfgVisitorusedVariables); for (VariableComponent component : dfgVisitorusedVariables.getVariables()) { variableUsage.addUsage(component); } } @Override public void visit(ColorNode node) { // R usage dfgVisitorusedVariables.getVariables().clear(); node.getR().accept(dfgVisitorusedVariables); for (VariableComponent component : dfgVisitorusedVariables.getVariables()) { variableUsage.addUsage(component); } // G usage dfgVisitorusedVariables.getVariables().clear(); node.getG().accept(dfgVisitorusedVariables); for (VariableComponent component : dfgVisitorusedVariables.getVariables()) { variableUsage.addUsage(component); } // B usage dfgVisitorusedVariables.getVariables().clear(); node.getB().accept(dfgVisitorusedVariables); for (VariableComponent component : dfgVisitorusedVariables.getVariables()) { variableUsage.addUsage(component); } // Alpha usage dfgVisitorusedVariables.getVariables().clear(); node.getAlpha().accept(dfgVisitorusedVariables); for (VariableComponent component : dfgVisitorusedVariables.getVariables()) { variableUsage.addUsage(component); } } @Override public void visit(StartNode node) { } @Override public void visit(IfThenElseNode node) { } @Override public void visit(BlockEndNode node) { } @Override public void visit(LoopNode node) { } @Override public void visit(BreakNode node) { } @Override public void visit(Macro node) { } @Override public void visit(EndNode node) { } }