/*
 * Copyright (C) 2009 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"

typedef struct LiveRange {
    int ssaName;
    bool active;
    int first;
    int last;
} LiveRange;

int computeLiveRange(LiveRange *list, BasicBlock *bb, int seqNum)
{
    MIR *mir;
    int i;

    if (bb->blockType != kDalvikByteCode &&
        bb->blockType != kEntryBlock)
        return seqNum;

    for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
        SSARepresentation *ssaRep = mir->ssaRep;
        mir->seqNum = seqNum;
        if (ssaRep) {
            for (i=0; i< ssaRep->numUses; i++) {
                int reg = ssaRep->uses[i];
                list[reg].first = MIN(list[reg].first, seqNum);
                list[reg].active = true;
            }
            for (i=0; i< ssaRep->numDefs; i++) {
                int reg = ssaRep->defs[i];
                list[reg].last = MAX(list[reg].last, seqNum + 1);
                list[reg].active = true;
            }
            seqNum += 2;
        }
    }
    return seqNum;
}

/*
 * Quick & dirty - make FP usage sticky.  This is strictly a hint - local
 * code generation will handle misses.  It might be worthwhile to collaborate
 * with dx/dexopt to avoid reusing the same Dalvik temp for values of
 * different types.
 */
static void inferTypes(CompilationUnit *cUnit, BasicBlock *bb)
{
    MIR *mir;
    if (bb->blockType != kDalvikByteCode &&
        bb->blockType != kEntryBlock)
        return;

    for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
        SSARepresentation *ssaRep = mir->ssaRep;
        if (ssaRep) {
            int i;
            for (i=0; ssaRep->fpUse && i< ssaRep->numUses; i++) {
                if (ssaRep->fpUse[i])
                    cUnit->regLocation[ssaRep->uses[i]].fp = true;
            }
            for (i=0; ssaRep->fpDef && i< ssaRep->numDefs; i++) {
                if (ssaRep->fpDef[i])
                    cUnit->regLocation[ssaRep->defs[i]].fp = true;
            }
        }
    }
}

/*
 * Determine whether to use simple or aggressive register allocation.  In
 * general, loops and full methods will get aggressive.
 */
static bool simpleTrace(CompilationUnit *cUnit)
{
    //TODO: flesh out
    return true;
}

/*
 * Target-independent register allocation.  Requires target-dependent
 * helper functions and assumes free list, temp list and spill region.
 * Uses a variant of linear scan and produces a mapping between SSA names
 * and location.  Location may be original Dalvik register, hardware
 * register or spill location.
 *
 * Method:
 *    0.  Allocate the structure to hold the SSA name life ranges
 *    1.  Number each MIR instruction, counting by 2.
 *        +0 -> The "read" of the operands
 *        +1 -> The definition of the target resource
 *    2.  Compute live ranges for all SSA names *not* including the
 *        subscript 0 original Dalvik names.  Phi functions ignored
 *        at this point.
 *    3.  Sort the live range list by lowest range start.
 *    4.  Process and remove all Phi functions.
 *        o If there is no live range collisions among all operands and
 *          the target of a Phi function, collapse operands and target
 *          and rewrite using target SSA name.
 *        o If there is a collision, introduce copies.
 *    5.  Allocate in order of increasing live range start.
 */
static const RegLocation freshLoc = {kLocDalvikFrame, 0, 0, INVALID_REG,
                                     INVALID_REG, INVALID_SREG};
void dvmCompilerRegAlloc(CompilationUnit *cUnit)
{
    int i;
    int seqNum = 0;
    LiveRange *ranges;
    RegLocation *loc;
    int *ssaToDalvikMap = (int *) cUnit->ssaToDalvikMap->elemList;

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

    /* Do type inference pass */
    for (i=0; i < cUnit->numBlocks; i++) {
        inferTypes(cUnit, cUnit->blockList[i]);
    }

    if (simpleTrace(cUnit)) {
        /*
         * Just rename everything back to subscript 0 names and don't do
         * any explicit promotion.  Local allocator will opportunistically
         * promote on the fly.
         */
        for (i=0; i < cUnit->numSSARegs; i++) {
            cUnit->regLocation[i].sRegLow =
                DECODE_REG(dvmConvertSSARegToDalvik(cUnit, loc[i].sRegLow));
        }
    } else {
        // Compute live ranges
        ranges = dvmCompilerNew(cUnit->numSSARegs * sizeof(*ranges), true);
        for (i=0; i < cUnit->numSSARegs; i++)
            ranges[i].active = false;
        seqNum = computeLiveRange(ranges, cUnit->blockList[i], seqNum);
        //TODO: phi squash & linear scan promotion
    }
}
