/*
 * Copyright (c) 2014, 2015, Oracle and/or its affiliates. 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.
 *
 * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package org.graalvm.compiler.core.common;

import java.util.ArrayList;

import jdk.vm.ci.code.Architecture;
import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.PlatformKind;
import jdk.vm.ci.meta.Value;
import jdk.vm.ci.meta.ValueKind;

/**
 * Represents the type of values in the LIR. It is composed of a {@link PlatformKind} that gives the
 * low level representation of the value, and a {@link #referenceMask} that describes the location
 * of object references in the value, and optionally a {@link #derivedReferenceBase}.
 *
 * <h2>Constructing {@link LIRKind} instances</h2>
 *
 * During LIR generation, every new {@link Value} should get a {@link LIRKind} of the correct
 * {@link PlatformKind} that also contains the correct reference information. {@linkplain LIRKind
 * LIRKinds} should be created as follows:
 *
 * <p>
 * If the result value is created from one or more input values, the {@link LIRKind} should be
 * created with {@link LIRKind#combine}(inputs). If the result has a different {@link PlatformKind}
 * than the inputs, {@link LIRKind#combine}(inputs).{@link #changeType}(resultKind) should be used.
 * <p>
 * If the result is an exact copy of one of the inputs, {@link Value#getValueKind()} can be used.
 * Note that this is only correct for move-like operations, like conditional move or
 * compare-and-swap. For convert operations, {@link LIRKind#combine} should be used.
 * <p>
 * If it is known that the result will be a reference (e.g. pointer arithmetic where the end result
 * is a valid oop), {@link LIRKind#reference} should be used.
 * <p>
 * If it is known that the result will neither be a reference nor be derived from a reference,
 * {@link LIRKind#value} can be used. If the operation producing this value has inputs, this is very
 * likely wrong, and {@link LIRKind#combine} should be used instead.
 * <p>
 * If it is known that the result is derived from a reference in a way that the garbage collector
 * can not track, {@link LIRKind#unknownReference} can be used. In most cases,
 * {@link LIRKind#combine} should be used instead, since it is able to detect this automatically.
 */
public final class LIRKind extends ValueKind<LIRKind> {

    private final int referenceMask;

    private AllocatableValue derivedReferenceBase;

    private static final int UNKNOWN_REFERENCE = -1;

    public static final LIRKind Illegal = unknownReference(ValueKind.Illegal.getPlatformKind());

    private LIRKind(PlatformKind platformKind, int referenceMask, AllocatableValue derivedReferenceBase) {
        super(platformKind);
        this.referenceMask = referenceMask;
        this.derivedReferenceBase = derivedReferenceBase;

        assert derivedReferenceBase == null || !derivedReferenceBase.getValueKind(LIRKind.class).isDerivedReference() : "derived reference can't have another derived reference as base";
    }

    /**
     * Create a {@link LIRKind} of type {@code platformKind} that contains a primitive value. Should
     * be only used when it's guaranteed that the value is not even indirectly derived from a
     * reference. Otherwise, {@link #combine(Value...)} should be used instead.
     */
    public static LIRKind value(PlatformKind platformKind) {
        return new LIRKind(platformKind, 0, null);
    }

    /**
     * Create a {@link LIRKind} of type {@code platformKind} that contains a single tracked oop
     * reference.
     */
    public static LIRKind reference(PlatformKind platformKind) {
        return derivedReference(platformKind, null);
    }

    /**
     * Create the correct {@link LIRKind} for a given {@link Architecture} and {@link JavaKind}.
     */
    public static LIRKind fromJavaKind(Architecture arch, JavaKind javaKind) {
        PlatformKind platformKind = arch.getPlatformKind(javaKind);
        if (javaKind.isObject()) {
            return LIRKind.reference(platformKind);
        } else {
            return LIRKind.value(platformKind);
        }
    }

    /**
     * Create a {@link LIRKind} of type {@code platformKind} that contains a derived reference.
     */
    public static LIRKind derivedReference(PlatformKind platformKind, AllocatableValue base) {
        int length = platformKind.getVectorLength();
        assert 0 < length && length < 32 : "vector of " + length + " references not supported";
        return new LIRKind(platformKind, (1 << length) - 1, base);
    }

    /**
     * Create a {@link LIRKind} of type {@code platformKind} that contains a value that is derived
     * from a reference in a non-linear way. Values of this {@link LIRKind} can not be live at
     * safepoints. In most cases, this should not be called directly. {@link #combine} should be
     * used instead to automatically propagate this information.
     */
    public static LIRKind unknownReference(PlatformKind platformKind) {
        return new LIRKind(platformKind, UNKNOWN_REFERENCE, null);
    }

    /**
     * Create a derived reference.
     *
     * @param base An {@link AllocatableValue} containing the base pointer of the derived reference.
     */
    public LIRKind makeDerivedReference(AllocatableValue base) {
        assert !isUnknownReference() && derivedReferenceBase == null;
        if (Value.ILLEGAL.equals(base)) {
            return makeUnknownReference();
        } else {
            if (isValue()) {
                return derivedReference(getPlatformKind(), base);
            } else {
                return new LIRKind(getPlatformKind(), referenceMask, base);
            }
        }
    }

