/*
 * 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.RegisterSpecList;
import com.android.dx.rop.code.RegisterSpec;
import com.android.dx.ssa.back.InterferenceGraph;
import com.android.dx.util.IntSet;
import com.android.dx.util.BitIntSet;

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

/**
 * A register mapper that keeps track of the accumulated interference
 * information for the registers in the new namespace.
 *
 * Please note that this mapper requires that the old namespace does not
 * have variable register widths/categories, and the new namespace does.
 */
public class InterferenceRegisterMapper extends BasicRegisterMapper {
    /**
     * Array of interference sets. ArrayList is indexed by new namespace
     * and BitIntSet's are indexed by old namespace.  The list expands
     * as needed and missing items are assumed to interfere with nothing.
     *
     * Bit sets are always used here, unlike elsewhere, because the max
     * size of this matrix will be (countSsaRegs * countRopRegs), which may
     * grow to hundreds of K but not megabytes.
     */
    private final ArrayList<BitIntSet> newRegInterference;

    /** the interference graph for the old namespace */
    private final InterferenceGraph oldRegInterference;

    /**
     * Constructs an instance
     * 
     * @param countOldRegisters number of registers in old namespace
     */
    public InterferenceRegisterMapper(InterferenceGraph oldRegInterference,
            int countOldRegisters) {
        super(countOldRegisters);

        newRegInterference = new ArrayList<BitIntSet>();
        this.oldRegInterference = oldRegInterference;
    }

    /** {@inheritDoc} */
    @Override
    public void addMapping(int oldReg, int newReg, int category) {
        super.addMapping(oldReg, newReg, category);

        addInterfence(newReg, oldReg);

        if (category == 2) {
            addInterfence(newReg + 1, oldReg);
        }
    }

    /**
     * Checks to see if old namespace reg {@code oldReg} interferes
     * with what currently maps to {@code newReg}.
     *
     * @param oldReg old namespace register
     * @param newReg new namespace register
     * @param category category of old namespace register
     * @return true if oldReg will interfere with newReg
     */
    public boolean interferes(int oldReg, int newReg, int category) {
        if (newReg >= newRegInterference.size()) {
            return false;
        } else {
            IntSet existing = newRegInterference.get(newReg);

            if (existing == null) {
                return false;
            } else if (category == 1) {
                return existing.has(oldReg);
            } else {
                return existing.has(oldReg)
                        || (interferes(oldReg, newReg+1, category-1));
            }
        }
    }

    /**
     * Checks to see if old namespace reg {@code oldReg} interferes
     * with what currently maps to {@code newReg}.
     *
     * @param oldSpec {@code non-null;} old namespace register
     * @param newReg new namespace register
     * @return true if oldReg will interfere with newReg
     */
    public boolean interferes(RegisterSpec oldSpec, int newReg) {
        return interferes(oldSpec.getReg(), newReg, oldSpec.getCategory());
    }

    /**
     * Adds a register's interference set to the interference list,
     * growing it if necessary.
     * 
     * @param newReg register in new namespace
     * @param oldReg register in old namespace
     */
    private void addInterfence(int newReg, int oldReg) {
        newRegInterference.ensureCapacity(newReg + 1);

        while (newReg >= newRegInterference.size()) {
            newRegInterference.add(new BitIntSet(newReg +1));
        }

        oldRegInterference.mergeInterferenceSet(
                oldReg, newRegInterference.get(newReg));
    }

    /**
     * Checks to see if any of a set of old-namespace registers are
     * pinned to the specified new-namespace reg + category. Takes into
     * account the category of the old-namespace registers.
     *
     * @param oldSpecs {@code non-null;} set of old-namespace regs
     * @param newReg {@code >= 0;} new-namespace register
     * @param targetCategory {@code 1..2;} the number of adjacent new-namespace
     * registers (starting at ropReg) to consider
     * @return true if any of the old-namespace register have been mapped
     * to the new-namespace register + category
     */
    public boolean areAnyPinned(RegisterSpecList oldSpecs,
            int newReg, int targetCategory) {
        int sz = oldSpecs.size();

        for (int i = 0; i < sz; i++) {
            RegisterSpec oldSpec = oldSpecs.get(i);
            int r = oldToNew(oldSpec.getReg());

            /*
             * If oldSpec is a category-2 register, then check both newReg
             * and newReg - 1.
             */
            if (r == newReg
                || (oldSpec.getCategory() == 2 && (r + 1) == newReg)
                || (targetCategory == 2 && (r == newReg + 1))) {
                return true;
            }
        }
        
        return false;
    }
}
