/*
 * Copyright (C) 2010 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 "Dataflow.h"
#include "libdex/DexOpcodes.h"

/* Convert the reg id from the callee to the original id passed by the caller */
static inline u4 convertRegId(const DecodedInstruction *invoke,
                              const Method *calleeMethod,
                              int calleeRegId, bool isRange)
{
    /* The order in the original arg passing list */
    int rank = calleeRegId -
               (calleeMethod->registersSize - calleeMethod->insSize);
    assert(rank >= 0);
    if (!isRange) {
        return invoke->arg[rank];
    } else {
        return invoke->vC + rank;
    }
}

static void inlineGetter(CompilationUnit *cUnit,
                         const Method *calleeMethod,
                         MIR *invokeMIR,
                         BasicBlock *invokeBB,
                         bool isPredicted,
                         bool isRange)
{
    BasicBlock *moveResultBB = invokeBB->fallThrough;
    MIR *moveResultMIR = moveResultBB->firstMIRInsn;
    MIR *newGetterMIR = dvmCompilerNew(sizeof(MIR), true);
    DecodedInstruction getterInsn;

    dexDecodeInstruction(calleeMethod->insns, &getterInsn);

    if (!dvmCompilerCanIncludeThisInstruction(calleeMethod, &getterInsn))
        return;

    /*
     * Some getters (especially invoked through interface) are not followed
     * by a move result.
     */
    if ((moveResultMIR == NULL) ||
        (moveResultMIR->dalvikInsn.opcode != OP_MOVE_RESULT &&
         moveResultMIR->dalvikInsn.opcode != OP_MOVE_RESULT_OBJECT &&
         moveResultMIR->dalvikInsn.opcode != OP_MOVE_RESULT_WIDE)) {
        return;
    }

    int dfFlags = dvmCompilerDataFlowAttributes[getterInsn.opcode];

    /* Expecting vA to be the destination register */
    if (dfFlags & (DF_UA | DF_UA_WIDE)) {
        LOGE("opcode %d has DF_UA set (not expected)", getterInsn.opcode);
        dvmAbort();
    }

    if (dfFlags & DF_UB) {
        getterInsn.vB = convertRegId(&invokeMIR->dalvikInsn, calleeMethod,
                                     getterInsn.vB, isRange);
    }

    if (dfFlags & DF_UC) {
        getterInsn.vC = convertRegId(&invokeMIR->dalvikInsn, calleeMethod,
                                     getterInsn.vC, isRange);
    }

    getterInsn.vA = moveResultMIR->dalvikInsn.vA;

    /* Now setup the Dalvik instruction with converted src/dst registers */
    newGetterMIR->dalvikInsn = getterInsn;

    newGetterMIR->width = dexGetWidthFromOpcode(getterInsn.opcode);

    newGetterMIR->OptimizationFlags |= MIR_CALLEE;

    /*
     * If the getter instruction is about to raise any exception, punt to the
     * interpreter and re-execute the invoke.
     */
    newGetterMIR->offset = invokeMIR->offset;

    newGetterMIR->meta.calleeMethod = calleeMethod;

    dvmCompilerInsertMIRAfter(invokeBB, invokeMIR, newGetterMIR);

    if (isPredicted) {
        MIR *invokeMIRSlow = dvmCompilerNew(sizeof(MIR), true);
        *invokeMIRSlow = *invokeMIR;
        invokeMIR->dalvikInsn.opcode = kMirOpCheckInlinePrediction;

        /* Use vC to denote the first argument (ie this) */
        if (!isRange) {
            invokeMIR->dalvikInsn.vC = invokeMIRSlow->dalvikInsn.arg[0];
        }

        moveResultMIR->OptimizationFlags |= MIR_INLINED_PRED;

        dvmCompilerInsertMIRAfter(invokeBB, newGetterMIR, invokeMIRSlow);
        invokeMIRSlow->OptimizationFlags |= MIR_INLINED_PRED;
#if defined(WITH_JIT_TUNING)
        gDvmJit.invokePolyGetterInlined++;
#endif
    } else {
        invokeMIR->OptimizationFlags |= MIR_INLINED;
        moveResultMIR->OptimizationFlags |= MIR_INLINED;
#if defined(WITH_JIT_TUNING)
        gDvmJit.invokeMonoGetterInlined++;
#endif
    }

    return;
}

