/*
 * 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_ALLOCATOR_H_
#define ART_COMPILER_OPTIMIZING_REGISTER_ALLOCATOR_H_

#include "arch/instruction_set.h"
#include "base/arena_containers.h"
#include "base/arena_object.h"
#include "base/macros.h"

namespace art {

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

/**
 * Base class for any register allocator.
 */
class RegisterAllocator : public ArenaObject<kArenaAllocRegisterAllocator> {
 public:
  enum Strategy {
    kRegisterAllocatorLinearScan,
    kRegisterAllocatorGraphColor
  };

  static constexpr Strategy kRegisterAllocatorDefault = kRegisterAllocatorLinearScan;

  static RegisterAllocator* Create(ArenaAllocator* allocator,
                                   CodeGenerator* codegen,
                                   const SsaLivenessAnalysis& analysis,
                                   Strategy strategy = kRegisterAllocatorDefault);

  virtual ~RegisterAllocator() = default;

  // Main entry point for the register allocator. Given the liveness analysis,
  // allocates registers to live intervals.
  virtual void AllocateRegisters() = 0;

  // Validate that the register allocator did not allocate the same register to
  // intervals that intersect each other. Returns false if it failed.
  virtual bool Validate(bool log_fatal_on_failure) = 0;

  static bool CanAllocateRegistersFor(const HGraph& graph,
                                      InstructionSet instruction_set);

  // Verifies that live intervals do not conflict. Used by unit testing.
  static bool ValidateIntervals(const ArenaVector<LiveInterval*>& intervals,
                                size_t number_of_spill_slots,
                                size_t number_of_out_slots,
                                const CodeGenerator& codegen,
                                ArenaAllocator* allocator,
                                bool processing_core_registers,
                                bool log_fatal_on_failure);

  static constexpr const char* kRegisterAllocatorPassName = "register";

 protected:
  RegisterAllocator(ArenaAllocator* allocator,
                    CodeGenerator* codegen,
                    const SsaLivenessAnalysis& analysis);

  // Split `interval` at the position `position`. The new interval starts at `position`.
  // If `position` is at the start of `interval`, returns `interval` with its
  // register location(s) cleared.
  static LiveInterval* Split(LiveInterval* interval, size_t position);

  // Split `interval` at a position between `from` and `to`. The method will try
  // to find an optimal split position.
  LiveInterval* SplitBetween(LiveInterval* interval, size_t from, size_t to);

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

}  // namespace art

#endif  // ART_COMPILER_OPTIMIZING_REGISTER_ALLOCATOR_H_
