package de.gaalop.gapp.importing; import de.gaalop.cfg.AssignmentNode; import de.gaalop.cfg.ControlFlowGraph; import de.gaalop.cfg.EmptyControlFlowVisitor; import de.gaalop.dfg.BinaryOperation; import de.gaalop.dfg.Division; import de.gaalop.dfg.Expression; import de.gaalop.dfg.ExpressionVisitor; import de.gaalop.dfg.FloatConstant; import de.gaalop.dfg.Multiplication; import de.gaalop.dfg.UnaryOperation; import de.gaalop.visitors.ExpressionTypeVisitor; /** * Replaces divisions with constants with multiplications * @author Christian Steinmetz */ public class ConstantDivisionTransformer extends EmptyControlFlowVisitor { //private constructor to make usage of transform-method mandatory private ConstantDivisionTransformer() { } /** * Replaces divisions with constants with multiplications * @param graph The graph */ public static void transform(ControlFlowGraph graph) { ConstantDivisionTransformer transformer = new ConstantDivisionTransformer(); graph.accept(transformer); } private Expression replaceWith = null; private ExpressionVisitor expressionVisitor = new ExpressionTypeVisitor() { @Override protected void visitBinaryOperation(BinaryOperation node) { node.getLeft().accept(expressionVisitor); if (replaceWith != null) { node.setLeft(replaceWith); replaceWith = null; } node.getRight().accept(expressionVisitor); if (replaceWith != null) { node.setRight(replaceWith); replaceWith = null; } } @Override protected void visitUnaryOperation(UnaryOperation node) { node.getOperand().accept(expressionVisitor); if (replaceWith != null) { node.setOperand(replaceWith); replaceWith = null; } } @Override protected void visitTerminal(Expression node) { } @Override public void visit(Division node) { if (node.getRight() instanceof FloatConstant) { FloatConstant newLeft = new FloatConstant(1/((FloatConstant) node.getRight()).getValue()); replaceWith = new Multiplication(newLeft, node.getLeft()); } } }; @Override public void visit(AssignmentNode node) { node.getValue().accept(expressionVisitor); if (replaceWith != null) { node.setValue(replaceWith); replaceWith = null; } super.visit(node); } }