/*
 * Copyright (C) 2011 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.
 */

/* This file contains register alloction support. */

#include "../compiler_utility.h"
#include "../compiler_ir.h"
#include "../dataflow.h"
#include "ralloc_util.h"
#include "codegen_util.h"

namespace art {

static const RegLocation bad_loc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0,
                                    INVALID_REG, INVALID_REG, INVALID_SREG,
                                    INVALID_SREG};

/*
 * Free all allocated temps in the temp pools.  Note that this does
 * not affect the "liveness" of a temp register, which will stay
 * live until it is either explicitly killed or reallocated.
 */
void ResetRegPool(CompilationUnit* cu)
{
  int i;
  for (i=0; i < cu->reg_pool->num_core_regs; i++) {
    if (cu->reg_pool->core_regs[i].is_temp)
      cu->reg_pool->core_regs[i].in_use = false;
  }
  for (i=0; i < cu->reg_pool->num_fp_regs; i++) {
    if (cu->reg_pool->FPRegs[i].is_temp)
      cu->reg_pool->FPRegs[i].in_use = false;
  }
}

 /*
  * Set up temp & preserved register pools specialized by target.
  * Note: num_regs may be zero.
  */
void CompilerInitPool(RegisterInfo* regs, int* reg_nums, int num)
{
  int i;
  for (i=0; i < num; i++) {
    regs[i].reg = reg_nums[i];
    regs[i].in_use = false;
    regs[i].is_temp = false;
    regs[i].pair = false;
    regs[i].live = false;
    regs[i].dirty = false;
    regs[i].s_reg = INVALID_SREG;
  }
}

static void DumpRegPool(RegisterInfo* p, int num_regs)
{
  LOG(INFO) << "================================================";
  for (int i = 0; i < num_regs; i++) {
    LOG(INFO) << StringPrintf(
        "R[%d]: T:%d, U:%d, P:%d, p:%d, LV:%d, D:%d, SR:%d, ST:%x, EN:%x",
        p[i].reg, p[i].is_temp, p[i].in_use, p[i].pair, p[i].partner,
        p[i].live, p[i].dirty, p[i].s_reg, reinterpret_cast<uintptr_t>(p[i].def_start),
        reinterpret_cast<uintptr_t>(p[i].def_end));
  }
  LOG(INFO) << "================================================";
}

void DumpCoreRegPool(CompilationUnit* cu)
{
  DumpRegPool(cu->reg_pool->core_regs, cu->reg_pool->num_core_regs);
}

void DumpFpRegPool(CompilationUnit* cu)
{
  DumpRegPool(cu->reg_pool->FPRegs, cu->reg_pool->num_fp_regs);
}

/* Mark a temp register as dead.  Does not affect allocation state. */
static void ClobberBody(CompilationUnit *cu, RegisterInfo* p)
{
  if (p->is_temp) {
    DCHECK(!(p->live && p->dirty))  << "Live & dirty temp in clobber";
    p->live = false;
    p->s_reg = INVALID_SREG;
    p->def_start = NULL;
    p->def_end = NULL;
    if (p->pair) {
      p->pair = false;
      Clobber(cu, p->partner);
    }
  }
}

/* Mark a temp register as dead.  Does not affect allocation state. */
void Clobber(CompilationUnit* cu, int reg)
{
  Codegen* cg = cu->cg.get();
  ClobberBody(cu, cg->GetRegInfo(cu, reg));
}

static void ClobberSRegBody(RegisterInfo* p, int num_regs, int s_reg)
{
  int i;
  for (i=0; i< num_regs; i++) {
    if (p[i].s_reg == s_reg) {
      if (p[i].is_temp) {
        p[i].live = false;
      }
      p[i].def_start = NULL;
      p[i].def_end = NULL;
    }
  }
}

/* Clobber any temp associated with an s_reg.  Could be in either class */
void ClobberSReg(CompilationUnit* cu, int s_reg)
{
#ifndef NDEBUG
  /* Reset live temp tracking sanity checker */
  if (s_reg == cu->live_sreg) {
    cu->live_sreg = INVALID_SREG;
  }
#endif
  ClobberSRegBody(cu->reg_pool->core_regs, cu->reg_pool->num_core_regs, s_reg);
  ClobberSRegBody(cu->reg_pool->FPRegs, cu->reg_pool->num_fp_regs, s_reg);
}

/*
 * SSA names associated with the initial definitions of Dalvik
 * registers are the same as the Dalvik register number (and
 * thus take the same position in the promotion_map.  However,
 * the special Method* and compiler temp resisters use negative
 * v_reg numbers to distinguish them and can have an arbitrary
 * ssa name (above the last original Dalvik register).  This function
 * maps SSA names to positions in the promotion_map array.
 */
int SRegToPMap(CompilationUnit* cu, int s_reg)
{
  DCHECK_LT(s_reg, cu->num_ssa_regs);
  DCHECK_GE(s_reg, 0);
  int v_reg = SRegToVReg(cu, s_reg);
  if (v_reg >= 0) {
    DCHECK_LT(v_reg, cu->num_dalvik_registers);
    return v_reg;
  } else {
    int pos = std::abs(v_reg) - std::abs(SSA_METHOD_BASEREG);
    DCHECK_LE(pos, cu->num_compiler_temps);
    return cu->num_dalvik_registers + pos;
  }
}

void RecordCorePromotion(CompilationUnit* cu, int reg, int s_reg)
{
  Codegen* cg = cu->cg.get();
  int p_map_idx = SRegToPMap(cu, s_reg);
  int v_reg = SRegToVReg(cu, s_reg);
  cg->GetRegInfo(cu, reg)->in_use = true;
  cu->core_spill_mask |= (1 << reg);
  // Include reg for later sort
  cu->core_vmap_table.push_back(reg << VREG_NUM_WIDTH |
                                 (v_reg & ((1 << VREG_NUM_WIDTH) - 1)));
  cu->num_core_spills++;
  cu->promotion_map[p_map_idx].core_location = kLocPhysReg;
  cu->promotion_map[p_map_idx].core_reg = reg;
}

