/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * 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.
 */

#include "pass_driver_me_opts.h"

#include "base/logging.h"
#include "base/macros.h"
#include "bb_optimizations.h"
#include "dataflow_iterator.h"
#include "dataflow_iterator-inl.h"
#include "pass_driver_me_opts.h"
#include "pass_manager.h"
#include "post_opt_passes.h"

namespace art {

void PassDriverMEOpts::SetupPasses(PassManager* pass_manager) {
  /*
   * Create the pass list. These passes are immutable and are shared across the threads.
   *
   * Advantage is that there will be no race conditions here.
   * Disadvantage is the passes can't change their internal states depending on CompilationUnit:
   *   - This is not yet an issue: no current pass would require it.
   */
  pass_manager->AddPass(new CacheFieldLoweringInfo);
  pass_manager->AddPass(new CacheMethodLoweringInfo);
  pass_manager->AddPass(new CalculatePredecessors);
  pass_manager->AddPass(new DFSOrders);
  pass_manager->AddPass(new ClassInitCheckElimination);
  pass_manager->AddPass(new SpecialMethodInliner);
  pass_manager->AddPass(new NullCheckElimination);
  pass_manager->AddPass(new BBCombine);
  pass_manager->AddPass(new CodeLayout);
  pass_manager->AddPass(new GlobalValueNumberingPass);
  pass_manager->AddPass(new DeadCodeEliminationPass);
  pass_manager->AddPass(new ConstantPropagation);
  pass_manager->AddPass(new MethodUseCount);
  pass_manager->AddPass(new BBOptimizations);
  pass_manager->AddPass(new SuspendCheckElimination);
}

void PassDriverMEOpts::ApplyPass(PassDataHolder* data, const Pass* pass) {
  const PassME* const pass_me = down_cast<const PassME*>(pass);
  DCHECK(pass_me != nullptr);
  PassMEDataHolder* const pass_me_data_holder = down_cast<PassMEDataHolder*>(data);
  // Set to dirty.
  pass_me_data_holder->dirty = true;
  // First call the base class' version.
  PassDriver::ApplyPass(data, pass);
  // Now we care about flags.
  if ((pass_me->GetFlag(kOptimizationBasicBlockChange) == true) ||
      (pass_me->GetFlag(kOptimizationDefUsesChange) == true)) {
    // Is it dirty at least?
    if (pass_me_data_holder->dirty == true) {
      CompilationUnit* c_unit = pass_me_data_holder->c_unit;
      c_unit->mir_graph.get()->CalculateBasicBlockInformation();
    }
  }
}

}  // namespace art
