/*
 * Copyright (C) 2007 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.
 */

package com.android.dx.ssa.back;

import com.android.dx.ssa.SsaMethod;
import com.android.dx.ssa.SsaBasicBlock;
import com.android.dx.ssa.SsaInsn;
import com.android.dx.ssa.PhiInsn;
import com.android.dx.rop.code.RegisterSpec;

import java.util.BitSet;
import java.util.List;
import java.util.ArrayList;

/**
 * From Appel "Modern Compiler Implementation in Java" algorithm 19.17
 * Calculate the live ranges for register {@code reg}.<p>
 *
 * v = regV <p>
 * s = insn <p>
 * M = visitedBlocks <p>
 */
public class LivenessAnalyzer {
    /**
     * {@code non-null;} index by basic block indexed set of basic blocks
     * that have already been visited. "M" as written in the original Appel
     * algorithm.
     */
    private final BitSet visitedBlocks;

    /**
     * {@code non-null;} set of blocks remaing to visit as "live out as block"
     */
    private final BitSet liveOutBlocks;

    /**
     * {@code >=0;} SSA register currently being analyzed.
     * "v" in the original Appel algorithm.
     */
    private final int regV;

    /** method to process */
    private final SsaMethod ssaMeth;

    /** interference graph being updated */
    private final InterferenceGraph interference;

    /** block "n" in Appel 19.17 */
    private SsaBasicBlock blockN;

    /** index of statement {@code s} in {@code blockN} */
    private int statementIndex;

    /** the next function to call */
    private NextFunction nextFunction;

    /** constants for {@link #nextFunction} */
    private static enum NextFunction {
        LIVE_IN_AT_STATEMENT,
            LIVE_OUT_AT_STATEMENT,
            LIVE_OUT_AT_BLOCK,
            DONE;
    }

    /**
     * Runs register liveness algorithm for a method, updating the
     * live in/out information in {@code SsaBasicBlock} instances and
     * returning an interference graph.
     *
     * @param ssaMeth {@code non-null;} method to process
     * @return {@code non-null;} interference graph indexed by SSA
     * registers in both directions
     */
    public static InterferenceGraph constructInterferenceGraph(
            SsaMethod ssaMeth) {
        int szRegs = ssaMeth.getRegCount();
        InterferenceGraph interference = new InterferenceGraph(szRegs);

        for (int i = 0; i < szRegs; i++) {
            new LivenessAnalyzer(ssaMeth, i, interference).run();
        }

        coInterferePhis(ssaMeth, interference);

        return interference;
    }
    
    /**
     * Makes liveness analyzer instance for specific register.
     *
     * @param ssaMeth {@code non-null;} method to process
     * @param reg register whose liveness to analyze
     * @param interference {@code non-null;} indexed by SSA reg in
     * both dimensions; graph to update
     *
     */
    private LivenessAnalyzer(SsaMethod ssaMeth, int reg,
            InterferenceGraph interference) {
        int blocksSz = ssaMeth.getBlocks().size();

        this.ssaMeth = ssaMeth;
        this.regV = reg;
        visitedBlocks = new BitSet(blocksSz);
        liveOutBlocks = new BitSet(blocksSz);
        this.interference = interference;
    }

    /**
     * The algorithm in Appel is presented in partial tail-recursion
     * form. Obviously, that's not efficient in java, so this function
     * serves as the dispatcher instead.
     */
    private void handleTailRecursion() {
        while (nextFunction != NextFunction.DONE) {
            switch (nextFunction) {
                case LIVE_IN_AT_STATEMENT:
                    nextFunction = NextFunction.DONE;
                    liveInAtStatement();
                    break;

                case LIVE_OUT_AT_STATEMENT:
                    nextFunction = NextFunction.DONE;
                    liveOutAtStatement();
                    break;

                case LIVE_OUT_AT_BLOCK:
                    nextFunction = NextFunction.DONE;
                    liveOutAtBlock();
                    break;

                default:
            }
        }
    }