/* Reserve a callee-save register.  Return -1 if none available */
static int AllocPreservedCoreReg(CompilationUnit* cu, int s_reg)
{
  int res = -1;
  RegisterInfo* core_regs = cu->reg_pool->core_regs;
  for (int i = 0; i < cu->reg_pool->num_core_regs; i++) {
    if (!core_regs[i].is_temp && !core_regs[i].in_use) {
      res = core_regs[i].reg;
      RecordCorePromotion(cu, res, s_reg);
      break;
    }
  }
  return res;
}

void RecordFpPromotion(CompilationUnit* cu, int reg, int s_reg)
{
  Codegen* cg = cu->cg.get();
  int p_map_idx = SRegToPMap(cu, s_reg);
  int v_reg = SRegToVReg(cu, s_reg);
  cg->GetRegInfo(cu, reg)->in_use = true;
  cg->MarkPreservedSingle(cu, v_reg, reg);
  cu->promotion_map[p_map_idx].fp_location = kLocPhysReg;
  cu->promotion_map[p_map_idx].FpReg = reg;
}

/*
 * Reserve a callee-save fp single register.  Try to fullfill request for
 * even/odd  allocation, but go ahead and allocate anything if not
 * available.  If nothing's available, return -1.
 */
static int AllocPreservedSingle(CompilationUnit* cu, int s_reg, bool even)
{
  int res = -1;
  RegisterInfo* FPRegs = cu->reg_pool->FPRegs;
  for (int i = 0; i < cu->reg_pool->num_fp_regs; i++) {
    if (!FPRegs[i].is_temp && !FPRegs[i].in_use &&
      ((FPRegs[i].reg & 0x1) == 0) == even) {
      res = FPRegs[i].reg;
      RecordFpPromotion(cu, res, s_reg);
      break;
    }
  }
  return res;
}

/*
 * Somewhat messy code here.  We want to allocate a pair of contiguous
 * physical single-precision floating point registers starting with
 * an even numbered reg.  It is possible that the paired s_reg (s_reg+1)
 * has already been allocated - try to fit if possible.  Fail to
 * allocate if we can't meet the requirements for the pair of
 * s_reg<=sX[even] & (s_reg+1)<= sX+1.
 */
static int AllocPreservedDouble(CompilationUnit* cu, int s_reg)
{
  Codegen* cg = cu->cg.get();
  int res = -1; // Assume failure
  int v_reg = SRegToVReg(cu, s_reg);
  int p_map_idx = SRegToPMap(cu, s_reg);
  if (cu->promotion_map[p_map_idx+1].fp_location == kLocPhysReg) {
    // Upper reg is already allocated.  Can we fit?
    int high_reg = cu->promotion_map[p_map_idx+1].FpReg;
    if ((high_reg & 1) == 0) {
      // High reg is even - fail.
      return res;
    }
    // Is the low reg of the pair free?
    RegisterInfo* p = cg->GetRegInfo(cu, high_reg-1);
    if (p->in_use || p->is_temp) {
      // Already allocated or not preserved - fail.
      return res;
    }
    // OK - good to go.
    res = p->reg;
    p->in_use = true;
    DCHECK_EQ((res & 1), 0);
    cg->MarkPreservedSingle(cu, v_reg, res);
  } else {
    RegisterInfo* FPRegs = cu->reg_pool->FPRegs;
    for (int i = 0; i < cu->reg_pool->num_fp_regs; i++) {
      if (!FPRegs[i].is_temp && !FPRegs[i].in_use &&
        ((FPRegs[i].reg & 0x1) == 0x0) &&
        !FPRegs[i+1].is_temp && !FPRegs[i+1].in_use &&
        ((FPRegs[i+1].reg & 0x1) == 0x1) &&
        (FPRegs[i].reg + 1) == FPRegs[i+1].reg) {
        res = FPRegs[i].reg;
        FPRegs[i].in_use = true;
        cg->MarkPreservedSingle(cu, v_reg, res);
        FPRegs[i+1].in_use = true;
        DCHECK_EQ(res + 1, FPRegs[i+1].reg);
        cg->MarkPreservedSingle(cu, v_reg+1, res+1);
        break;
      }
    }
  }
  if (res != -1) {
    cu->promotion_map[p_map_idx].fp_location = kLocPhysReg;
    cu->promotion_map[p_map_idx].FpReg = res;
    cu->promotion_map[p_map_idx+1].fp_location = kLocPhysReg;
    cu->promotion_map[p_map_idx+1].FpReg = res + 1;
  }
  return res;
}


/*
 * Reserve a callee-save fp register.   If this register can be used
 * as the first of a double, attempt to allocate an even pair of fp
 * single regs (but if can't still attempt to allocate a single, preferring
 * first to allocate an odd register.
 */
static int AllocPreservedFPReg(CompilationUnit* cu, int s_reg, bool double_start)
{
  int res = -1;
  if (double_start) {
    res = AllocPreservedDouble(cu, s_reg);
  }
  if (res == -1) {
    res = AllocPreservedSingle(cu, s_reg, false /* try odd # */);
  }
  if (res == -1)
    res = AllocPreservedSingle(cu, s_reg, true /* try even # */);
  return res;
}

static int AllocTempBody(CompilationUnit* cu, RegisterInfo* p, int num_regs, int* next_temp,
                          bool required)
{
  int i;
  int next = *next_temp;
  for (i=0; i< num_regs; i++) {
    if (next >= num_regs)
      next = 0;
    if (p[next].is_temp && !p[next].in_use && !p[next].live) {
      Clobber(cu, p[next].reg);
      p[next].in_use = true;
      p[next].pair = false;
      *next_temp = next + 1;
      return p[next].reg;
    }
    next++;
  }
  next = *next_temp;
  for (i=0; i< num_regs; i++) {
    if (next >= num_regs)
      next = 0;
    if (p[next].is_temp && !p[next].in_use) {
      Clobber(cu, p[next].reg);
      p[next].in_use = true;
      p[next].pair = false;
      *next_temp = next + 1;
      return p[next].reg;
    }
    next++;
  }
  if (required) {
    CodegenDump(cu);
    DumpRegPool(cu->reg_pool->core_regs,
          cu->reg_pool->num_core_regs);
    LOG(FATAL) << "No free temp registers";
  }
  return -1;  // No register available
}

