/*
 * Copyright 1996-2003 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package sun.tools.tree;

import sun.tools.java.*;

/**
 * WARNING: The contents of this source file are not part of any
 * supported API.  Code that depends on them does so at its own risk:
 * they are subject to change or removal without notice.
 */
public final
class Vset implements Constants {
    long vset;                  // DA bits for first 64 variables
    long uset;                  // DU bits for first 64 variables

    // The extension array is interleaved, consisting of alternating
    // blocks of 64 DA bits followed by 64 DU bits followed by 64 DA
    // bits, and so on.

    long x[];                   // extension array for more bits

    // An infinite vector of zeroes or an infinite vector of ones is
    // represented by a special value of the extension array.
    //
    // IMPORTANT: The condition 'this.x == fullX' is used as a marker for
    // unreachable code, i.e., for a dead-end.  We maintain the invariant
    // that (this.x != fullX || (this.vset == -1 && this.uset == -1)).
    // A dead-end has the peculiar property that all variables are both
    // definitely assigned and definitely unassigned.  We always force this
    // condition to hold, even when the normal bitvector operations performed
    // during DA/DU analysis would produce a different result.  This supresses
    // reporting of DA/DU errors in unreachable code.

    static final long emptyX[] = new long[0]; // all zeroes
    static final long fullX[]  = new long[0]; // all ones

    // For more thorough testing of long vset support, it is helpful to
    // temporarily redefine this value to a smaller number, such as 1 or 2.

    static final int VBITS = 64; // number of bits in vset (uset)

    /**
     * This is the Vset which reports all vars assigned and unassigned.
     * This impossibility is degenerately true exactly when
     * control flow cannot reach this point.
     */

    // We distinguish a canonical dead-end value generated initially for
    // statements that do not complete normally, making the next one unreachable.
    // Once an unreachable statement is reported, a non-canonical dead-end value
    // is used for subsequent statements in order to suppress redundant error
    // messages.

    static final Vset DEAD_END = new Vset(-1, -1, fullX);

    /**
     * Create an empty Vset.
     */
    public Vset() {
        this.x = emptyX;
    }

    private Vset(long vset, long uset, long x[]) {
        this.vset = vset;
        this.uset = uset;
        this.x = x;
    }

    /**
     * Create an copy of the given Vset.
     * (However, DEAD_END simply returns itself.)
     */
    public Vset copy() {
        if (this == DEAD_END) {
            return this;
        }
        Vset vs = new Vset(vset, uset, x);
        if (x.length > 0) {
            vs.growX(x.length); // recopy the extension vector
        }
        return vs;
    }

    private void growX(int length) {
        long newX[] = new long[length];
        long oldX[] = x;
        for (int i = 0; i < oldX.length; i++) {
            newX[i] = oldX[i];
        }
        x = newX;
    }

    /**
     * Ask if this is a vset for a dead end.
     * Answer true only for the canonical dead-end, DEAD_END.
     * A canonical dead-end is produced only as a result of
     * a statement that cannot complete normally, as specified
     * by the JLS.  Due to the special-case rules for if-then
     * and if-then-else, this may fail to detect actual unreachable
     * code that could easily be identified.
     */

    public boolean isDeadEnd() {
        return (this == DEAD_END);
    }

    /**
     * Ask if this is a vset for a dead end.
     * Answer true for any dead-end.
     * Since 'clearDeadEnd' has no effect on this predicate,
     * if-then and if-then-else are handled in the more 'obvious'
     * and precise way.  This predicate is to be preferred for
     * dead code elimination purposes.
     * (Presently used in workaround for bug 4173473 in MethodExpression.java)
     */
    public boolean isReallyDeadEnd() {
        return (x == fullX);
    }

    /**
     * Replace canonical DEAD_END with a distinct but
     * equivalent Vset.  The bits are unaltered, but
     * the result does not answer true to 'isDeadEnd'.
     * <p>
     * Used mostly for error recovery, but see
     * 'IfStatement.check', where it is used to
     * implement the special-case treatment of
     * statement reachability for such statements.
     */
    public Vset clearDeadEnd() {
        if (this == DEAD_END) {
            return new Vset(-1, -1, fullX);
        }
        return this;
    }

    /**
     * Ask if a var is definitely assigned.
     */
    public boolean testVar(int varNumber) {
        long bit = (1L << varNumber);
        if (varNumber >= VBITS) {
            int i = (varNumber / VBITS - 1) * 2;
            if (i >= x.length) {
                return (x == fullX);
            }
            return (x[i] & bit) != 0;
        } else {
            return (vset & bit) != 0;
        }
    }

