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

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();

  HEnvironment* 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;
  }

  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.
  HEnvironment* 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_