//REDO: too many assumptions.
int AllocTempDouble(CompilationUnit* cu)
{
  RegisterInfo* p = cu->reg_pool->FPRegs;
  int num_regs = cu->reg_pool->num_fp_regs;
  /* Start looking at an even reg */
  int next = cu->reg_pool->next_fp_reg & ~0x1;

  // First try to avoid allocating live registers
  for (int i=0; i < num_regs; i+=2) {
    if (next >= num_regs)
      next = 0;
    if ((p[next].is_temp && !p[next].in_use && !p[next].live) &&
      (p[next+1].is_temp && !p[next+1].in_use && !p[next+1].live)) {
      Clobber(cu, p[next].reg);
      Clobber(cu, p[next+1].reg);
      p[next].in_use = true;
      p[next+1].in_use = true;
      DCHECK_EQ((p[next].reg+1), p[next+1].reg);
      DCHECK_EQ((p[next].reg & 0x1), 0);
      cu->reg_pool->next_fp_reg = next + 2;
      if (cu->reg_pool->next_fp_reg >= num_regs) {
        cu->reg_pool->next_fp_reg = 0;
      }
      return p[next].reg;
    }
    next += 2;
  }
  next = cu->reg_pool->next_fp_reg & ~0x1;

  // No choice - find a pair and kill it.
  for (int i=0; i < num_regs; i+=2) {
    if (next >= num_regs)
      next = 0;
    if (p[next].is_temp && !p[next].in_use && p[next+1].is_temp &&
      !p[next+1].in_use) {
      Clobber(cu, p[next].reg);
      Clobber(cu, p[next+1].reg);
      p[next].in_use = true;
      p[next+1].in_use = true;
      DCHECK_EQ((p[next].reg+1), p[next+1].reg);
      DCHECK_EQ((p[next].reg & 0x1), 0);
      cu->reg_pool->next_fp_reg = next + 2;
      if (cu->reg_pool->next_fp_reg >= num_regs) {
        cu->reg_pool->next_fp_reg = 0;
      }
      return p[next].reg;
    }
    next += 2;
  }
  LOG(FATAL) << "No free temp registers (pair)";
  return -1;
}

/* Return a temp if one is available, -1 otherwise */
int AllocFreeTemp(CompilationUnit* cu)
{
  return AllocTempBody(cu, cu->reg_pool->core_regs,
             cu->reg_pool->num_core_regs,
             &cu->reg_pool->next_core_reg, true);
}

int AllocTemp(CompilationUnit* cu)
{
  return AllocTempBody(cu, cu->reg_pool->core_regs,
             cu->reg_pool->num_core_regs,
             &cu->reg_pool->next_core_reg, true);
}

int AllocTempFloat(CompilationUnit* cu)
{
  return AllocTempBody(cu, cu->reg_pool->FPRegs,
             cu->reg_pool->num_fp_regs,
             &cu->reg_pool->next_fp_reg, true);
}

static RegisterInfo* AllocLiveBody(RegisterInfo* p, int num_regs, int s_reg)
{
  int i;
  if (s_reg == -1)
    return NULL;
  for (i=0; i < num_regs; i++) {
    if (p[i].live && (p[i].s_reg == s_reg)) {
      if (p[i].is_temp)
        p[i].in_use = true;
      return &p[i];
    }
  }
  return NULL;
}

RegisterInfo* AllocLive(CompilationUnit* cu, int s_reg, int reg_class)
{
  RegisterInfo* res = NULL;
  switch (reg_class) {
    case kAnyReg:
      res = AllocLiveBody(cu->reg_pool->FPRegs,
                cu->reg_pool->num_fp_regs, s_reg);
      if (res)
        break;
      /* Intentional fallthrough */
    case kCoreReg:
      res = AllocLiveBody(cu->reg_pool->core_regs,
                cu->reg_pool->num_core_regs, s_reg);
      break;
    case kFPReg:
      res = AllocLiveBody(cu->reg_pool->FPRegs,
                cu->reg_pool->num_fp_regs, s_reg);
      break;
    default:
      LOG(FATAL) << "Invalid register type";
  }
  return res;
}

void FreeTemp(CompilationUnit* cu, int reg)
{
  RegisterInfo* p = cu->reg_pool->core_regs;
  int num_regs = cu->reg_pool->num_core_regs;
  int i;
  for (i=0; i< num_regs; i++) {
    if (p[i].reg == reg) {
      if (p[i].is_temp) {
        p[i].in_use = false;
      }
      p[i].pair = false;
      return;
    }
  }
  p = cu->reg_pool->FPRegs;
  num_regs = cu->reg_pool->num_fp_regs;
  for (i=0; i< num_regs; i++) {
    if (p[i].reg == reg) {
      if (p[i].is_temp) {
        p[i].in_use = false;
      }
      p[i].pair = false;
      return;
    }
  }
  LOG(FATAL) << "Tried to free a non-existant temp: r" << reg;
}

RegisterInfo* IsLive(CompilationUnit* cu, int reg)
{
  RegisterInfo* p = cu->reg_pool->core_regs;
  int num_regs = cu->reg_pool->num_core_regs;
  int i;
  for (i=0; i< num_regs; i++) {
    if (p[i].reg == reg) {
      return p[i].live ? &p[i] : NULL;
    }
  }
  p = cu->reg_pool->FPRegs;
  num_regs = cu->reg_pool->num_fp_regs;
  for (i=0; i< num_regs; i++) {
    if (p[i].reg == reg) {
      return p[i].live ? &p[i] : NULL;
    }
  }
  return NULL;
}

RegisterInfo* IsTemp(CompilationUnit* cu, int reg)
{
  Codegen* cg = cu->cg.get();
  RegisterInfo* p = cg->GetRegInfo(cu, reg);
  return (p->is_temp) ? p : NULL;
}

