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

#include "compiler_internals.h"
#include "dataflow.h"
#include "codegen/ralloc_util.h"

namespace art {

static bool SetFp(CompilationUnit* cu, int index, bool is_fp) {
  bool change = false;
  if (is_fp && !cu->reg_location[index].fp) {
    cu->reg_location[index].fp = true;
    cu->reg_location[index].defined = true;
    change = true;
  }
  return change;
}

static bool SetCore(CompilationUnit* cu, int index, bool is_core) {
  bool change = false;
  if (is_core && !cu->reg_location[index].defined) {
    cu->reg_location[index].core = true;
    cu->reg_location[index].defined = true;
    change = true;
  }
  return change;
}

static bool SetRef(CompilationUnit* cu, int index, bool is_ref) {
  bool change = false;
  if (is_ref && !cu->reg_location[index].defined) {
    cu->reg_location[index].ref = true;
    cu->reg_location[index].defined = true;
    change = true;
  }
  return change;
}

static bool SetWide(CompilationUnit* cu, int index, bool is_wide) {
  bool change = false;
  if (is_wide && !cu->reg_location[index].wide) {
    cu->reg_location[index].wide = true;
    change = true;
  }
  return change;
}

static bool SetHigh(CompilationUnit* cu, int index, bool is_high) {
  bool change = false;
  if (is_high && !cu->reg_location[index].high_word) {
    cu->reg_location[index].high_word = true;
    change = true;
  }
  return change;
}

/*
 * Infer types and sizes.  We don't need to track change on sizes,
 * as it doesn't propagate.  We're guaranteed at least one pass through
 * the cfg.
 */
static bool InferTypeAndSize(CompilationUnit* cu, BasicBlock* bb)
{
  MIR *mir;
  bool changed = false;   // Did anything change?

  if (bb->data_flow_info == NULL) return false;
  if (bb->block_type != kDalvikByteCode && bb->block_type != kEntryBlock)
    return false;

  for (mir = bb->first_mir_insn; mir != NULL; mir = mir->next) {
    SSARepresentation *ssa_rep = mir->ssa_rep;
    if (ssa_rep) {
      int attrs = oat_data_flow_attributes[mir->dalvikInsn.opcode];

      // Handle defs
      if (attrs & DF_DA) {
        if (attrs & DF_CORE_A) {
          changed |= SetCore(cu, ssa_rep->defs[0], true);
        }
        if (attrs & DF_REF_A) {
          changed |= SetRef(cu, ssa_rep->defs[0], true);
        }
        if (attrs & DF_A_WIDE) {
          cu->reg_location[ssa_rep->defs[0]].wide = true;
          cu->reg_location[ssa_rep->defs[1]].wide = true;
          cu->reg_location[ssa_rep->defs[1]].high_word = true;
          DCHECK_EQ(SRegToVReg(cu, ssa_rep->defs[0])+1,
          SRegToVReg(cu, ssa_rep->defs[1]));
        }
      }

      // Handles uses
      int next = 0;
      if (attrs & DF_UA) {
        if (attrs & DF_CORE_A) {
          changed |= SetCore(cu, ssa_rep->uses[next], true);
        }
        if (attrs & DF_REF_A) {
          changed |= SetRef(cu, ssa_rep->uses[next], true);
        }
        if (attrs & DF_A_WIDE) {
          cu->reg_location[ssa_rep->uses[next]].wide = true;
          cu->reg_location[ssa_rep->uses[next + 1]].wide = true;
          cu->reg_location[ssa_rep->uses[next + 1]].high_word = true;
          DCHECK_EQ(SRegToVReg(cu, ssa_rep->uses[next])+1,
          SRegToVReg(cu, ssa_rep->uses[next + 1]));
          next += 2;
        } else {
          next++;
        }
      }
      if (attrs & DF_UB) {
        if (attrs & DF_CORE_B) {
          changed |= SetCore(cu, ssa_rep->uses[next], true);
        }
        if (attrs & DF_REF_B) {
          changed |= SetRef(cu, ssa_rep->uses[next], true);
        }
        if (attrs & DF_B_WIDE) {
          cu->reg_location[ssa_rep->uses[next]].wide = true;
          cu->reg_location[ssa_rep->uses[next + 1]].wide = true;
          cu->reg_location[ssa_rep->uses[next + 1]].high_word = true;
          DCHECK_EQ(SRegToVReg(cu, ssa_rep->uses[next])+1,
                               SRegToVReg(cu, ssa_rep->uses[next + 1]));
          next += 2;
        } else {
          next++;
        }
      }
      if (attrs & DF_UC) {
        if (attrs & DF_CORE_C) {
          changed |= SetCore(cu, ssa_rep->uses[next], true);
        }
        if (attrs & DF_REF_C) {
          changed |= SetRef(cu, ssa_rep->uses[next], true);
        }
        if (attrs & DF_C_WIDE) {
          cu->reg_location[ssa_rep->uses[next]].wide = true;
          cu->reg_location[ssa_rep->uses[next + 1]].wide = true;
          cu->reg_location[ssa_rep->uses[next + 1]].high_word = true;
          DCHECK_EQ(SRegToVReg(cu, ssa_rep->uses[next])+1,
          SRegToVReg(cu, ssa_rep->uses[next + 1]));
        }
      }

      // Special-case return handling
      if ((mir->dalvikInsn.opcode == Instruction::RETURN) ||
          (mir->dalvikInsn.opcode == Instruction::RETURN_WIDE) ||
          (mir->dalvikInsn.opcode == Instruction::RETURN_OBJECT)) {
        switch(cu->shorty[0]) {
            case 'I':
              changed |= SetCore(cu, ssa_rep->uses[0], true);
              break;
            case 'J':
              changed |= SetCore(cu, ssa_rep->uses[0], true);
              changed |= SetCore(cu, ssa_rep->uses[1], true);
              cu->reg_location[ssa_rep->uses[0]].wide = true;
              cu->reg_location[ssa_rep->uses[1]].wide = true;
              cu->reg_location[ssa_rep->uses[1]].high_word = true;
              break;
            case 'F':
              changed |= SetFp(cu, ssa_rep->uses[0], true);
              break;
            case 'D':
              changed |= SetFp(cu, ssa_rep->uses[0], true);
              changed |= SetFp(cu, ssa_rep->uses[1], true);
              cu->reg_location[ssa_rep->uses[0]].wide = true;
              cu->reg_location[ssa_rep->uses[1]].wide = true;
              cu->reg_location[ssa_rep->uses[1]].high_word = true;
              break;
            case 'L':
              changed |= SetRef(cu, ssa_rep->uses[0], true);
              break;
            default: break;
        }
      }

      // Special-case handling for format 35c/3rc invokes
      Instruction::Code opcode = mir->dalvikInsn.opcode;
      int flags = (static_cast<int>(opcode) >= kNumPackedOpcodes)
          ? 0 : Instruction::FlagsOf(mir->dalvikInsn.opcode);
      if ((flags & Instruction::kInvoke) &&
          (attrs & (DF_FORMAT_35C | DF_FORMAT_3RC))) {
        DCHECK_EQ(next, 0);
        int target_idx = mir->dalvikInsn.vB;
        const char* shorty = GetShortyFromTargetIdx(cu, target_idx);
        // Handle result type if floating point
        if ((shorty[0] == 'F') || (shorty[0] == 'D')) {
          MIR* move_result_mir = FindMoveResult(cu, bb, mir);
          // Result might not be used at all, so no move-result
          if (move_result_mir && (move_result_mir->dalvikInsn.opcode !=
              Instruction::MOVE_RESULT_OBJECT)) {
            SSARepresentation* tgt_rep = move_result_mir->ssa_rep;
            DCHECK(tgt_rep != NULL);
            tgt_rep->fp_def[0] = true;
            changed |= SetFp(cu, tgt_rep->defs[0], true);
            if (shorty[0] == 'D') {
              tgt_rep->fp_def[1] = true;
              changed |= SetFp(cu, tgt_rep->defs[1], true);
            }
          }
        }
        int num_uses = mir->dalvikInsn.vA;
        // If this is a non-static invoke, mark implicit "this"
        if (((mir->dalvikInsn.opcode != Instruction::INVOKE_STATIC) &&
            (mir->dalvikInsn.opcode != Instruction::INVOKE_STATIC_RANGE))) {
          cu->reg_location[ssa_rep->uses[next]].defined = true;
          cu->reg_location[ssa_rep->uses[next]].ref = true;
          next++;
        }
        uint32_t cpos = 1;
        if (strlen(shorty) > 1) {
          for (int i = next; i < num_uses;) {
            DCHECK_LT(cpos, strlen(shorty));
            switch (shorty[cpos++]) {
              case 'D':
                ssa_rep->fp_use[i] = true;
                ssa_rep->fp_use[i+1] = true;
                cu->reg_location[ssa_rep->uses[i]].wide = true;
                cu->reg_location[ssa_rep->uses[i+1]].wide = true;
                cu->reg_location[ssa_rep->uses[i+1]].high_word = true;
                DCHECK_EQ(SRegToVReg(cu, ssa_rep->uses[i])+1,
                                     SRegToVReg(cu, ssa_rep->uses[i+1]));
                i++;
                break;
              case 'J':
                cu->reg_location[ssa_rep->uses[i]].wide = true;
                cu->reg_location[ssa_rep->uses[i+1]].wide = true;
                cu->reg_location[ssa_rep->uses[i+1]].high_word = true;
                DCHECK_EQ(SRegToVReg(cu, ssa_rep->uses[i])+1,
                                     SRegToVReg(cu, ssa_rep->uses[i+1]));
                changed |= SetCore(cu, ssa_rep->uses[i],true);
                i++;
                break;
              case 'F':
                ssa_rep->fp_use[i] = true;
                break;
              case 'L':
                changed |= SetRef(cu,ssa_rep->uses[i], true);
                break;
              default:
                changed |= SetCore(cu,ssa_rep->uses[i], true);
                break;
            }
            i++;
          }
        }
      }

      for (int i=0; ssa_rep->fp_use && i< ssa_rep->num_uses; i++) {
        if (ssa_rep->fp_use[i])
          changed |= SetFp(cu, ssa_rep->uses[i], true);
        }
      for (int i=0; ssa_rep->fp_def && i< ssa_rep->num_defs; i++) {
        if (ssa_rep->fp_def[i])
          changed |= SetFp(cu, ssa_rep->defs[i], true);
        }
      // Special-case handling for moves & Phi
      if (attrs & (DF_IS_MOVE | DF_NULL_TRANSFER_N)) {
        /*
         * If any of our inputs or outputs is defined, set all.
         * Some ugliness related to Phi nodes and wide values.
         * The Phi set will include all low words or all high
         * words, so we have to treat them specially.
         */
        bool is_phi = (static_cast<int>(mir->dalvikInsn.opcode) ==
                      kMirOpPhi);
        RegLocation rl_temp = cu->reg_location[ssa_rep->defs[0]];
        bool defined_fp = rl_temp.defined && rl_temp.fp;
        bool defined_core = rl_temp.defined && rl_temp.core;
        bool defined_ref = rl_temp.defined && rl_temp.ref;
        bool is_wide = rl_temp.wide || ((attrs & DF_A_WIDE) != 0);
        bool is_high = is_phi && rl_temp.wide && rl_temp.high_word;
        for (int i = 0; i < ssa_rep->num_uses;i++) {
          rl_temp = cu->reg_location[ssa_rep->uses[i]];
          defined_fp |= rl_temp.defined && rl_temp.fp;
          defined_core |= rl_temp.defined && rl_temp.core;
          defined_ref |= rl_temp.defined && rl_temp.ref;
          is_wide |= rl_temp.wide;
          is_high |= is_phi && rl_temp.wide && rl_temp.high_word;
        }
        /*
         * TODO: cleaner fix
         * We don't normally expect to see a Dalvik register
         * definition used both as a floating point and core
         * value.  However, the instruction rewriting that occurs
         * during verification can eliminate some type information,
         * leaving us confused.  The real fix here is either to
         * add explicit type information to Dalvik byte codes,
         * or to recognize THROW_VERIFICATION_ERROR as
         * an unconditional branch and support dead code elimination.
         * As a workaround we can detect this situation and
         * disable register promotion (which is the only thing that
         * relies on distinctions between core and fp usages.
         */
        if ((defined_fp && (defined_core | defined_ref)) &&
            ((cu->disable_opt & (1 << kPromoteRegs)) == 0)) {
          LOG(WARNING) << PrettyMethod(cu->method_idx, *cu->dex_file)
                       << " op at block " << bb->id
                       << " has both fp and core/ref uses for same def.";
          cu->disable_opt |= (1 << kPromoteRegs);
        }
        changed |= SetFp(cu, ssa_rep->defs[0], defined_fp);
        changed |= SetCore(cu, ssa_rep->defs[0], defined_core);
        changed |= SetRef(cu, ssa_rep->defs[0], defined_ref);
        changed |= SetWide(cu, ssa_rep->defs[0], is_wide);
        changed |= SetHigh(cu, ssa_rep->defs[0], is_high);
        if (attrs & DF_A_WIDE) {
          changed |= SetWide(cu, ssa_rep->defs[1], true);
          changed |= SetHigh(cu, ssa_rep->defs[1], true);
        }
        for (int i = 0; i < ssa_rep->num_uses; i++) {
          changed |= SetFp(cu, ssa_rep->uses[i], defined_fp);
          changed |= SetCore(cu, ssa_rep->uses[i], defined_core);
          changed |= SetRef(cu, ssa_rep->uses[i], defined_ref);
          changed |= SetWide(cu, ssa_rep->uses[i], is_wide);
          changed |= SetHigh(cu, ssa_rep->uses[i], is_high);
        }
        if (attrs & DF_A_WIDE) {
          DCHECK_EQ(ssa_rep->num_uses, 2);
          changed |= SetWide(cu, ssa_rep->uses[1], true);
          changed |= SetHigh(cu, ssa_rep->uses[1], true);
        }
      }
    }
  }
  return changed;
}

static const char* storage_name[] = {" Frame ", "PhysReg", " Spill "};

static void DumpRegLocTable(CompilationUnit* cu, RegLocation* table, int count)
{
  Codegen* cg = cu->cg.get();
  for (int i = 0; i < count; i++) {
    LOG(INFO) << StringPrintf("Loc[%02d] : %s, %c %c %c %c %c %c %c%d %c%d S%d",
        table[i].orig_sreg, storage_name[table[i].location],
        table[i].wide ? 'W' : 'N', table[i].defined ? 'D' : 'U',
        table[i].fp ? 'F' : table[i].ref ? 'R' :'C',
        table[i].is_const ? 'c' : 'n',
        table[i].high_word ? 'H' : 'L', table[i].home ? 'h' : 't',
        cg->IsFpReg(table[i].low_reg) ? 's' : 'r',
        table[i].low_reg & cg->FpRegMask(),
        cg->IsFpReg(table[i].high_reg) ? 's' : 'r',
        table[i].high_reg & cg->FpRegMask(), table[i].s_reg_low);
  }
}

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

int ComputeFrameSize(CompilationUnit* cu) {
  /* Figure out the frame size */
  static const uint32_t kAlignMask = kStackAlignment - 1;
  uint32_t size = (cu->num_core_spills + cu->num_fp_spills +
                   1 /* filler word */ + cu->num_regs + cu->num_outs +
                   cu->num_compiler_temps + 1 /* cur_method* */)
                   * sizeof(uint32_t);
  /* Align and set */
  return (size + kAlignMask) & ~(kAlignMask);
}

/*
 * Simple register allocation.  Some Dalvik virtual registers may
 * be promoted to physical registers.  Most of the work for temp
 * allocation is done on the fly.  We also do some initialization and
 * type inference here.
 */
void SimpleRegAlloc(CompilationUnit* cu)
{
  int i;
  RegLocation* loc;

  /* Allocate the location map */
  loc = static_cast<RegLocation*>(NewMem(cu, cu->num_ssa_regs * sizeof(*loc),
                                  true, kAllocRegAlloc));
  for (i=0; i< cu->num_ssa_regs; i++) {
    loc[i] = fresh_loc;
    loc[i].s_reg_low = i;
    loc[i].is_const = IsBitSet(cu->is_constant_v, i);
  }

  /* Patch up the locations for Method* and the compiler temps */
  loc[cu->method_sreg].location = kLocCompilerTemp;
  loc[cu->method_sreg].defined = true;
  for (i = 0; i < cu->num_compiler_temps; i++) {
    CompilerTemp* ct = reinterpret_cast<CompilerTemp*>(cu->compiler_temps.elem_list[i]);
    loc[ct->s_reg].location = kLocCompilerTemp;
    loc[ct->s_reg].defined = true;
  }

  cu->reg_location = loc;

  /* Allocation the promotion map */
  int num_regs = cu->num_dalvik_registers;
  cu->promotion_map = static_cast<PromotionMap*>
      (NewMem(cu, (num_regs + cu->num_compiler_temps + 1) * sizeof(cu->promotion_map[0]),
              true, kAllocRegAlloc));

  /* Add types of incoming arguments based on signature */
  int num_ins = cu->num_ins;
  if (num_ins > 0) {
    int s_reg = num_regs - num_ins;
    if ((cu->access_flags & kAccStatic) == 0) {
      // For non-static, skip past "this"
      cu->reg_location[s_reg].defined = true;
      cu->reg_location[s_reg].ref = true;
      s_reg++;
    }
    const char* shorty = cu->shorty;
    int shorty_len = strlen(shorty);
    for (int i = 1; i < shorty_len; i++) {
      switch (shorty[i]) {
        case 'D':
          cu->reg_location[s_reg].wide = true;
          cu->reg_location[s_reg+1].high_word = true;
          cu->reg_location[s_reg+1].fp = true;
          DCHECK_EQ(SRegToVReg(cu, s_reg)+1, SRegToVReg(cu, s_reg+1));
          cu->reg_location[s_reg].fp = true;
          cu->reg_location[s_reg].defined = true;
          s_reg++;
          break;
        case 'J':
          cu->reg_location[s_reg].wide = true;
          cu->reg_location[s_reg+1].high_word = true;
          DCHECK_EQ(SRegToVReg(cu, s_reg)+1, SRegToVReg(cu, s_reg+1));
          cu->reg_location[s_reg].core = true;
          cu->reg_location[s_reg].defined = true;
          s_reg++;
          break;
        case 'F':
          cu->reg_location[s_reg].fp = true;
          cu->reg_location[s_reg].defined = true;
          break;
        case 'L':
          cu->reg_location[s_reg].ref = true;
          cu->reg_location[s_reg].defined = true;
          break;
        default:
          cu->reg_location[s_reg].core = true;
          cu->reg_location[s_reg].defined = true;
          break;
        }
        s_reg++;
      }
  }

  /* Do type & size inference pass */
  DataFlowAnalysisDispatcher(cu, InferTypeAndSize,
                                kPreOrderDFSTraversal,
                                true /* is_iterative */);

  /*
   * Set the s_reg_low field to refer to the pre-SSA name of the
   * base Dalvik virtual register.  Once we add a better register
   * allocator, remove this remapping.
   */
  for (i=0; i < cu->num_ssa_regs; i++) {
    if (cu->reg_location[i].location != kLocCompilerTemp) {
      int orig_sreg = cu->reg_location[i].s_reg_low;
      cu->reg_location[i].orig_sreg = orig_sreg;
      cu->reg_location[i].s_reg_low = SRegToVReg(cu, orig_sreg);
    }
  }

  /*
   * Now that everything is typed and constants propagated, identify those constants
   * that can be cheaply materialized and don't need to be flushed to a home location.
   * The default is to not flush, and some have already been marked as must flush.
   */
  for (i=0; i < cu->num_ssa_regs; i++) {
    if (IsBitSet(cu->is_constant_v, i)) {
      bool flush = false;
      RegLocation loc = cu->reg_location[i];
      if (loc.wide) {
        int64_t value = ConstantValueWide(cu, loc);
        if (loc.fp) {
          flush = !cu->cg->InexpensiveConstantDouble(value);
        } else {
          flush = !cu->cg->InexpensiveConstantLong(value);
        }
      } else {
        int32_t value = ConstantValue(cu, loc);
        if (loc.fp) {
          flush = !cu->cg->InexpensiveConstantFloat(value);
        } else {
          flush = !cu->cg->InexpensiveConstantInt(value);
        }
      }
      if (flush) {
        SetBit(cu, cu->must_flush_constant_v, i);
      }
      if (loc.wide) {
        i++;  // Skip the high word
      }
    }
  }

  cu->core_spill_mask = 0;
  cu->fp_spill_mask = 0;
  cu->num_core_spills = 0;

  DoPromotion(cu);

  /* Get easily-accessable post-promotion copy of RegLocation for Method* */
  cu->method_loc = cu->reg_location[cu->method_sreg];

  if (cu->verbose && !(cu->disable_opt & (1 << kPromoteRegs))) {
    LOG(INFO) << "After Promotion";
    DumpRegLocTable(cu, cu->reg_location, cu->num_ssa_regs);
  }

  /* Set the frame size */
  cu->frame_size = ComputeFrameSize(cu);
}

}  // namespace art
