/*
 * 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;

import com.android.dx.rop.code.PlainCstInsn;
import com.android.dx.rop.code.TranslationAdvice;
import com.android.dx.rop.code.RegisterSpecList;
import com.android.dx.rop.code.Insn;
import com.android.dx.rop.code.Rop;
import com.android.dx.rop.code.RegisterSpec;
import com.android.dx.rop.code.PlainInsn;
import com.android.dx.rop.code.Rops;
import com.android.dx.rop.code.RegOps;
import com.android.dx.rop.cst.Constant;
import com.android.dx.rop.cst.CstLiteralBits;
import com.android.dx.rop.type.Type;
import com.android.dx.rop.type.TypeBearer;

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

/**
 * Upgrades insn to their literal (constant-immediate) equivilent if possible.
 * Also switches IF instructions that compare with a constant zero or null
 * to be their IF_*Z equivalents.
 */
public class LiteralOpUpgrader {

    /** method we're processing */
    private final SsaMethod ssaMeth;

    /**
     * Process a method.
     *
     * @param ssaMethod {@code non-null;} method to process
     */
    public static void process(SsaMethod ssaMethod) {
        LiteralOpUpgrader dc;

        dc = new LiteralOpUpgrader(ssaMethod);

        dc.run();
    }

    private LiteralOpUpgrader(SsaMethod ssaMethod) {
        this.ssaMeth = ssaMethod;
    }

    /**
     * Returns true if the register contains an integer 0 or a known-null
     * object reference
     *
     * @param spec non-null spec
     * @return true for 0 or null type bearers
     */
    private static boolean isConstIntZeroOrKnownNull(RegisterSpec spec) {
        TypeBearer tb = spec.getTypeBearer();
        if (tb instanceof CstLiteralBits) {
            CstLiteralBits clb = (CstLiteralBits) tb;
            return (clb.getLongBits() == 0);
        }
        return false;
    }

    /**
     * Run the literal op upgrader
     */
    private void run() {
        final TranslationAdvice advice = Optimizer.getAdvice();

        ssaMeth.forEachInsn(new SsaInsn.Visitor() {
            public void visitMoveInsn(NormalSsaInsn insn) {
                // do nothing
            }

            public void visitPhiInsn(PhiInsn insn) {
                // do nothing
            }

            public void visitNonMoveInsn(NormalSsaInsn insn) {

                Insn originalRopInsn = insn.getOriginalRopInsn();
                Rop opcode = originalRopInsn.getOpcode();
                RegisterSpecList sources = insn.getSources();

                // Replace insns with constant results with const insns
                if (tryReplacingWithConstant(insn)) return;

                if (sources.size() != 2 ) {
                    // We're only dealing with two-source insns here.
                    return;
                }

                if (opcode.getBranchingness() == Rop.BRANCH_IF) {
                    /*
                     * An if instruction can become an if-*z instruction.
                     */
                    if (isConstIntZeroOrKnownNull(sources.get(0))) {
                        replacePlainInsn(insn, sources.withoutFirst(),
                              RegOps.flippedIfOpcode(opcode.getOpcode()), null);
                    } else if (isConstIntZeroOrKnownNull(sources.get(1))) {
                        replacePlainInsn(insn, sources.withoutLast(),
                              opcode.getOpcode(), null);
                    }
                } else if (advice.hasConstantOperation(
                        opcode, sources.get(0), sources.get(1))) {
                    insn.upgradeToLiteral();
                } else  if (opcode.isCommutative()
                        && advice.hasConstantOperation(
                        opcode, sources.get(1), sources.get(0))) {
                    /*
                     * An instruction can be commuted to a literal operation
                     */

                    insn.setNewSources(
                            RegisterSpecList.make(
                                    sources.get(1), sources.get(0)));

                    insn.upgradeToLiteral();
                }
            }
        });
    }

    /**
     * Tries to replace an instruction with a const instruction. The given
     * instruction must have a constant result for it to be replaced.
     *
     * @param insn {@code non-null;} instruction to try to replace
     * @return true if the instruction was replaced
     */
    private boolean tryReplacingWithConstant(NormalSsaInsn insn) {
        Insn originalRopInsn = insn.getOriginalRopInsn();
        Rop opcode = originalRopInsn.getOpcode();

        if (insn.getResult() != null && opcode.getOpcode() != RegOps.CONST) {
            TypeBearer type = insn.getResult().getTypeBearer();
            if (type.isConstant() && type.getBasicType() == Type.BT_INT) {
                // Replace the instruction with a constant
                replacePlainInsn(insn, RegisterSpecList.EMPTY,
                        RegOps.CONST, (Constant) type);

                // Remove the source as well if this is a move-result-pseudo
                if (opcode.getOpcode() == RegOps.MOVE_RESULT_PSEUDO) {
                    int pred = insn.getBlock().getPredecessors().nextSetBit(0);
                    ArrayList<SsaInsn> predInsns =
                            ssaMeth.getBlocks().get(pred).getInsns();
                    NormalSsaInsn sourceInsn =
                            (NormalSsaInsn) predInsns.get(predInsns.size()-1);
                    replacePlainInsn(sourceInsn, RegisterSpecList.EMPTY,
                            RegOps.GOTO, null);
                }
                return true;
            }
        }
        return false;
    }

    /**
     * Replaces an SsaInsn containing a PlainInsn with a new PlainInsn. The
     * new PlainInsn is constructed with a new RegOp and new sources.
     *
     * TODO move this somewhere else.
     *
     * @param insn {@code non-null;} an SsaInsn containing a PlainInsn
     * @param newSources {@code non-null;} new sources list for new insn
     * @param newOpcode A RegOp from {@link RegOps}
     * @param cst {@code null-ok;} constant for new instruction, if any
     */
    private void replacePlainInsn(NormalSsaInsn insn,
            RegisterSpecList newSources, int newOpcode, Constant cst) {

        Insn originalRopInsn = insn.getOriginalRopInsn();
        Rop newRop = Rops.ropFor(newOpcode, insn.getResult(), newSources, cst);
        Insn newRopInsn;
        if (cst == null) {
            newRopInsn = new PlainInsn(newRop, originalRopInsn.getPosition(),
                    insn.getResult(), newSources);
        } else {
            newRopInsn = new PlainCstInsn(newRop, originalRopInsn.getPosition(),
                    insn.getResult(), newSources, cst);
        }
        NormalSsaInsn newInsn = new NormalSsaInsn(newRopInsn, insn.getBlock());

        List<SsaInsn> insns = insn.getBlock().getInsns();

        ssaMeth.onInsnRemoved(insn);
        insns.set(insns.lastIndexOf(insn), newInsn);
        ssaMeth.onInsnAdded(newInsn);
    }
}