RegisterInfo* IsPromoted(CompilationUnit* cu, int reg)
{
  Codegen* cg = cu->cg.get();
  RegisterInfo* p = cg->GetRegInfo(cu, reg);
  return (p->is_temp) ? NULL : p;
}

bool IsDirty(CompilationUnit* cu, int reg)
{
  Codegen* cg = cu->cg.get();
  RegisterInfo* p = cg->GetRegInfo(cu, reg);
  return p->dirty;
}

/*
 * Similar to AllocTemp(), but forces the allocation of a specific
 * register.  No check is made to see if the register was previously
 * allocated.  Use with caution.
 */
void LockTemp(CompilationUnit* cu, int reg)
{
  RegisterInfo* p = cu->reg_pool->core_regs;
  int num_regs = cu->reg_pool->num_core_regs;
  int i;
  for (i=0; i< num_regs; i++) {
    if (p[i].reg == reg) {
      DCHECK(p[i].is_temp);
      p[i].in_use = true;
      p[i].live = false;
      return;
    }
  }
  p = cu->reg_pool->FPRegs;
  num_regs = cu->reg_pool->num_fp_regs;
  for (i=0; i< num_regs; i++) {
    if (p[i].reg == reg) {
      DCHECK(p[i].is_temp);
      p[i].in_use = true;
      p[i].live = false;
      return;
    }
  }
  LOG(FATAL) << "Tried to lock a non-existant temp: r" << reg;
}

static void ResetDefBody(RegisterInfo* p)
{
  p->def_start = NULL;
  p->def_end = NULL;
}

void ResetDef(CompilationUnit* cu, int reg)
{
  Codegen* cg = cu->cg.get();
  ResetDefBody(cg->GetRegInfo(cu, reg));
}

static void NullifyRange(CompilationUnit* cu, LIR *start, LIR *finish, int s_reg1, int s_reg2)
{
  if (start && finish) {
    LIR *p;
    DCHECK_EQ(s_reg1, s_reg2);
    for (p = start; ;p = p->next) {
      NopLIR(p);
      if (p == finish)
        break;
    }
  }
}

/*
 * Mark the beginning and end LIR of a def sequence.  Note that
 * on entry start points to the LIR prior to the beginning of the
 * sequence.
 */
void MarkDef(CompilationUnit* cu, RegLocation rl,
             LIR *start, LIR *finish)
{
  DCHECK(!rl.wide);
  DCHECK(start && start->next);
  DCHECK(finish);
  Codegen* cg = cu->cg.get();
  RegisterInfo* p = cg->GetRegInfo(cu, rl.low_reg);
  p->def_start = start->next;
  p->def_end = finish;
}

/*
 * Mark the beginning and end LIR of a def sequence.  Note that
 * on entry start points to the LIR prior to the beginning of the
 * sequence.
 */
void MarkDefWide(CompilationUnit* cu, RegLocation rl,
               LIR *start, LIR *finish)
{
  DCHECK(rl.wide);
  DCHECK(start && start->next);
  DCHECK(finish);
  Codegen* cg = cu->cg.get();
  RegisterInfo* p = cg->GetRegInfo(cu, rl.low_reg);
  ResetDef(cu, rl.high_reg);  // Only track low of pair
  p->def_start = start->next;
  p->def_end = finish;
}

RegLocation WideToNarrow(CompilationUnit* cu, RegLocation rl)
{
  DCHECK(rl.wide);
  Codegen* cg = cu->cg.get();
  if (rl.location == kLocPhysReg) {
    RegisterInfo* info_lo = cg->GetRegInfo(cu, rl.low_reg);
    RegisterInfo* info_hi = cg->GetRegInfo(cu, rl.high_reg);
    if (info_lo->is_temp) {
      info_lo->pair = false;
      info_lo->def_start = NULL;
      info_lo->def_end = NULL;
    }
    if (info_hi->is_temp) {
      info_hi->pair = false;
      info_hi->def_start = NULL;
      info_hi->def_end = NULL;
    }
  }
  rl.wide = false;
  return rl;
}

void ResetDefLoc(CompilationUnit* cu, RegLocation rl)
{
  DCHECK(!rl.wide);
  RegisterInfo* p = IsTemp(cu, rl.low_reg);
  if (p && !(cu->disable_opt & (1 << kSuppressLoads))) {
    DCHECK(!p->pair);
    NullifyRange(cu, p->def_start, p->def_end, p->s_reg, rl.s_reg_low);
  }
  ResetDef(cu, rl.low_reg);
}

void ResetDefLocWide(CompilationUnit* cu, RegLocation rl)
{
  DCHECK(rl.wide);
  RegisterInfo* p_low = IsTemp(cu, rl.low_reg);
  RegisterInfo* p_high = IsTemp(cu, rl.high_reg);
  if (p_low && !(cu->disable_opt & (1 << kSuppressLoads))) {
    DCHECK(p_low->pair);
    NullifyRange(cu, p_low->def_start, p_low->def_end, p_low->s_reg, rl.s_reg_low);
  }
  if (p_high && !(cu->disable_opt & (1 << kSuppressLoads))) {
    DCHECK(p_high->pair);
  }
  ResetDef(cu, rl.low_reg);
  ResetDef(cu, rl.high_reg);
}

void ResetDefTracking(CompilationUnit* cu)
{
  int i;
  for (i=0; i< cu->reg_pool->num_core_regs; i++) {
    ResetDefBody(&cu->reg_pool->core_regs[i]);
  }
  for (i=0; i< cu->reg_pool->num_fp_regs; i++) {
    ResetDefBody(&cu->reg_pool->FPRegs[i]);
  }
}

void ClobberAllRegs(CompilationUnit* cu)
{
  int i;
  for (i=0; i< cu->reg_pool->num_core_regs; i++) {
    ClobberBody(cu, &cu->reg_pool->core_regs[i]);
  }
  for (i=0; i< cu->reg_pool->num_fp_regs; i++) {
    ClobberBody(cu, &cu->reg_pool->FPRegs[i]);
  }
}

