/*
 * 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 "Dalvik.h"
#include "CompilerInternals.h"
#include "Dataflow.h"
#include "codegen/Ralloc.h"

namespace art {

bool setFp(CompilationUnit* cUnit, int index, bool isFP) {
  bool change = false;
  if (isFP && !cUnit->regLocation[index].fp) {
    cUnit->regLocation[index].fp = true;
    cUnit->regLocation[index].defined = true;
    change = true;
  }
  return change;
}

bool setCore(CompilationUnit* cUnit, int index, bool isCore) {
  bool change = false;
  if (isCore && !cUnit->regLocation[index].defined) {
    cUnit->regLocation[index].core = true;
    cUnit->regLocation[index].defined = true;
    change = true;
  }
  return change;
}

bool setRef(CompilationUnit* cUnit, int index, bool isRef) {
  bool change = false;
  if (isRef && !cUnit->regLocation[index].defined) {
    cUnit->regLocation[index].ref = true;
    cUnit->regLocation[index].defined = true;
    change = true;
  }
  return change;
}

bool setWide(CompilationUnit* cUnit, int index, bool isWide) {
  bool change = false;
  if (isWide && !cUnit->regLocation[index].wide) {
    cUnit->regLocation[index].wide = true;
    change = true;
  }
  return change;
}

bool setHigh(CompilationUnit* cUnit, int index, bool isHigh) {
  bool change = false;
  if (isHigh && !cUnit->regLocation[index].highWord) {
    cUnit->regLocation[index].highWord = true;
    change = true;
  }
  return change;
}

bool remapNames(CompilationUnit* cUnit, BasicBlock* bb)
{
  if (bb->blockType != kDalvikByteCode && bb->blockType != kEntryBlock &&
      bb->blockType != kExitBlock)
    return false;

  for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
    SSARepresentation *ssaRep = mir->ssaRep;
    if (ssaRep) {
      for (int i = 0; i < ssaRep->numUses; i++) {
        ssaRep->uses[i] = cUnit->phiAliasMap[ssaRep->uses[i]];
      }
      for (int i = 0; i < ssaRep->numDefs; i++) {
        ssaRep->defs[i] = cUnit->phiAliasMap[ssaRep->defs[i]];
      }
    }
  }
  return false;
}

/*
 * 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.
 */