    /**
     * Ask if a var is definitely un-assigned.
     * (This is not just the negation of testVar:
     * It's possible for neither to be true.)
     */
    public boolean testVarUnassigned(int varNumber) {
        long bit = (1L << varNumber);
        if (varNumber >= VBITS) {
            // index "uset" extension
            int i = ((varNumber / VBITS - 1) * 2) + 1;
            if (i >= x.length) {
                return (x == fullX);
            }
            return (x[i] & bit) != 0;
        } else {
            return (uset & bit) != 0;
        }
    }

    /**
     * Note that a var is definitely assigned.
     * (Side-effecting.)
     */
    public Vset addVar(int varNumber) {
        if (x == fullX) {
            return this;
        }

        // gen DA, kill DU

        long bit = (1L << varNumber);
        if (varNumber >= VBITS) {
            int i = (varNumber / VBITS - 1) * 2;
            if (i >= x.length) {
                growX(i+1);
            }
            x[i] |= bit;
            if (i+1 < x.length) {
                x[i+1] &=~ bit;
            }
        } else {
            vset |= bit;
            uset &=~ bit;
        }
        return this;
    }

    /**
     * Note that a var is definitely un-assigned.
     * (Side-effecting.)
     */
    public Vset addVarUnassigned(int varNumber) {
        if (x == fullX) {
            return this;
        }

        // gen DU, kill DA

        long bit = (1L << varNumber);
        if (varNumber >= VBITS) {
            // index "uset" extension
            int i = ((varNumber / VBITS - 1) * 2) + 1;
            if (i >= x.length) {
                growX(i+1);
            }
            x[i] |= bit;
            x[i-1] &=~ bit;
        } else {
            uset |= bit;
            vset &=~ bit;
        }
        return this;
    }

    /**
     * Retract any assertion about the var.
     * This operation is ineffective on a dead-end.
     * (Side-effecting.)
     */
    public Vset clearVar(int varNumber) {
        if (x == fullX) {
            return this;
        }
        long bit = (1L << varNumber);
        if (varNumber >= VBITS) {
            int i = (varNumber / VBITS - 1) * 2;
            if (i >= x.length) {
                return this;
            }
            x[i] &=~ bit;
            if (i+1 < x.length) {
                x[i+1] &=~ bit;
            }
        } else {
            vset &=~ bit;
            uset &=~ bit;
        }
        return this;
    }

    /**
     * Join with another vset.  This is set intersection.
     * (Side-effecting.)
     */
    public Vset join(Vset other) {

        // Return a dead-end if both vsets are dead-ends.
        // Return the canonical DEAD_END only if both vsets
        // are the canonical DEAD_END.  Otherwise, an incoming
        // dead-end vset has already produced an error message,
        // and is now assumed to be reachable.
        if (this == DEAD_END) {
            return other.copy();
        }
        if (other == DEAD_END) {
            return this;
        }
        if (x == fullX) {
            return other.copy();
        }
        if (other.x == fullX) {
            return this;
        }

        // DA = DA intersection DA
        // DU = DU intersection DU

        vset &= other.vset;
        uset &= other.uset;

        if (other.x == emptyX) {
            x = emptyX;
        } else {
            // ASSERT(otherX.length > 0);
            long otherX[] = other.x;
            int selfLength = x.length;
            int limit = (otherX.length < selfLength) ? otherX.length : selfLength;
            for (int i = 0; i < limit; i++) {
                x[i] &= otherX[i];
            }
            // If self is longer than other, all remaining
            // bits are implicitly 0.  In the result, then,
            // the remaining DA and DU bits are cleared.
            for (int i = limit; i < selfLength; i++) {
                x[i] = 0;
            }
        }
        return this;
    }

    /**
     * Add in the definite assignment bits of another vset,
     * but join the definite unassignment bits.  This unusual
     * operation is used only for 'finally' blocks.  The
     * original vset 'this' is destroyed by this operation.
     * (Part of fix for 4068688.)
     */

