/*
 * Copyright (C) 2016 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_REGISTER_ALLOCATION_RESOLVER_H_
#define ART_COMPILER_OPTIMIZING_REGISTER_ALLOCATION_RESOLVER_H_

#include "base/arena_containers.h"
#include "base/array_ref.h"
#include "base/value_object.h"
#include "primitive.h"

namespace art {

class ArenaAllocator;
class CodeGenerator;
class HBasicBlock;
class HInstruction;
class HParallelMove;
class LiveInterval;
class Location;
class SsaLivenessAnalysis;

/**
 * Reconciles the locations assigned to live intervals with the location
 * summary of each instruction, and inserts moves to resolve split intervals,
 * nonlinear control flow, and phi inputs.
 */
class RegisterAllocationResolver : ValueObject {
 public:
  RegisterAllocationResolver(ArenaAllocator* allocator,
                             CodeGenerator* codegen,
                             const SsaLivenessAnalysis& liveness);

  void Resolve(ArrayRef<HInstruction* const> safepoints,
               size_t reserved_out_slots,  // Includes slot(s) for the art method.
               size_t int_spill_slots,
               size_t long_spill_slots,
               size_t float_spill_slots,
               size_t double_spill_slots,
               size_t catch_phi_spill_slots,
               const ArenaVector<LiveInterval*>& temp_intervals);

 private:
  // Update live registers of safepoint location summary.
  void UpdateSafepointLiveRegisters();

  // Calculate the maximum size of the spill area for safepoints.
  size_t CalculateMaximumSafepointSpillSize(ArrayRef<HInstruction* const> safepoints);

  // Connect adjacent siblings within blocks, and resolve inputs along the way.
  void ConnectSiblings(LiveInterval* interval);

  // Connect siblings between block entries and exits.
  void ConnectSplitSiblings(LiveInterval* interval, HBasicBlock* from, HBasicBlock* to) const;

  // Helper methods for inserting parallel moves in the graph.
  void InsertParallelMoveAtExitOf(HBasicBlock* block,
                                  HInstruction* instruction,
                                  Location source,
                                  Location destination) const;
  void InsertParallelMoveAtEntryOf(HBasicBlock* block,
                                   HInstruction* instruction,
                                   Location source,
                                   Location destination) const;
  void InsertMoveAfter(HInstruction* instruction, Location source, Location destination) const;
  void AddInputMoveFor(HInstruction* input,
                       HInstruction* user,
                       Location source,
                       Location destination) const;
  void InsertParallelMoveAt(size_t position,
                            HInstruction* instruction,
                            Location source,
                            Location destination) const;
  void AddMove(HParallelMove* move,
               Location source,
               Location destination,
               HInstruction* instruction,
               Primitive::Type type) const;

  ArenaAllocator* const allocator_;
  CodeGenerator* const codegen_;
  const SsaLivenessAnalysis& liveness_;

  DISALLOW_COPY_AND_ASSIGN(RegisterAllocationResolver);
};

}  // namespace art

#endif  // ART_COMPILER_OPTIMIZING_REGISTER_ALLOCATION_RESOLVER_H_