    /**
     * Derive a new type from inputs. The result will have the {@link PlatformKind} of one of the
     * inputs. If all inputs are values, the result is a value. Otherwise, the result is an unknown
     * reference.
     *
     * This method should be used to construct the result {@link LIRKind} of any operation that
     * modifies values (e.g. arithmetics).
     */
    public static LIRKind combine(Value... inputs) {
        assert inputs.length > 0;
        for (Value input : inputs) {
            LIRKind kind = input.getValueKind(LIRKind.class);
            if (kind.isUnknownReference()) {
                return kind;
            } else if (!kind.isValue()) {
                return kind.makeUnknownReference();
            }
        }

        // all inputs are values, just return one of them
        return inputs[0].getValueKind(LIRKind.class);
    }

    /**
     * Merge the types of the inputs. The result will have the {@link PlatformKind} of one of the
     * inputs. If all inputs are values (references), the result is a value (reference). Otherwise,
     * the result is an unknown reference.
     *
     * This method should be used to construct the result {@link LIRKind} of merge operation that
     * does not modify values (e.g. phis).
     */
    public static LIRKind merge(Value... inputs) {
        assert inputs.length > 0;
        ArrayList<LIRKind> kinds = new ArrayList<>(inputs.length);
        for (int i = 0; i < inputs.length; i++) {
            kinds.add(inputs[i].getValueKind(LIRKind.class));
        }
        return merge(kinds);
    }

    /**
     * Helper method to construct derived reference kinds. Returns the base value of a reference or
     * derived reference. For values it returns {@code null}, and for unknown references it returns
     * {@link Value#ILLEGAL}.
     */
    public static AllocatableValue derivedBaseFromValue(AllocatableValue value) {
        ValueKind<?> valueKind = value.getValueKind();
        if (valueKind instanceof LIRKind) {
            LIRKind kind = value.getValueKind(LIRKind.class);
            if (kind.isValue()) {
                return null;
            } else if (kind.isDerivedReference()) {
                return kind.getDerivedReferenceBase();
            } else if (kind.isUnknownReference()) {
                return Value.ILLEGAL;
            } else {
                // kind is a reference
                return value;
            }
        } else {
            return Value.ILLEGAL;
        }
    }

    /**
     * Helper method to construct derived reference kinds. If one of {@code base1} or {@code base2}
     * are set, it creates a derived reference using it as the base. If both are set, the result is
     * an unknown reference.
     */
    public static LIRKind combineDerived(LIRKind kind, AllocatableValue base1, AllocatableValue base2) {
        if (base1 == null && base2 == null) {
            return kind;
        } else if (base1 == null) {
            return kind.makeDerivedReference(base2);
        } else if (base2 == null) {
            return kind.makeDerivedReference(base1);
        } else {
            return kind.makeUnknownReference();
        }
    }

    /**
     * @see #merge(Value...)
     */
    public static LIRKind merge(Iterable<LIRKind> kinds) {
        LIRKind mergeKind = null;

        for (LIRKind kind : kinds) {

            if (kind.isUnknownReference()) {
                /**
                 * Kind is an unknown reference, therefore the result can only be also an unknown
                 * reference.
                 */
                mergeKind = kind;
                break;
            }
            if (mergeKind == null) {
                mergeKind = kind;
                continue;
            }

            if (kind.isValue()) {
                /* Kind is a value. */
                if (mergeKind.referenceMask != 0) {
                    /*
                     * Inputs consists of values and references. Make the result an unknown
                     * reference.
                     */
                    mergeKind = mergeKind.makeUnknownReference();
                    break;
                }
                /* Check that other inputs are also values. */
            } else {
                /* Kind is a reference. */
                if (mergeKind.referenceMask != kind.referenceMask) {
                    /*
                     * Reference maps do not match so the result can only be an unknown reference.
                     */
                    mergeKind = mergeKind.makeUnknownReference();
                    break;
                }
            }

        }
        assert mergeKind != null && verifyMerge(mergeKind, kinds);

        // all inputs are values or references, just return one of them
        return mergeKind;
    }

    private static boolean verifyMerge(LIRKind mergeKind, Iterable<LIRKind> kinds) {
        for (LIRKind kind : kinds) {
            assert mergeKind == null || verifyMoveKinds(mergeKind, kind) : String.format("Input kinds do not match %s vs. %s", mergeKind, kind);
        }
        return true;
    }

    /**
     * Create a new {@link LIRKind} with the same reference information and a new
     * {@linkplain #getPlatformKind platform kind}. If the new kind is a longer vector than this,
     * the new elements are marked as untracked values.
     */
    @Override
    public LIRKind changeType(PlatformKind newPlatformKind) {
        if (newPlatformKind == getPlatformKind()) {
            return this;
        } else if (isUnknownReference()) {
            return unknownReference(newPlatformKind);
        } else if (referenceMask == 0) {
            // value type
            return LIRKind.value(newPlatformKind);
        } else {
            // reference type
            int newLength = Math.min(32, newPlatformKind.getVectorLength());
            int newReferenceMask = referenceMask & (0xFFFFFFFF >>> (32 - newLength));
            assert newReferenceMask != UNKNOWN_REFERENCE;
            return new LIRKind(newPlatformKind, newReferenceMask, derivedReferenceBase);
        }
    }