// Make sure nothing is live and dirty
static void FlushAllRegsBody(CompilationUnit* cu, RegisterInfo* info, int num_regs)
{
  Codegen* cg = cu->cg.get();
  int i;
  for (i=0; i < num_regs; i++) {
    if (info[i].live && info[i].dirty) {
      if (info[i].pair) {
        cg->FlushRegWide(cu, info[i].reg, info[i].partner);
      } else {
        cg->FlushReg(cu, info[i].reg);
      }
    }
  }
}

void FlushAllRegs(CompilationUnit* cu)
{
  FlushAllRegsBody(cu, cu->reg_pool->core_regs,
           cu->reg_pool->num_core_regs);
  FlushAllRegsBody(cu, cu->reg_pool->FPRegs,
           cu->reg_pool->num_fp_regs);
  ClobberAllRegs(cu);
}


//TUNING: rewrite all of this reg stuff.  Probably use an attribute table
static bool RegClassMatches(CompilationUnit* cu, int reg_class, int reg)
{
  Codegen* cg = cu->cg.get();
  if (reg_class == kAnyReg) {
    return true;
  } else if (reg_class == kCoreReg) {
    return !cg->IsFpReg(reg);
  } else {
    return cg->IsFpReg(reg);
  }
}

void MarkLive(CompilationUnit* cu, int reg, int s_reg)
{
  Codegen* cg = cu->cg.get();
  RegisterInfo* info = cg->GetRegInfo(cu, reg);
  if ((info->reg == reg) && (info->s_reg == s_reg) && info->live) {
    return;  /* already live */
  } else if (s_reg != INVALID_SREG) {
    ClobberSReg(cu, s_reg);
    if (info->is_temp) {
      info->live = true;
    }
  } else {
    /* Can't be live if no associated s_reg */
    DCHECK(info->is_temp);
    info->live = false;
  }
  info->s_reg = s_reg;
}

void MarkTemp(CompilationUnit* cu, int reg)
{
  Codegen* cg = cu->cg.get();
  RegisterInfo* info = cg->GetRegInfo(cu, reg);
  info->is_temp = true;
}

void UnmarkTemp(CompilationUnit* cu, int reg)
{
  Codegen* cg = cu->cg.get();
  RegisterInfo* info = cg->GetRegInfo(cu, reg);
  info->is_temp = false;
}

void MarkPair(CompilationUnit* cu, int low_reg, int high_reg)
{
  Codegen* cg = cu->cg.get();
  RegisterInfo* info_lo = cg->GetRegInfo(cu, low_reg);
  RegisterInfo* info_hi = cg->GetRegInfo(cu, high_reg);
  info_lo->pair = info_hi->pair = true;
  info_lo->partner = high_reg;
  info_hi->partner = low_reg;
}

void MarkClean(CompilationUnit* cu, RegLocation loc)
{
  Codegen* cg = cu->cg.get();
  RegisterInfo* info = cg->GetRegInfo(cu, loc.low_reg);
  info->dirty = false;
  if (loc.wide) {
    info = cg->GetRegInfo(cu, loc.high_reg);
    info->dirty = false;
  }
}

void MarkDirty(CompilationUnit* cu, RegLocation loc)
{
  if (loc.home) {
    // If already home, can't be dirty
    return;
  }
  Codegen* cg = cu->cg.get();
  RegisterInfo* info = cg->GetRegInfo(cu, loc.low_reg);
  info->dirty = true;
  if (loc.wide) {
    info = cg->GetRegInfo(cu, loc.high_reg);
    info->dirty = true;
  }
}

void MarkInUse(CompilationUnit* cu, int reg)
{
  Codegen* cg = cu->cg.get();
    RegisterInfo* info = cg->GetRegInfo(cu, reg);
    info->in_use = true;
}

static void CopyRegInfo(CompilationUnit* cu, int new_reg, int old_reg)
{
  Codegen* cg = cu->cg.get();
  RegisterInfo* new_info = cg->GetRegInfo(cu, new_reg);
  RegisterInfo* old_info = cg->GetRegInfo(cu, old_reg);
  // Target temp status must not change
  bool is_temp = new_info->is_temp;
  *new_info = *old_info;
  // Restore target's temp status
  new_info->is_temp = is_temp;
  new_info->reg = new_reg;
}

static bool CheckCorePoolSanity(CompilationUnit* cu)
{
  Codegen* cg = cu->cg.get();
   for (static int i = 0; i < cu->reg_pool->num_core_regs; i++) {
     if (cu->reg_pool->core_regs[i].pair) {
       static int my_reg = cu->reg_pool->core_regs[i].reg;
       static int my_sreg = cu->reg_pool->core_regs[i].s_reg;
       static int partner_reg = cu->reg_pool->core_regs[i].partner;
       static RegisterInfo* partner = cg->GetRegInfo(cu, partner_reg);
       DCHECK(partner != NULL);
       DCHECK(partner->pair);
       DCHECK_EQ(my_reg, partner->partner);
       static int partner_sreg = partner->s_reg;
       if (my_sreg == INVALID_SREG) {
         DCHECK_EQ(partner_sreg, INVALID_SREG);
       } else {
         int diff = my_sreg - partner_sreg;
         DCHECK((diff == -1) || (diff == 1));
       }
     }
     if (!cu->reg_pool->core_regs[i].live) {
       DCHECK(cu->reg_pool->core_regs[i].def_start == NULL);
       DCHECK(cu->reg_pool->core_regs[i].def_end == NULL);
     }
   }
   return true;
}

/*
 * Return an updated location record with current in-register status.
 * If the value lives in live temps, reflect that fact.  No code
 * is generated.  If the live value is part of an older pair,
 * clobber both low and high.
 * TUNING: clobbering both is a bit heavy-handed, but the alternative
 * is a bit complex when dealing with FP regs.  Examine code to see
 * if it's worthwhile trying to be more clever here.
 */

