/* * Copyright 2009 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.google.gwt.dev.jjs.impl.gflow; import com.google.gwt.dev.jjs.ast.Context; import com.google.gwt.dev.jjs.ast.JDeclaredType; import com.google.gwt.dev.jjs.ast.JMethod; import com.google.gwt.dev.jjs.ast.JMethodBody; import com.google.gwt.dev.jjs.ast.JModVisitor; import com.google.gwt.dev.jjs.ast.JNode; import com.google.gwt.dev.jjs.ast.JProgram; import com.google.gwt.dev.jjs.impl.DeadCodeElimination; import com.google.gwt.dev.jjs.impl.OptimizerStats; import com.google.gwt.dev.jjs.impl.gflow.cfg.Cfg; import com.google.gwt.dev.jjs.impl.gflow.cfg.CfgBuilder; import com.google.gwt.dev.jjs.impl.gflow.cfg.CfgEdge; import com.google.gwt.dev.jjs.impl.gflow.cfg.CfgNode; import com.google.gwt.dev.jjs.impl.gflow.cfg.CfgTransformer; import com.google.gwt.dev.jjs.impl.gflow.constants.ConstantsAnalysis; import com.google.gwt.dev.jjs.impl.gflow.copy.CopyAnalysis; import com.google.gwt.dev.jjs.impl.gflow.liveness.LivenessAnalysis; import com.google.gwt.dev.jjs.impl.gflow.unreachable.UnreachableAnalysis; import com.google.gwt.dev.util.Preconditions; import com.google.gwt.dev.util.log.speedtracer.CompilerEventType; import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger; import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event; /** */ public class DataflowOptimizer { public static String NAME = DataflowOptimizer.class.getSimpleName(); public static OptimizerStats exec(JProgram jprogram, JNode node) { Event optimizeEvent = SpeedTracerLogger.start(CompilerEventType.OPTIMIZE, "optimizer", NAME); OptimizerStats stats = new DataflowOptimizer(jprogram).execImpl(node); optimizeEvent.end(); return stats; } public static OptimizerStats exec(JProgram jprogram) { return exec(jprogram, jprogram); } private final JProgram program; public DataflowOptimizer(JProgram program) { this.program = program; } private class DataflowOptimizerVisitor extends JModVisitor { @Override public boolean visit(JMethodBody methodBody, Context ctx) { Cfg cfg = CfgBuilder.build(program, methodBody.getBlock()); JMethod method = methodBody.getMethod(); JDeclaredType enclosingType = method.getEnclosingType(); String methodName = enclosingType.getName() + "." + method.getName(); // AnalysisSolver.debug = methodName.equals("<some method>"); Preconditions.checkNotNull(cfg, "Can't build flow for %s", methodName); try { CombinedIntegratedAnalysis<CfgNode<?>, CfgEdge, CfgTransformer, Cfg> fwdAnalysis = CombinedIntegratedAnalysis.createAnalysis(); fwdAnalysis.addAnalysis(new UnreachableAnalysis()); fwdAnalysis.addAnalysis(new ConstantsAnalysis()); fwdAnalysis.addAnalysis(new CopyAnalysis()); // fwdAnalysis.addAnalysis(new InlineVarAnalysis(program)); boolean madeChanges = false; madeChanges = AnalysisSolver.solveIntegrated(cfg, fwdAnalysis, true) || madeChanges; cfg = CfgBuilder.build(program, methodBody.getBlock()); Preconditions.checkNotNull(cfg); CombinedIntegratedAnalysis<CfgNode<?>, CfgEdge, CfgTransformer, Cfg> bkwAnalysis = CombinedIntegratedAnalysis.createAnalysis(); bkwAnalysis.addAnalysis(new LivenessAnalysis()); madeChanges = AnalysisSolver.solveIntegrated(cfg, bkwAnalysis, false) || madeChanges; if (madeChanges) { madeChanges(); DeadCodeElimination.exec(program, methodBody); } } catch (Throwable t) { throw new RuntimeException("Error optimizing: " + methodName, t); } return true; } } private OptimizerStats execImpl(JNode node) { DataflowOptimizerVisitor visitor = new DataflowOptimizerVisitor(); visitor.accept(node); return new OptimizerStats(NAME).recordModified(visitor.getNumMods()); } }