package de.gaalop.tba.cfgImport; import de.gaalop.OptimizationException; import de.gaalop.algebra.UpdateLocalVariableSet; import de.gaalop.api.cfg.RoundingCFGVisitor; import de.gaalop.cfg.ControlFlowGraph; import de.gaalop.dfg.Variable; import de.gaalop.tba.Plugin; import de.gaalop.tba.UseAlgebra; import de.gaalop.tba.cfgImport.optimization.OptConstantPropagation; import de.gaalop.tba.cfgImport.optimization.OptMaxima; import de.gaalop.tba.cfgImport.optimization.OptOneExpressionsRemoval; import de.gaalop.tba.cfgImport.optimization.OptimizationStrategyWithModifyFlag; import de.gaalop.tba.cfgImport.optimization.OptUnusedAssignmentsRemoval; import java.util.LinkedList; /** * This class provides a simple facade to transform the graph * with the table based approach * * @author Christian Steinmetz */ public class CFGImporterFacade { private LinkedList<OptimizationStrategyWithModifyFlag> optimizations; private Plugin plugin; private UseAlgebra usedAlgebra; public CFGImporterFacade(Plugin plugin) { this.plugin = plugin; optimizations = new LinkedList<OptimizationStrategyWithModifyFlag>(); if (plugin.isOptConstantPropagation()) { optimizations.add(new OptConstantPropagation()); } if (plugin.isOptUnusedAssignments()) { optimizations.add(new OptUnusedAssignmentsRemoval()); } if (plugin.isOptOneExpressionRemoval()) { optimizations.add(new OptOneExpressionsRemoval()); } } /** * Transforms the graph and apply optionally optimizations. * Note, that the graph is changed in place. * * @param graph The graph to be transformed * @return The transformed graph * @throws OptimizationException */ public ControlFlowGraph importGraph(ControlFlowGraph graph) throws OptimizationException { //load desired algebra usedAlgebra = new UseAlgebra(graph.getAlgebraDefinitionFile()); if (ContainsControlFlow.containsControlFlow(graph)) { throw new OptimizationException("Due to Control Flow Existence in Source, TBA isn't assigned on graph!", graph); } Variable v; if ((v = GetMultipleAssignments.getMulipleAssignments(graph)) != null) { throw new OptimizationException("Due to Existence of multiple assignments of variable '"+v.getName()+"' in source, TBA isn't assigned on graph!", graph); } if (!plugin.isInvertTransformation()) { DivisionRemover divisionRemover = new DivisionRemover(); graph.accept(divisionRemover); } if (!plugin.isScalarFunctions()) { VariablesCollector collector = new VariablesCollector(); graph.accept(collector); MathFunctionSeparator mathFunctionSeparator = new MathFunctionSeparator(collector.getVariables()); graph.accept(mathFunctionSeparator); } CFGImporter builder = new CFGImporter(usedAlgebra, plugin.isScalarFunctions(), graph.getAlgebraDefinitionFile()); graph.accept(builder); int count = 0; boolean repeat; do { repeat = false; for (OptimizationStrategyWithModifyFlag curOpt : optimizations) { repeat = repeat || curOpt.transform(graph, usedAlgebra); } count++; } while (repeat); //Use Maxima only once if (graph.globalSettings.isOptMaxima()) { OptMaxima optMaxima = new OptMaxima(graph.globalSettings.getMaximaCommand(), plugin); optMaxima.transform(graph, usedAlgebra); //repeat other optimizations count = 0; do { repeat = false; for (OptimizationStrategyWithModifyFlag curOpt : optimizations) { repeat = repeat || curOpt.transform(graph, usedAlgebra); } count++; } while (repeat); } // update variable sets UpdateLocalVariableSet.updateVariableSets(graph); // round float constants, if this is desired by the user through configuration panel if (plugin.isDoRoundingAfterOptimization()) graph.accept(new RoundingCFGVisitor(plugin.getNumberOfRoundingDigits())); return graph; } public UseAlgebra getUsedAlgebra() { return usedAlgebra; } }