RegLocation UpdateLoc(CompilationUnit* cu, RegLocation loc)
{
  DCHECK(!loc.wide);
  DCHECK(CheckCorePoolSanity(cu));
  if (loc.location != kLocPhysReg) {
    DCHECK((loc.location == kLocDalvikFrame) ||
         (loc.location == kLocCompilerTemp));
    RegisterInfo* info_lo = AllocLive(cu, loc.s_reg_low, kAnyReg);
    if (info_lo) {
      if (info_lo->pair) {
        Clobber(cu, info_lo->reg);
        Clobber(cu, info_lo->partner);
        FreeTemp(cu, info_lo->reg);
      } else {
        loc.low_reg = info_lo->reg;
        loc.location = kLocPhysReg;
      }
    }
  }

  return loc;
}

/* see comments for update_loc */
RegLocation UpdateLocWide(CompilationUnit* cu, RegLocation loc)
{
  DCHECK(loc.wide);
  DCHECK(CheckCorePoolSanity(cu));
  Codegen* cg = cu->cg.get();
  if (loc.location != kLocPhysReg) {
    DCHECK((loc.location == kLocDalvikFrame) ||
         (loc.location == kLocCompilerTemp));
    // Are the dalvik regs already live in physical registers?
    RegisterInfo* info_lo = AllocLive(cu, loc.s_reg_low, kAnyReg);
    RegisterInfo* info_hi = AllocLive(cu,
        GetSRegHi(loc.s_reg_low), kAnyReg);
    bool match = true;
    match = match && (info_lo != NULL);
    match = match && (info_hi != NULL);
    // Are they both core or both FP?
    match = match && (cg->IsFpReg(info_lo->reg) == cg->IsFpReg(info_hi->reg));
    // If a pair of floating point singles, are they properly aligned?
    if (match && cg->IsFpReg(info_lo->reg)) {
      match &= ((info_lo->reg & 0x1) == 0);
      match &= ((info_hi->reg - info_lo->reg) == 1);
    }
    // If previously used as a pair, it is the same pair?
    if (match && (info_lo->pair || info_hi->pair)) {
      match = (info_lo->pair == info_hi->pair);
      match &= ((info_lo->reg == info_hi->partner) &&
            (info_hi->reg == info_lo->partner));
    }
    if (match) {
      // Can reuse - update the register usage info
      loc.low_reg = info_lo->reg;
      loc.high_reg = info_hi->reg;
      loc.location = kLocPhysReg;
      MarkPair(cu, loc.low_reg, loc.high_reg);
      DCHECK(!cg->IsFpReg(loc.low_reg) || ((loc.low_reg & 0x1) == 0));
      return loc;
    }
    // Can't easily reuse - clobber and free any overlaps
    if (info_lo) {
      Clobber(cu, info_lo->reg);
      FreeTemp(cu, info_lo->reg);
      if (info_lo->pair)
        Clobber(cu, info_lo->partner);
    }
    if (info_hi) {
      Clobber(cu, info_hi->reg);
      FreeTemp(cu, info_hi->reg);
      if (info_hi->pair)
        Clobber(cu, info_hi->partner);
    }
  }
  return loc;
}


/* For use in cases we don't know (or care) width */
RegLocation UpdateRawLoc(CompilationUnit* cu, RegLocation loc)
{
  if (loc.wide)
    return UpdateLocWide(cu, loc);
  else
    return UpdateLoc(cu, loc);
}

RegLocation EvalLocWide(CompilationUnit* cu, RegLocation loc, int reg_class, bool update)
{
  DCHECK(loc.wide);
  int new_regs;
  int low_reg;
  int high_reg;
  Codegen* cg = cu->cg.get();

  loc = UpdateLocWide(cu, loc);

  /* If already in registers, we can assume proper form.  Right reg class? */
  if (loc.location == kLocPhysReg) {
    DCHECK_EQ(cg->IsFpReg(loc.low_reg), cg->IsFpReg(loc.high_reg));
    DCHECK(!cg->IsFpReg(loc.low_reg) || ((loc.low_reg & 0x1) == 0));
    if (!RegClassMatches(cu, reg_class, loc.low_reg)) {
      /* Wrong register class.  Reallocate and copy */
      new_regs = cg->AllocTypedTempPair(cu, loc.fp, reg_class);
      low_reg = new_regs & 0xff;
      high_reg = (new_regs >> 8) & 0xff;
      cg->OpRegCopyWide(cu, low_reg, high_reg, loc.low_reg, loc.high_reg);
      CopyRegInfo(cu, low_reg, loc.low_reg);
      CopyRegInfo(cu, high_reg, loc.high_reg);
      Clobber(cu, loc.low_reg);
      Clobber(cu, loc.high_reg);
      loc.low_reg = low_reg;
      loc.high_reg = high_reg;
      MarkPair(cu, loc.low_reg, loc.high_reg);
      DCHECK(!cg->IsFpReg(loc.low_reg) || ((loc.low_reg & 0x1) == 0));
    }
    return loc;
  }

  DCHECK_NE(loc.s_reg_low, INVALID_SREG);
  DCHECK_NE(GetSRegHi(loc.s_reg_low), INVALID_SREG);

  new_regs = cg->AllocTypedTempPair(cu, loc.fp, reg_class);
  loc.low_reg = new_regs & 0xff;
  loc.high_reg = (new_regs >> 8) & 0xff;

  MarkPair(cu, loc.low_reg, loc.high_reg);
  if (update) {
    loc.location = kLocPhysReg;
    MarkLive(cu, loc.low_reg, loc.s_reg_low);
    MarkLive(cu, loc.high_reg, GetSRegHi(loc.s_reg_low));
  }
  DCHECK(!cg->IsFpReg(loc.low_reg) || ((loc.low_reg & 0x1) == 0));
  return loc;
}