    /**
     * From Appel algorithm 19.17.
     */
    public void run() {
        List<SsaInsn> useList = ssaMeth.getUseListForRegister(regV);

        for (SsaInsn insn : useList) {
            nextFunction = NextFunction.DONE;

            if (insn instanceof PhiInsn) {
                // If s is a phi-function with V as it's ith argument.
                PhiInsn phi = (PhiInsn) insn;

                for (SsaBasicBlock pred :
                         phi.predBlocksForReg(regV, ssaMeth)) {
                    blockN = pred;

                    nextFunction = NextFunction.LIVE_OUT_AT_BLOCK;
                    handleTailRecursion();
                }
            } else {
                blockN = insn.getBlock();
                statementIndex = blockN.getInsns().indexOf(insn);

                if (statementIndex < 0) {
                    throw new RuntimeException(
                            "insn not found in it's own block");
                }

                nextFunction = NextFunction.LIVE_IN_AT_STATEMENT;
                handleTailRecursion();
            }
        }

        int nextLiveOutBlock;
        while ((nextLiveOutBlock = liveOutBlocks.nextSetBit(0)) >= 0) {
            blockN = ssaMeth.getBlocks().get(nextLiveOutBlock);
            liveOutBlocks.clear(nextLiveOutBlock);
            nextFunction = NextFunction.LIVE_OUT_AT_BLOCK;
            handleTailRecursion();
        }
    }

    /**
     * "v is live-out at n."
     */
    private void liveOutAtBlock() {
        if (! visitedBlocks.get(blockN.getIndex())) {
            visitedBlocks.set(blockN.getIndex());

            blockN.addLiveOut(regV);

            ArrayList<SsaInsn> insns;

            insns = blockN.getInsns();

            // Live out at last statement in blockN
            statementIndex = insns.size() - 1;
            nextFunction = NextFunction.LIVE_OUT_AT_STATEMENT;
        }
    }

    /**
     * "v is live-in at s."
     */
    private void liveInAtStatement() {
        // if s is the first statement in block N
        if (statementIndex == 0) {
            // v is live-in at n
            blockN.addLiveIn(regV);

            BitSet preds = blockN.getPredecessors();

            liveOutBlocks.or(preds);
        } else {
            // Let s' be the statement preceeding s
            statementIndex -= 1;
            nextFunction = NextFunction.LIVE_OUT_AT_STATEMENT;
        }
    }

    /**
     * "v is live-out at s."
     */
    private void liveOutAtStatement() {
        SsaInsn statement = blockN.getInsns().get(statementIndex);
        RegisterSpec rs = statement.getResult();

        if (!statement.isResultReg(regV)) {
            if (rs != null) {
                interference.add(regV, rs.getReg());
            }
            nextFunction = NextFunction.LIVE_IN_AT_STATEMENT;
        }
    }

    /**
     * Ensures that all the phi result registers for all the phis in the
     * same basic block interfere with each other. This is needed since
     * the dead code remover has allowed through "dead-end phis" whose
     * results are not used except as local assignments. Without this step,
     * a the result of a dead-end phi might be assigned the same register
     * as the result of another phi, and the phi removal move scheduler may
     * generate moves that over-write the live result.
     *
     * @param ssaMeth {@code non-null;} method to pricess
     * @param interference {@code non-null;} interference graph
     */
    private static void coInterferePhis(SsaMethod ssaMeth,
            InterferenceGraph interference) {
        for (SsaBasicBlock b : ssaMeth.getBlocks()) {
            List<SsaInsn> phis = b.getPhiInsns();

            int szPhis = phis.size();

            for (int i = 0; i < szPhis; i++) {
                for (int j = 0; j < szPhis; j++) {
                    if (i == j) {
                        continue;
                    }

                    interference.add(phis.get(i).getResult().getReg(),
                        phis.get(j).getResult().getReg());
                }
            }
        }
    }
}