    public Vset addDAandJoinDU(Vset other) {

        // Return a dead-end if either vset is a dead end.
        // If either vset is the canonical DEAD_END, the
        // result is also the canonical DEAD_END.
        if (this == DEAD_END) {
            return this;
        }
        if (other == DEAD_END) {
            return other;
        }
        if (x == fullX) {
            return this;
        }
        if (other.x == fullX) {
            return other.copy();
        }

        // DA = DA union DA'
        // DU = (DU intersection DU') - DA'

        vset = vset | other.vset;
        uset = (uset & other.uset) & ~other.vset;

        int selfLength = x.length;
        long otherX[] = other.x;
        int otherLength = otherX.length;

        if (otherX != emptyX) {
            // ASSERT(otherX.length > 0);
            if (otherLength > selfLength) {
                growX(otherLength);
            }
            int i = 0;
            while (i < otherLength) {
                x[i] |= otherX[i];
                i++;
                if (i == otherLength) break;
                x[i] = ((x[i] & otherX[i]) & ~otherX[i-1]);
                i++;
            }
        }
        // If self is longer than other, all remaining
        // bits are implicitly 0. In the result, then,
        // the remaining DA bits are left unchanged, and
        // the DU bits are all cleared. First, align
        // index to the next block of DU bits (odd index).
        for (int i = (otherLength | 1); i < selfLength; i += 2) {
            x[i] = 0;
        }
        return this;
    }


    /**
     * Construct a vset consisting of the DA bits of the first argument
     * and the DU bits of the second argument.  This is a higly unusual
     * operation, as it implies a case where the flowgraph for DA analysis
     * differs from that for DU analysis.  It is only needed for analysing
     * 'try' blocks.  The result is a dead-end iff the first argument is
     * dead-end. (Part of fix for 4068688.)
     */

    public static Vset firstDAandSecondDU(Vset sourceDA, Vset sourceDU) {

        // Note that reachability status is received via 'sourceDA' only!
        // This is a consequence of the fact that reachability and DA
        // analysis are performed on an identical flow graph, whereas the
        // flowgraph for DU analysis differs in the case of a 'try' statement.
        if (sourceDA.x == fullX) {
            return sourceDA.copy();
        }

        long sourceDAx[] = sourceDA.x;
        int lenDA = sourceDAx.length;
        long sourceDUx[] = sourceDU.x;
        int lenDU = sourceDUx.length;
        int limit = (lenDA > lenDU) ? lenDA : lenDU;
        long x[] = emptyX;

        if (limit > 0) {
            x = new long[limit];
            for (int i = 0; i < lenDA; i += 2) {
                x[i] = sourceDAx[i];
            }
            for (int i = 1; i < lenDU; i += 2) {
                x[i] = sourceDUx[i];
            }
        }

        return new Vset(sourceDA.vset, sourceDU.uset, x);
    }

    /**
     * Remove variables from the vset that are no longer part of
     * a context.  Zeroes are stored past varNumber.
     * (Side-effecting.)<p>
     * However, if this is a dead end, keep it so.
     * That is, leave an infinite tail of bits set.
     */
    public Vset removeAdditionalVars(int varNumber) {
        if (x == fullX) {
            return this;
        }
        long bit = (1L << varNumber);
        if (varNumber >= VBITS) {
            int i = (varNumber / VBITS - 1) * 2;
            if (i < x.length) {
                x[i] &= (bit - 1);
                if (++i < x.length) {
                    x[i] &= (bit - 1); // do the "uset" extension also
                }
                while (++i < x.length) {
                    x[i] = 0;
                }
            }
        } else {
            if (x.length > 0) {
                x = emptyX;
            }
            vset &= (bit - 1);
            uset &= (bit - 1);
        }
        return this;
    }

    /**
     * Return one larger than the highest bit set.
     */
    public int varLimit() {
        long vset;
        int result;
    scan: {
            for (int i = (x.length / 2) * 2; i >= 0; i -= 2) {
                if (i == x.length)  continue; // oops
                vset = x[i];
                if (i+1 < x.length) {
                    vset |= x[i+1]; // check the "uset" also
                }
                if (vset != 0) {
                    result = (i/2 + 1) * VBITS;
                    break scan;
                }
            }
            vset = this.vset;
            vset |= this.uset;  // check the "uset" also
            if (vset != 0) {
                result = 0;
                break scan;
            } else {
                return 0;
            }
        }
        while (vset != 0) {
            result += 1;
            vset >>>= 1;
        }
        return result;
    }

    public String toString() {
        if (this == DEAD_END)
            return "{DEAD_END}";
        StringBuffer sb = new StringBuffer("{");
        int maxVar = VBITS * (1 + (x.length+1)/2);
        for (int i = 0; i < maxVar; i++) {
            if (!testVarUnassigned(i)) {
                if (sb.length() > 1) {
                    sb.append(' ');
                }
                sb.append(i);
                if (!testVar(i)) {
                    sb.append('?'); // not definitely unassigned
                }
            }
        }
        if (x == fullX) {
            sb.append("...DEAD_END");
        }
        sb.append('}');
        return sb.toString();
    }

}