    /**
     * Create a new {@link LIRKind} with a new {@linkplain #getPlatformKind platform kind}. If the
     * new kind is longer than this, the reference positions are repeated to fill the vector.
     */
    public LIRKind repeat(PlatformKind newPlatformKind) {
        if (isUnknownReference()) {
            return unknownReference(newPlatformKind);
        } else if (referenceMask == 0) {
            // value type
            return LIRKind.value(newPlatformKind);
        } else {
            // reference type
            int oldLength = getPlatformKind().getVectorLength();
            int newLength = newPlatformKind.getVectorLength();
            assert oldLength <= newLength && newLength < 32 && (newLength % oldLength) == 0;

            // repeat reference mask to fill new kind
            int newReferenceMask = 0;
            for (int i = 0; i < newLength; i += getPlatformKind().getVectorLength()) {
                newReferenceMask |= referenceMask << i;
            }

            assert newReferenceMask != UNKNOWN_REFERENCE;
            return new LIRKind(newPlatformKind, newReferenceMask, derivedReferenceBase);
        }
    }

    /**
     * Create a new {@link LIRKind} with the same type, but marked as containing an
     * {@link LIRKind#unknownReference}.
     */
    public LIRKind makeUnknownReference() {
        return new LIRKind(getPlatformKind(), UNKNOWN_REFERENCE, null);
    }

    /**
     * Check whether this value is a derived reference.
     */
    public boolean isDerivedReference() {
        return getDerivedReferenceBase() != null;
    }

    /**
     * Get the base value of a derived reference.
     */
    public AllocatableValue getDerivedReferenceBase() {
        return derivedReferenceBase;
    }

    /**
     * Change the base value of a derived reference. This must be called on derived references only.
     */
    public void setDerivedReferenceBase(AllocatableValue derivedReferenceBase) {
        assert isDerivedReference();
        this.derivedReferenceBase = derivedReferenceBase;
    }

    /**
     * Check whether this value is derived from a reference in a non-linear way. If this returns
     * {@code true}, this value must not be live at safepoints.
     */
    public boolean isUnknownReference() {
        return referenceMask == UNKNOWN_REFERENCE;
    }

    public static boolean isUnknownReference(ValueKind<?> kind) {
        if (kind instanceof LIRKind) {
            return ((LIRKind) kind).isUnknownReference();
        } else {
            return true;
        }
    }

    public static boolean isUnknownReference(Value value) {
        return isUnknownReference(value.getValueKind());
    }

    public int getReferenceCount() {
        assert !isUnknownReference();
        return Integer.bitCount(referenceMask);
    }

    /**
     * Check whether the {@code idx}th part of this value is a reference that must be tracked at
     * safepoints.
     *
     * @param idx The index into the vector if this is a vector kind. Must be 0 if this is a scalar
     *            kind.
     */
    public boolean isReference(int idx) {
        assert 0 <= idx && idx < getPlatformKind().getVectorLength() : "invalid index " + idx + " in " + this;
        return !isUnknownReference() && (referenceMask & 1 << idx) != 0;
    }

    /**
     * Check whether this kind is a value type that doesn't need to be tracked at safepoints.
     */
    public boolean isValue() {
        return referenceMask == 0;
    }

    public static boolean isValue(ValueKind<?> kind) {
        if (kind instanceof LIRKind) {
            return ((LIRKind) kind).isValue();
        } else {
            return false;
        }
    }

    public static boolean isValue(Value value) {
        return isValue(value.getValueKind());
    }

    @Override
    public String toString() {
        if (isValue()) {
            return getPlatformKind().name();
        } else if (isUnknownReference()) {
            return getPlatformKind().name() + "[*]";
        } else {
            StringBuilder ret = new StringBuilder();
            ret.append(getPlatformKind().name());
            ret.append('[');
            for (int i = 0; i < getPlatformKind().getVectorLength(); i++) {
                if (isReference(i)) {
                    ret.append('.');
                } else {
                    ret.append(' ');
                }
            }
            ret.append(']');
            return ret.toString();
        }
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((getPlatformKind() == null) ? 0 : getPlatformKind().hashCode());
        result = prime * result + referenceMask;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (!(obj instanceof LIRKind)) {
            return false;
        }

        LIRKind other = (LIRKind) obj;
        return getPlatformKind() == other.getPlatformKind() && referenceMask == other.referenceMask;
    }

    public static boolean verifyMoveKinds(ValueKind<?> dst, ValueKind<?> src) {
        if (src.equals(dst)) {
            return true;
        }
        if (src.getPlatformKind().equals(dst.getPlatformKind())) {
            return !isUnknownReference(src) || isUnknownReference(dst);
        }
        return false;
    }
}