static void inlineSetter(CompilationUnit *cUnit,
                         const Method *calleeMethod,
                         MIR *invokeMIR,
                         BasicBlock *invokeBB,
                         bool isPredicted,
                         bool isRange)
{
    MIR *newSetterMIR = dvmCompilerNew(sizeof(MIR), true);
    DecodedInstruction setterInsn;

    dexDecodeInstruction(calleeMethod->insns, &setterInsn);

    if (!dvmCompilerCanIncludeThisInstruction(calleeMethod, &setterInsn))
        return;

    int dfFlags = dvmCompilerDataFlowAttributes[setterInsn.opcode];

    if (dfFlags & (DF_UA | DF_UA_WIDE)) {
        setterInsn.vA = convertRegId(&invokeMIR->dalvikInsn, calleeMethod,
                                     setterInsn.vA, isRange);

    }

    if (dfFlags & DF_UB) {
        setterInsn.vB = convertRegId(&invokeMIR->dalvikInsn, calleeMethod,
                                     setterInsn.vB, isRange);

    }

    if (dfFlags & DF_UC) {
        setterInsn.vC = convertRegId(&invokeMIR->dalvikInsn, calleeMethod,
                                     setterInsn.vC, isRange);
    }

    /* Now setup the Dalvik instruction with converted src/dst registers */
    newSetterMIR->dalvikInsn = setterInsn;

    newSetterMIR->width = dexGetWidthFromOpcode(setterInsn.opcode);

    newSetterMIR->OptimizationFlags |= MIR_CALLEE;

    /*
     * If the setter instruction is about to raise any exception, punt to the
     * interpreter and re-execute the invoke.
     */
    newSetterMIR->offset = invokeMIR->offset;

    newSetterMIR->meta.calleeMethod = calleeMethod;

    dvmCompilerInsertMIRAfter(invokeBB, invokeMIR, newSetterMIR);

    if (isPredicted) {
        MIR *invokeMIRSlow = dvmCompilerNew(sizeof(MIR), true);
        *invokeMIRSlow = *invokeMIR;
        invokeMIR->dalvikInsn.opcode = kMirOpCheckInlinePrediction;

        /* Use vC to denote the first argument (ie this) */
        if (!isRange) {
            invokeMIR->dalvikInsn.vC = invokeMIRSlow->dalvikInsn.arg[0];
        }

        dvmCompilerInsertMIRAfter(invokeBB, newSetterMIR, invokeMIRSlow);
        invokeMIRSlow->OptimizationFlags |= MIR_INLINED_PRED;
#if defined(WITH_JIT_TUNING)
        gDvmJit.invokePolySetterInlined++;
#endif
    } else {
        /*
         * The invoke becomes no-op so it needs an explicit branch to jump to
         * the chaining cell.
         */
        invokeBB->needFallThroughBranch = true;
        invokeMIR->OptimizationFlags |= MIR_INLINED;
#if defined(WITH_JIT_TUNING)
        gDvmJit.invokeMonoSetterInlined++;
#endif
    }

    return;
}

static void tryInlineSingletonCallsite(CompilationUnit *cUnit,
                                       const Method *calleeMethod,
                                       MIR *invokeMIR,
                                       BasicBlock *invokeBB,
                                       bool isRange)
{
    /* Not a Java method */
    if (dvmIsNativeMethod(calleeMethod)) return;

    CompilerMethodStats *methodStats =
        dvmCompilerAnalyzeMethodBody(calleeMethod, true);

    /* Empty callee - do nothing */
    if (methodStats->attributes & METHOD_IS_EMPTY) {
        /* The original invoke instruction is effectively turned into NOP */
        invokeMIR->OptimizationFlags |= MIR_INLINED;
        /*
         * Need to insert an explicit branch to catch the falling knife (into
         * the PC reconstruction or chaining cell).
         */
        invokeBB->needFallThroughBranch = true;
        return;
    }

    if (methodStats->attributes & METHOD_IS_GETTER) {
        inlineGetter(cUnit, calleeMethod, invokeMIR, invokeBB, false, isRange);
        return;
    } else if (methodStats->attributes & METHOD_IS_SETTER) {
        inlineSetter(cUnit, calleeMethod, invokeMIR, invokeBB, false, isRange);
        return;
    }
}