RegLocation EvalLoc(CompilationUnit* cu, RegLocation loc,
                int reg_class, bool update)
{
  int new_reg;

  if (loc.wide)
    return EvalLocWide(cu, loc, reg_class, update);

  Codegen* cg = cu->cg.get();
  loc = UpdateLoc(cu, loc);

  if (loc.location == kLocPhysReg) {
    if (!RegClassMatches(cu, reg_class, loc.low_reg)) {
      /* Wrong register class.  Realloc, copy and transfer ownership */
      new_reg = cg->AllocTypedTemp(cu, loc.fp, reg_class);
      cg->OpRegCopy(cu, new_reg, loc.low_reg);
      CopyRegInfo(cu, new_reg, loc.low_reg);
      Clobber(cu, loc.low_reg);
      loc.low_reg = new_reg;
    }
    return loc;
  }

  DCHECK_NE(loc.s_reg_low, INVALID_SREG);

  new_reg = cg->AllocTypedTemp(cu, loc.fp, reg_class);
  loc.low_reg = new_reg;

  if (update) {
    loc.location = kLocPhysReg;
    MarkLive(cu, loc.low_reg, loc.s_reg_low);
  }
  return loc;
}

RegLocation GetRawSrc(CompilationUnit* cu, MIR* mir, int num)
{
  DCHECK(num < mir->ssa_rep->num_uses);
  RegLocation res = cu->reg_location[mir->ssa_rep->uses[num]];
  return res;
}

RegLocation GetRawDest(CompilationUnit* cu, MIR* mir)
{
  DCHECK_GT(mir->ssa_rep->num_defs, 0);
  RegLocation res = cu->reg_location[mir->ssa_rep->defs[0]];
  return res;
}

RegLocation GetDest(CompilationUnit* cu, MIR* mir)
{
  RegLocation res = GetRawDest(cu, mir);
  DCHECK(!res.wide);
  return res;
}

RegLocation GetSrc(CompilationUnit* cu, MIR* mir, int num)
{
  RegLocation res = GetRawSrc(cu, mir, num);
  DCHECK(!res.wide);
  return res;
}

RegLocation GetDestWide(CompilationUnit* cu, MIR* mir)
{
  RegLocation res = GetRawDest(cu, mir);
  DCHECK(res.wide);
  return res;
}

RegLocation GetSrcWide(CompilationUnit* cu, MIR* mir,
                 int low)
{
  RegLocation res = GetRawSrc(cu, mir, low);
  DCHECK(res.wide);
  return res;
}

/* USE SSA names to count references of base Dalvik v_regs. */
static void CountRefs(CompilationUnit *cu, BasicBlock* bb, RefCounts* core_counts,
                      RefCounts* fp_counts)
{
  if ((cu->disable_opt & (1 << kPromoteRegs)) ||
    !((bb->block_type == kEntryBlock) || (bb->block_type == kExitBlock) ||
      (bb->block_type == kDalvikByteCode))) {
    return;
  }
  for (int i = 0; i < cu->num_ssa_regs;) {
    RegLocation loc = cu->reg_location[i];
    RefCounts* counts = loc.fp ? fp_counts : core_counts;
    int p_map_idx = SRegToPMap(cu, loc.s_reg_low);
    if (loc.defined) {
      counts[p_map_idx].count += cu->use_counts.elem_list[i];
    }
    if (loc.wide) {
      if (loc.defined) {
        if (loc.fp) {
          counts[p_map_idx].double_start = true;
          counts[p_map_idx+1].count += cu->use_counts.elem_list[i+1];
        }
      }
      i += 2;
    } else {
      i++;
    }
  }
}

/* qsort callback function, sort descending */
static int SortCounts(const void *val1, const void *val2)
{
  const RefCounts* op1 = reinterpret_cast<const RefCounts*>(val1);
  const RefCounts* op2 = reinterpret_cast<const RefCounts*>(val2);
  return (op1->count == op2->count) ? 0 : (op1->count < op2->count ? 1 : -1);
}

static void DumpCounts(const RefCounts* arr, int size, const char* msg)
{
  LOG(INFO) << msg;
  for (int i = 0; i < size; i++) {
    LOG(INFO) << "s_reg[" << arr[i].s_reg << "]: " << arr[i].count;
  }
}

/*
 * Note: some portions of this code required even if the kPromoteRegs
 * optimization is disabled.
 */
