/*
 * 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());
  }
}