static void inlineEmptyVirtualCallee(CompilationUnit *cUnit,
                                     const Method *calleeMethod,
                                     MIR *invokeMIR,
                                     BasicBlock *invokeBB)
{
    MIR *invokeMIRSlow = dvmCompilerNew(sizeof(MIR), true);
    *invokeMIRSlow = *invokeMIR;
    invokeMIR->dalvikInsn.opcode = kMirOpCheckInlinePrediction;

    dvmCompilerInsertMIRAfter(invokeBB, invokeMIR, invokeMIRSlow);
    invokeMIRSlow->OptimizationFlags |= MIR_INLINED_PRED;
}

static void tryInlineVirtualCallsite(CompilationUnit *cUnit,
                                     const Method *calleeMethod,
                                     MIR *invokeMIR,
                                     BasicBlock *invokeBB,
                                     bool isRange)
{
    /* Not a Java method */
    if (dvmIsNativeMethod(calleeMethod)) return;

    CompilerMethodStats *methodStats =
        dvmCompilerAnalyzeMethodBody(calleeMethod, true);

    /* Empty callee - do nothing by checking the clazz pointer */
    if (methodStats->attributes & METHOD_IS_EMPTY) {
        inlineEmptyVirtualCallee(cUnit, calleeMethod, invokeMIR, invokeBB);
        return;
    }

    if (methodStats->attributes & METHOD_IS_GETTER) {
        inlineGetter(cUnit, calleeMethod, invokeMIR, invokeBB, true, isRange);
        return;
    } else if (methodStats->attributes & METHOD_IS_SETTER) {
        inlineSetter(cUnit, calleeMethod, invokeMIR, invokeBB, true, isRange);
        return;
    }
}


void dvmCompilerInlineMIR(CompilationUnit *cUnit)
{
    int i;
    bool isRange = false;

    /*
     * Analyze the basic block containing an invoke to see if it can be inlined
     */
    for (i = 0; i < cUnit->numBlocks; i++) {
        BasicBlock *bb = cUnit->blockList[i];
        if (bb->blockType != kDalvikByteCode)
            continue;
        MIR *lastMIRInsn = bb->lastMIRInsn;
        int opcode = lastMIRInsn->dalvikInsn.opcode;
        int flags = dexGetFlagsFromOpcode(opcode);

        /* No invoke - continue */
        if ((flags & kInstrInvoke) == 0)
            continue;

        /*
         * If the invoke itself is selected for single stepping, don't bother
         * to inline it.
         */
        if (SINGLE_STEP_OP(opcode))
            continue;

        const Method *calleeMethod;

        switch (opcode) {
            case OP_INVOKE_SUPER:
            case OP_INVOKE_DIRECT:
            case OP_INVOKE_STATIC:
            case OP_INVOKE_SUPER_QUICK:
                calleeMethod = lastMIRInsn->meta.callsiteInfo->method;
                break;
            case OP_INVOKE_SUPER_RANGE:
            case OP_INVOKE_DIRECT_RANGE:
            case OP_INVOKE_STATIC_RANGE:
            case OP_INVOKE_SUPER_QUICK_RANGE:
                isRange = true;
                calleeMethod = lastMIRInsn->meta.callsiteInfo->method;
                break;
            default:
                calleeMethod = NULL;
                break;
        }

        if (calleeMethod) {
            tryInlineSingletonCallsite(cUnit, calleeMethod, lastMIRInsn, bb,
                                       isRange);
            return;
        }

        switch (opcode) {
            case OP_INVOKE_VIRTUAL:
            case OP_INVOKE_VIRTUAL_QUICK:
            case OP_INVOKE_INTERFACE:
                isRange = false;
                calleeMethod = lastMIRInsn->meta.callsiteInfo->method;
                break;
            case OP_INVOKE_VIRTUAL_RANGE:
            case OP_INVOKE_VIRTUAL_QUICK_RANGE:
            case OP_INVOKE_INTERFACE_RANGE:
                isRange = true;
                calleeMethod = lastMIRInsn->meta.callsiteInfo->method;
                break;
            default:
                break;
        }

        if (calleeMethod) {
            tryInlineVirtualCallsite(cUnit, calleeMethod, lastMIRInsn, bb,
                                     isRange);
            return;
        }
    }
}