bool inferTypeAndSize(CompilationUnit* cUnit, BasicBlock* bb)
{
  MIR *mir;
  bool changed = false;   // Did anything change?

  if (bb->dataFlowInfo == NULL) return false;
  if (bb->blockType != kDalvikByteCode && bb->blockType != kEntryBlock)
    return false;

  for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
    SSARepresentation *ssaRep = mir->ssaRep;
    if (ssaRep) {
      int attrs = oatDataFlowAttributes[mir->dalvikInsn.opcode];

      // Handle defs
      if (attrs & DF_DA) {
        if (attrs & DF_CORE_A) {
          changed |= setCore(cUnit, ssaRep->defs[0], true);
        }
        if (attrs & DF_REF_A) {
          changed |= setRef(cUnit, ssaRep->defs[0], true);
        }
        if (attrs & DF_A_WIDE) {
          cUnit->regLocation[ssaRep->defs[0]].wide = true;
          cUnit->regLocation[ssaRep->defs[1]].wide = true;
          cUnit->regLocation[ssaRep->defs[1]].highWord = true;
          DCHECK_EQ(SRegToVReg(cUnit, ssaRep->defs[0])+1,
          SRegToVReg(cUnit, ssaRep->defs[1]));
        }
      }

      // Handles uses
      int next = 0;
      if (attrs & DF_UA) {
        if (attrs & DF_CORE_A) {
          changed |= setCore(cUnit, ssaRep->uses[next], true);
        }
        if (attrs & DF_REF_A) {
          changed |= setRef(cUnit, ssaRep->uses[next], true);
        }
        if (attrs & DF_A_WIDE) {
          cUnit->regLocation[ssaRep->uses[next]].wide = true;
          cUnit->regLocation[ssaRep->uses[next + 1]].wide = true;
          cUnit->regLocation[ssaRep->uses[next + 1]].highWord = true;
          DCHECK_EQ(SRegToVReg(cUnit, ssaRep->uses[next])+1,
          SRegToVReg(cUnit, ssaRep->uses[next + 1]));
          next += 2;
        } else {
          next++;
        }
      }
      if (attrs & DF_UB) {
        if (attrs & DF_CORE_B) {
          changed |= setCore(cUnit, ssaRep->uses[next], true);
        }
        if (attrs & DF_REF_B) {
          changed |= setRef(cUnit, ssaRep->uses[next], true);
        }
        if (attrs & DF_B_WIDE) {
          cUnit->regLocation[ssaRep->uses[next]].wide = true;
          cUnit->regLocation[ssaRep->uses[next + 1]].wide = true;
          cUnit->regLocation[ssaRep->uses[next + 1]].highWord = true;
          DCHECK_EQ(SRegToVReg(cUnit, ssaRep->uses[next])+1,
                               SRegToVReg(cUnit, ssaRep->uses[next + 1]));
          next += 2;
        } else {
          next++;
        }
      }
      if (attrs & DF_UC) {
        if (attrs & DF_CORE_C) {
          changed |= setCore(cUnit, ssaRep->uses[next], true);
        }
        if (attrs & DF_REF_C) {
          changed |= setRef(cUnit, ssaRep->uses[next], true);
        }
        if (attrs & DF_C_WIDE) {
          cUnit->regLocation[ssaRep->uses[next]].wide = true;
          cUnit->regLocation[ssaRep->uses[next + 1]].wide = true;
          cUnit->regLocation[ssaRep->uses[next + 1]].highWord = true;
          DCHECK_EQ(SRegToVReg(cUnit, ssaRep->uses[next])+1,
          SRegToVReg(cUnit, ssaRep->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(cUnit->shorty[0]) {
            case 'I':
              changed |= setCore(cUnit, ssaRep->uses[0], true);
              break;
            case 'J':
              changed |= setCore(cUnit, ssaRep->uses[0], true);
              changed |= setCore(cUnit, ssaRep->uses[1], true);
              cUnit->regLocation[ssaRep->uses[0]].wide = true;
              cUnit->regLocation[ssaRep->uses[1]].wide = true;
              cUnit->regLocation[ssaRep->uses[1]].highWord = true;
              break;
            case 'F':
              changed |= setFp(cUnit, ssaRep->uses[0], true);
              break;
            case 'D':
              changed |= setFp(cUnit, ssaRep->uses[0], true);
              changed |= setFp(cUnit, ssaRep->uses[1], true);
              cUnit->regLocation[ssaRep->uses[0]].wide = true;
              cUnit->regLocation[ssaRep->uses[1]].wide = true;
              cUnit->regLocation[ssaRep->uses[1]].highWord = true;
              break;
            case 'L':
              changed |= setRef(cUnit, ssaRep->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::Flags(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 = oatGetShortyFromTargetIdx(cUnit, target_idx);
        // Handle result type if floating point
        if ((shorty[0] == 'F') || (shorty[0] == 'D')) {
          MIR* moveResultMIR = oatFindMoveResult(cUnit, bb, mir);
          // Result might not be used at all, so no move-result
          if (moveResultMIR && (moveResultMIR->dalvikInsn.opcode !=
              Instruction::MOVE_RESULT_OBJECT)) {
            SSARepresentation* tgtRep = moveResultMIR->ssaRep;
            DCHECK(tgtRep != NULL);
            tgtRep->fpDef[0] = true;
            changed |= setFp(cUnit, tgtRep->defs[0], true);
            if (shorty[0] == 'D') {
              tgtRep->fpDef[1] = true;
              changed |= setFp(cUnit, tgtRep->defs[1], true);
            }
          }
        }
        int numUses = 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))) {
          cUnit->regLocation[ssaRep->uses[next]].defined = true;
          cUnit->regLocation[ssaRep->uses[next]].ref = true;
          next++;
        }
        uint32_t cpos = 1;
        if (strlen(shorty) > 1) {
          for (int i = next; i < numUses;) {
            DCHECK_LT(cpos, strlen(shorty));
            switch (shorty[cpos++]) {
              case 'D':
                ssaRep->fpUse[i] = true;
                ssaRep->fpUse[i+1] = true;
                cUnit->regLocation[ssaRep->uses[i]].wide = true;
                cUnit->regLocation[ssaRep->uses[i+1]].wide = true;
                cUnit->regLocation[ssaRep->uses[i+1]].highWord = true;
                DCHECK_EQ(SRegToVReg(cUnit, ssaRep->uses[i])+1,
                                     SRegToVReg(cUnit, ssaRep->uses[i+1]));
                i++;
                break;
              case 'J':
                cUnit->regLocation[ssaRep->uses[i]].wide = true;
                cUnit->regLocation[ssaRep->uses[i+1]].wide = true;
                cUnit->regLocation[ssaRep->uses[i+1]].highWord = true;
                DCHECK_EQ(SRegToVReg(cUnit, ssaRep->uses[i])+1,
                                     SRegToVReg(cUnit, ssaRep->uses[i+1]));
                changed |= setCore(cUnit, ssaRep->uses[i],true);
                i++;
                break;
              case 'F':
                ssaRep->fpUse[i] = true;
                break;
              case 'L':
                changed |= setRef(cUnit,ssaRep->uses[i], true);
                break;
              default:
                changed |= setCore(cUnit,ssaRep->uses[i], true);
                break;
            }
            i++;
          }
        }
      }

      for (int i=0; ssaRep->fpUse && i< ssaRep->numUses; i++) {
        if (ssaRep->fpUse[i])
          changed |= setFp(cUnit, ssaRep->uses[i], true);
        }
      for (int i=0; ssaRep->fpDef && i< ssaRep->numDefs; i++) {
        if (ssaRep->fpDef[i])
          changed |= setFp(cUnit, ssaRep->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 isPhi = (static_cast<int>(mir->dalvikInsn.opcode) ==
                      kMirOpPhi);
        RegLocation rlTemp = cUnit->regLocation[ssaRep->defs[0]];
        bool definedFP = rlTemp.defined && rlTemp.fp;
        bool definedCore = rlTemp.defined && rlTemp.core;
        bool definedRef = rlTemp.defined && rlTemp.ref;
        bool isWide = rlTemp.wide || ((attrs & DF_A_WIDE) != 0);
        bool isHigh = isPhi && rlTemp.wide && rlTemp.highWord;
        for (int i = 0; i < ssaRep->numUses;i++) {
          rlTemp = cUnit->regLocation[ssaRep->uses[i]];
          definedFP |= rlTemp.defined && rlTemp.fp;
          definedCore |= rlTemp.defined && rlTemp.core;
          definedRef |= rlTemp.defined && rlTemp.ref;
          isWide |= rlTemp.wide;
          isHigh |= isPhi && rlTemp.wide && rlTemp.highWord;
        }
        /*
         * 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 ((definedFP && (definedCore | definedRef)) &&
            ((cUnit->disableOpt & (1 << kPromoteRegs)) == 0)) {
          LOG(WARNING) << PrettyMethod(cUnit->method_idx, *cUnit->dex_file)
                       << " op at block " << bb->id
                       << " has both fp and core/ref uses for same def.";
          cUnit->disableOpt |= (1 << kPromoteRegs);
        }
        changed |= setFp(cUnit, ssaRep->defs[0], definedFP);
        changed |= setCore(cUnit, ssaRep->defs[0], definedCore);
        changed |= setRef(cUnit, ssaRep->defs[0], definedRef);
        changed |= setWide(cUnit, ssaRep->defs[0], isWide);
        changed |= setHigh(cUnit, ssaRep->defs[0], isHigh);
        if (attrs & DF_A_WIDE) {
          changed |= setWide(cUnit, ssaRep->defs[1], true);
          changed |= setHigh(cUnit, ssaRep->defs[1], true);
        }
        for (int i = 0; i < ssaRep->numUses; i++) {
          changed |= setFp(cUnit, ssaRep->uses[i], definedFP);
          changed |= setCore(cUnit, ssaRep->uses[i], definedCore);
          changed |= setRef(cUnit, ssaRep->uses[i], definedRef);
          changed |= setWide(cUnit, ssaRep->uses[i], isWide);
          changed |= setHigh(cUnit, ssaRep->uses[i], isHigh);
        }
        if (attrs & DF_A_WIDE) {
          DCHECK_EQ(ssaRep->numUses, 2);
          changed |= setWide(cUnit, ssaRep->uses[1], true);
          changed |= setHigh(cUnit, ssaRep->uses[1], true);
        }
      }
    }
  }
  return changed;
}

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

void oatDumpRegLocTable(RegLocation* table, int count)
{
  for (int i = 0; i < count; i++) {
    LOG(INFO) << StringPrintf("Loc[%02d] : %s, %c %c %c %c %c %c%d %c%d S%d",
        table[i].origSReg, storageName[table[i].location],
        table[i].wide ? 'W' : 'N', table[i].defined ? 'D' : 'U',
        table[i].fp ? 'F' : table[i].ref ? 'R' :'C',
        table[i].highWord ? 'H' : 'L', table[i].home ? 'h' : 't',
        oatIsFpReg(table[i].lowReg) ? 's' : 'r',
        table[i].lowReg & oatFpRegMask(),
        oatIsFpReg(table[i].highReg) ? 's' : 'r',
        table[i].highReg & oatFpRegMask(), table[i].sRegLow);
  }
}

void oatDumpRegLoc(RegLocation loc) {
  oatDumpRegLocTable(&loc, 1);
}

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

int oatComputeFrameSize(CompilationUnit* cUnit) {
  /* Figure out the frame size */
  static const uint32_t kAlignMask = kStackAlignment - 1;
  uint32_t size = (cUnit->numCoreSpills + cUnit->numFPSpills +
                   1 /* filler word */ + cUnit->numRegs + cUnit->numOuts +
                   cUnit->numCompilerTemps + 1 /* curMethod* */)
                   * 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 oatSimpleRegAlloc(CompilationUnit* cUnit)
{
  int i;
  RegLocation* loc;

  /* Allocate the location map */
  loc = (RegLocation*)oatNew(cUnit, cUnit->numSSARegs * sizeof(*loc), true,
                             kAllocRegAlloc);
  for (i=0; i< cUnit->numSSARegs; i++) {
    loc[i] = freshLoc;
    loc[i].sRegLow = i;
    loc[i].isConst = oatIsBitSet(cUnit->isConstantV, i);
  }

  /* Patch up the locations for Method* and the compiler temps */
  loc[cUnit->methodSReg].location = kLocCompilerTemp;
  loc[cUnit->methodSReg].defined = true;
  for (i = 0; i < cUnit->numCompilerTemps; i++) {
    CompilerTemp* ct = (CompilerTemp*)cUnit->compilerTemps.elemList[i];
    loc[ct->sReg].location = kLocCompilerTemp;
    loc[ct->sReg].defined = true;
  }

  cUnit->regLocation = loc;

  /* Allocation the promotion map */
  int numRegs = cUnit->numDalvikRegisters;
  cUnit->promotionMap =
      (PromotionMap*)oatNew(cUnit, (numRegs + cUnit->numCompilerTemps + 1) *
                            sizeof(cUnit->promotionMap[0]), true,
                            kAllocRegAlloc);

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

#if defined(ART_USE_QUICK_COMPILER)
  if (!cUnit->genBitcode) {
    /* Remap names */
    oatDataFlowAnalysisDispatcher(cUnit, remapNames,
                                  kPreOrderDFSTraversal,
                                  false /* isIterative */);
  }
#else
  /* Remap names */
  oatDataFlowAnalysisDispatcher(cUnit, remapNames,
                                kPreOrderDFSTraversal,
                                false /* isIterative */);
#endif

  /* Do type & size inference pass */
  oatDataFlowAnalysisDispatcher(cUnit, inferTypeAndSize,
                                kPreOrderDFSTraversal,
                                true /* isIterative */);

  /*
   * Set the sRegLow 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 < cUnit->numSSARegs; i++) {
    if (cUnit->regLocation[i].location != kLocCompilerTemp) {
      int origSReg = cUnit->regLocation[i].sRegLow;
      cUnit->regLocation[i].origSReg = origSReg;
      cUnit->regLocation[i].sRegLow = SRegToVReg(cUnit, origSReg);
    }
  }

  cUnit->coreSpillMask = 0;
  cUnit->fpSpillMask = 0;
  cUnit->numCoreSpills = 0;

  oatDoPromotion(cUnit);

  /* Get easily-accessable post-promotion copy of RegLocation for Method* */
  cUnit->methodLoc = cUnit->regLocation[cUnit->methodSReg];

  if (cUnit->printMe && !(cUnit->disableOpt & (1 << kPromoteRegs))) {
    LOG(INFO) << "After Promotion";
    oatDumpRegLocTable(cUnit->regLocation, cUnit->numSSARegs);
  }

  /* Set the frame size */
  cUnit->frameSize = oatComputeFrameSize(cUnit);
}

}  // namespace art