void DoPromotion(CompilationUnit* cu)
{
  Codegen* cg = cu->cg.get();
  int reg_bias = cu->num_compiler_temps + 1;
  int dalvik_regs = cu->num_dalvik_registers;
  int num_regs = dalvik_regs + reg_bias;
  const int promotion_threshold = 2;

  // Allow target code to add any special registers
  cg->AdjustSpillMask(cu);

  /*
   * Simple register promotion. Just do a static count of the uses
   * of Dalvik registers.  Note that we examine the SSA names, but
   * count based on original Dalvik register name.  Count refs
   * separately based on type in order to give allocation
   * preference to fp doubles - which must be allocated sequential
   * physical single fp registers started with an even-numbered
   * reg.
   * TUNING: replace with linear scan once we have the ability
   * to describe register live ranges for GC.
   */
  RefCounts *core_regs = static_cast<RefCounts*>(NewMem(cu, sizeof(RefCounts) * num_regs,
                                                       true, kAllocRegAlloc));
  RefCounts *FpRegs = static_cast<RefCounts *>(NewMem(cu, sizeof(RefCounts) * num_regs,
                                                      true, kAllocRegAlloc));
  // Set ssa names for original Dalvik registers
  for (int i = 0; i < dalvik_regs; i++) {
    core_regs[i].s_reg = FpRegs[i].s_reg = i;
  }
  // Set ssa name for Method*
  core_regs[dalvik_regs].s_reg = cu->method_sreg;
  FpRegs[dalvik_regs].s_reg = cu->method_sreg;  // For consistecy
  // Set ssa names for compiler_temps
  for (int i = 1; i <= cu->num_compiler_temps; i++) {
    CompilerTemp* ct = reinterpret_cast<CompilerTemp*>(cu->compiler_temps.elem_list[i]);
    core_regs[dalvik_regs + i].s_reg = ct->s_reg;
    FpRegs[dalvik_regs + i].s_reg = ct->s_reg;
  }

  GrowableListIterator iterator;
  GrowableListIteratorInit(&cu->block_list, &iterator);
  while (true) {
    BasicBlock* bb;
    bb = reinterpret_cast<BasicBlock*>(GrowableListIteratorNext(&iterator));
    if (bb == NULL) break;
    CountRefs(cu, bb, core_regs, FpRegs);
  }

  /*
   * Ideally, we'd allocate doubles starting with an even-numbered
   * register.  Bias the counts to try to allocate any vreg that's
   * used as the start of a pair first.
   */
  for (int i = 0; i < num_regs; i++) {
    if (FpRegs[i].double_start) {
      FpRegs[i].count *= 2;
    }
  }

  // Sort the count arrays
  qsort(core_regs, num_regs, sizeof(RefCounts), SortCounts);
  qsort(FpRegs, num_regs, sizeof(RefCounts), SortCounts);

  if (cu->verbose) {
    DumpCounts(core_regs, num_regs, "Core regs after sort");
    DumpCounts(FpRegs, num_regs, "Fp regs after sort");
  }

  if (!(cu->disable_opt & (1 << kPromoteRegs))) {
    // Promote FpRegs
    for (int i = 0; (i < num_regs) &&
            (FpRegs[i].count >= promotion_threshold ); i++) {
      int p_map_idx = SRegToPMap(cu, FpRegs[i].s_reg);
      if (cu->promotion_map[p_map_idx].fp_location != kLocPhysReg) {
        int reg = AllocPreservedFPReg(cu, FpRegs[i].s_reg,
          FpRegs[i].double_start);
        if (reg < 0) {
          break;  // No more left
        }
      }
    }

    // Promote core regs
    for (int i = 0; (i < num_regs) &&
            (core_regs[i].count > promotion_threshold); i++) {
      int p_map_idx = SRegToPMap(cu, core_regs[i].s_reg);
      if (cu->promotion_map[p_map_idx].core_location !=
          kLocPhysReg) {
        int reg = AllocPreservedCoreReg(cu, core_regs[i].s_reg);
        if (reg < 0) {
           break;  // No more left
        }
      }
    }
  } else if (cu->qd_mode) {
    AllocPreservedCoreReg(cu, cu->method_sreg);
    for (int i = 0; i < num_regs; i++) {
      int reg = AllocPreservedCoreReg(cu, i);
      if (reg < 0) {
         break;  // No more left
      }
    }
  }


  // Now, update SSA names to new home locations
  for (int i = 0; i < cu->num_ssa_regs; i++) {
    RegLocation *curr = &cu->reg_location[i];
    int p_map_idx = SRegToPMap(cu, curr->s_reg_low);
    if (!curr->wide) {
      if (curr->fp) {
        if (cu->promotion_map[p_map_idx].fp_location == kLocPhysReg) {
          curr->location = kLocPhysReg;
          curr->low_reg = cu->promotion_map[p_map_idx].FpReg;
          curr->home = true;
        }
      } else {
        if (cu->promotion_map[p_map_idx].core_location == kLocPhysReg) {
          curr->location = kLocPhysReg;
          curr->low_reg = cu->promotion_map[p_map_idx].core_reg;
          curr->home = true;
        }
      }
      curr->high_reg = INVALID_REG;
    } else {
      if (curr->high_word) {
        continue;
      }
      if (curr->fp) {
        if ((cu->promotion_map[p_map_idx].fp_location == kLocPhysReg) &&
          (cu->promotion_map[p_map_idx+1].fp_location ==
          kLocPhysReg)) {
          int low_reg = cu->promotion_map[p_map_idx].FpReg;
          int high_reg = cu->promotion_map[p_map_idx+1].FpReg;
          // Doubles require pair of singles starting at even reg
          if (((low_reg & 0x1) == 0) && ((low_reg + 1) == high_reg)) {
            curr->location = kLocPhysReg;
            curr->low_reg = low_reg;
            curr->high_reg = high_reg;
            curr->home = true;
          }
        }
      } else {
        if ((cu->promotion_map[p_map_idx].core_location == kLocPhysReg)
           && (cu->promotion_map[p_map_idx+1].core_location ==
           kLocPhysReg)) {
          curr->location = kLocPhysReg;
          curr->low_reg = cu->promotion_map[p_map_idx].core_reg;
          curr->high_reg = cu->promotion_map[p_map_idx+1].core_reg;
          curr->home = true;
        }
      }
    }
  }
  if (cu->verbose) {
    DumpPromotionMap(cu);
  }
}

/* Returns sp-relative offset in bytes for a VReg */
int VRegOffset(CompilationUnit* cu, int v_reg)
{
  return StackVisitor::GetVRegOffset(cu->code_item, cu->core_spill_mask,
                                     cu->fp_spill_mask, cu->frame_size, v_reg);
}

/* Returns sp-relative offset in bytes for a SReg */
int SRegOffset(CompilationUnit* cu, int s_reg)
{
  return VRegOffset(cu, SRegToVReg(cu, s_reg));
}

RegLocation GetBadLoc()
{
  RegLocation res = bad_loc;
  return res;
}

/* Mark register usage state and return long retloc */
RegLocation GetReturnWide(CompilationUnit* cu, bool is_double)
{
  Codegen* cg = cu->cg.get();
  RegLocation gpr_res = cg->LocCReturnWide();
  RegLocation fpr_res = cg->LocCReturnDouble();
  RegLocation res = is_double ? fpr_res : gpr_res;
  Clobber(cu, res.low_reg);
  Clobber(cu, res.high_reg);
  LockTemp(cu, res.low_reg);
  LockTemp(cu, res.high_reg);
  MarkPair(cu, res.low_reg, res.high_reg);
  return res;
}

RegLocation GetReturn(CompilationUnit* cu, bool is_float)
{
  Codegen* cg = cu->cg.get();
  RegLocation gpr_res = cg->LocCReturn();
  RegLocation fpr_res = cg->LocCReturnFloat();
  RegLocation res = is_float ? fpr_res : gpr_res;
  Clobber(cu, res.low_reg);
  if (cu->instruction_set == kMips) {
    MarkInUse(cu, res.low_reg);
  } else {
    LockTemp(cu, res.low_reg);
  }
  return res;
}

}  // namespace art
