/*
 * 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/OpCodeNames.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(&gDvm.instrInfo, 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 = gDvm.instrInfo.widths[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(&gDvm.instrInfo, 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 = gDvm.instrInfo.widths[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 = dexGetInstrFlags(gDvm.instrInfo.flags, opCode);

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

        /* Not a real invoke - continue */
        if (opCode == OP_INVOKE_DIRECT_EMPTY)
            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;
        }
    }
}
