/*
 * 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.
 */

#ifndef ART_COMPILER_OPTIMIZING_SSA_BUILDER_H_
#define ART_COMPILER_OPTIMIZING_SSA_BUILDER_H_

#include "nodes.h"
#include "optimization.h"

namespace art {

class TransformToSsa : public HOptimization {
 public:
  explicit TransformToSsa(HGraph* graph) : HOptimization(graph, true, "ssa transform") {}

  void Run() OVERRIDE {
    graph_->BuildDominatorTree();
    graph_->TransformToSSA();
    graph_->FindNaturalLoops();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(TransformToSsa);
};

static constexpr int kDefaultNumberOfLoops = 2;

class SsaBuilder : public HGraphVisitor {
 public:
  explicit SsaBuilder(HGraph* graph)
      : HGraphVisitor(graph),
        current_locals_(nullptr),
        loop_headers_(graph->GetArena(), kDefaultNumberOfLoops),
        locals_for_(graph->GetArena(), graph->GetBlocks().Size()) {
    locals_for_.SetSize(graph->GetBlocks().Size());
  }

  void BuildSsa();

  GrowableArray<HInstruction*>* GetLocalsFor(HBasicBlock* block) {
    HEnvironment* env = locals_for_.Get(block->GetBlockId());
    if (env == nullptr) {
      env = new (GetGraph()->GetArena()) HEnvironment(
          GetGraph()->GetArena(), GetGraph()->GetNumberOfVRegs());
      locals_for_.Put(block->GetBlockId(), env);
    }
    return env->GetVRegs();
  }

  HInstruction* ValueOfLocal(HBasicBlock* block, size_t local);

  void VisitBasicBlock(HBasicBlock* block);
  void VisitLoadLocal(HLoadLocal* load);
  void VisitStoreLocal(HStoreLocal* store);
  void VisitInstruction(HInstruction* instruction);
  void VisitTemporary(HTemporary* instruction);

  static HInstruction* GetFloatOrDoubleEquivalent(HInstruction* user,
                                                  HInstruction* instruction,
                                                  Primitive::Type type);

 private:
  // Locals for the current block being visited.
  GrowableArray<HInstruction*>* current_locals_;

  // Keep track of loop headers found. The last phase of the analysis iterates
  // over these blocks to set the inputs of their phis.
  GrowableArray<HBasicBlock*> loop_headers_;

  // HEnvironment for each block.
  GrowableArray<HEnvironment*> locals_for_;

  DISALLOW_COPY_AND_ASSIGN(SsaBuilder);
};

}  // namespace art

#endif  // ART_COMPILER_OPTIMIZING_SSA_BUILDER_H_
