/*
 * Copyright (C) 2015-2021 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#include "config.h"
#include "DFGIntegerRangeOptimizationPhase.h"

#if ENABLE(DFG_JIT)

#include "DFGBlockMapInlines.h"
#include "DFGBlockSet.h"
#include "DFGGraph.h"
#include "DFGInsertionSet.h"
#include "DFGNodeFlowProjection.h"
#include "DFGPhase.h"
#include "JSCJSValueInlines.h"

namespace JSC { namespace DFG {

namespace {

namespace DFGIntegerRangeOptimizationPhaseInternal {
static constexpr bool verbose = false;
}
const unsigned giveUpThreshold = 50;

int64_t clampedSumImpl() { return 0; }

template<typename... Args>
int64_t clampedSumImpl(int left, Args... args)
{
    return static_cast<int64_t>(left) + clampedSumImpl(args...);
}

template<typename... Args>
int clampedSum(Args... args)
{
    int64_t result = clampedSumImpl(args...);
    return static_cast<int>(std::min(
        static_cast<int64_t>(std::numeric_limits<int>::max()),
        std::max(
            static_cast<int64_t>(std::numeric_limits<int>::min()),
            result)));
}

bool isGeneralOffset(int offset)
{
    return offset >= -1 && offset <= 1;
}

class Relationship {
public:
    enum Kind {
        LessThan,
        Equal,
        NotEqual,
        GreaterThan
    };

    // Some relationships provide more information than others. When a relationship provides more
    // information, it is less vague.
    static unsigned vagueness(Kind kind)
    {
        switch (kind) {
        case Equal:
            return 0;
        case LessThan:
        case GreaterThan:
            return 1;
        case NotEqual:
            return 2;
        }
        RELEASE_ASSERT_NOT_REACHED();
        return 0;
    }

    static constexpr unsigned minVagueness = 0;
    static constexpr unsigned maxVagueness = 2;
    
    static Kind flipped(Kind kind)
    {
        switch (kind) {
        case LessThan:
            return GreaterThan;
        case Equal:
            return Equal;
        case NotEqual:
            return NotEqual;
        case GreaterThan:
            return LessThan;
        }
        RELEASE_ASSERT_NOT_REACHED();
        return kind;
    }
    
    Relationship()
        : m_left(nullptr)
        , m_right(nullptr)
        , m_kind(Equal)
        , m_offset(0)
    {
    }
    
    Relationship(NodeFlowProjection left, NodeFlowProjection right, Kind kind, int offset = 0)
        : m_left(left)
        , m_right(right)
        , m_kind(kind)
        , m_offset(offset)
    {
        RELEASE_ASSERT(m_left);
        RELEASE_ASSERT(m_right);
        RELEASE_ASSERT(m_left != m_right);
    }
    
    static Relationship safeCreate(NodeFlowProjection left, NodeFlowProjection right, Kind kind, int offset = 0)
    {
        if (!left.isStillValid() || !right.isStillValid() || left == right)
            return Relationship();
        return Relationship(left, right, kind, offset);
    }

    explicit operator bool() const { return !!m_left; }
    
    NodeFlowProjection left() const { return m_left; }
    NodeFlowProjection right() const { return m_right; }
    Kind kind() const { return m_kind; }
    int offset() const { return m_offset; }

    unsigned vagueness() const { return vagueness(kind()); }
    
    Relationship flipped() const
    {
        if (!*this)
            return Relationship();
        
        // This should return Relationship() if -m_offset overflows. For example:
        //
        //     @a > @b - 2**31
        //
        // If we flip it we get:
        //
        //     @b < @a + 2**31
        //
        // Except that the sign gets flipped since it's INT_MIN:
        //
        //     @b < @a - 2**31
        //
        // And that makes no sense. To see how little sense it makes, consider:
        //
        //     @a > @zero - 2**31
        //
        // We would flip it to mean:
        //
        //     @zero < @a - 2**31
        //
        // Which is absurd.
        
        if (m_offset == std::numeric_limits<int>::min())
            return Relationship();
        
        return Relationship(m_right, m_left, flipped(m_kind), -m_offset);
    }
    
    Relationship inverse() const
    {
        if (!*this)
            return *this;
        
        switch (m_kind) {
        case Equal:
            return Relationship(m_left, m_right, NotEqual, m_offset);
        case NotEqual:
            return Relationship(m_left, m_right, Equal, m_offset);
        case LessThan:
            if (sumOverflows<int>(m_offset, -1))
                return Relationship();
            return Relationship(m_left, m_right, GreaterThan, m_offset - 1);
        case GreaterThan:
            if (sumOverflows<int>(m_offset, 1))
                return Relationship();
            return Relationship(m_left, m_right, LessThan, m_offset + 1);
        }
        
        RELEASE_ASSERT_NOT_REACHED();
    }
    
    bool isCanonical() const { return m_left < m_right; }
    
    Relationship canonical() const
    {
        if (isCanonical())
            return *this;
        return flipped();
    }
    
    bool sameNodesAs(const Relationship& other) const
    {
        return m_left == other.m_left
            && m_right == other.m_right;
    }

    bool isEquivalentTo(const Relationship& other) const
    {
        if (m_left != other.m_left || m_kind != other.m_kind)
            return false;

        if (*this == other)
            return true;

        if (m_right->isInt32Constant() && other.m_right->isInt32Constant()) {
            int thisRight = m_right->asInt32();
            int otherRight = other.m_right->asInt32();

            if (sumOverflows<int>(thisRight, m_offset))
                return false;
            if (sumOverflows<int>(otherRight, other.m_offset))
                return false;

            return (thisRight + m_offset) == (otherRight + other.m_offset);
        }
        return false;
    }
    
    bool operator==(const Relationship& other) const
    {
        return sameNodesAs(other)
            && m_kind == other.m_kind
            && m_offset == other.m_offset;
    }
    
    bool operator!=(const Relationship& other) const
    {
        return !(*this == other);
    }
    
    bool operator<(const Relationship& other) const
    {
        if (m_left != other.m_left)
            return m_left < other.m_left;
        if (m_right != other.m_right)
            return m_right < other.m_right;
        if (m_kind != other.m_kind)
            return m_kind < other.m_kind;
        return m_offset < other.m_offset;
    }
    
    // If possible, returns a form of this relationship where the given node is the left
    // side. Returns a null relationship if this relationship cannot say anything about this
    // node.
    Relationship forNode(NodeFlowProjection node) const
    {
        if (m_left == node)
            return *this;
        if (m_right == node)
            return flipped();
        return Relationship();
    }
    
    void setLeft(NodeFlowProjection left)
    {
        RELEASE_ASSERT(left != m_right);
        m_left = left;
    }
    void setRight(NodeFlowProjection right)
    {
        RELEASE_ASSERT(right != m_left);
        m_right = right;
    }
    bool addToOffset(int offset)
    {
        if (sumOverflows<int>(m_offset, offset))
            return false;
        m_offset += offset;
        return true;
    }

    // Attempts to create relationships that summarize the union of this relationship and
    // the other relationship. Relationships are returned by calling the functor with the newly
    // created relationships. No relationships are created to indicate TOP. This is used
    // for merging the current relationship-at-head for some pair of nodes and a new
    // relationship-at-head being proposed by a predecessor. We wish to create a new
    // relationship that is true whenever either of them are true, which ensuring that we don't
    // do this forever. Anytime we create a relationship that is not equal to either of the
    // previous ones, we will cause the analysis fixpoint to reexecute.
    //
    // If *this and other are identical, we just pass it to the functor.
    //
    // If they are different, we pick from a finite set of "general" relationships:
    //
    // Eq: this == other + C, where C is -1, 0, or 1.
    // Lt: this < other + C, where C is -1, 0, or 1.
    // Gt: this > other + C, where C is -1, 0, or 1.
    // Ne: this != other + C, where C is -1, 0, or 1.
    // TOP: the null relationship.
    //
    // Constraining C to -1,0,1 is necessary to ensure that the set of general relationships is
    // finite. This finite set of relationships forms a pretty simple lattice where a
    // relA->relB means "relB is more general than relA". For example, this<other+1 is more
    // general than this==other. I'll leave it as an exercise for the reader to see that a
    // graph between the 13 general relationships is indeed a lattice. The fact that the set of
    // general relationships is a finite lattice ensures monotonicity of the fixpoint, since
    // any merge over not-identical relationships returns a relationship that is closer to the
    // TOP relationship than either of the original relationships. Here's how convergence is
    // achieved for any pair of relationships over the same nodes:
    //
    // - If they are identical, then returning *this means that we won't be responsible for
    //   causing another fixpoint iteration. Once all merges reach this point, we're done.
    //
    // - If they are different, then we pick the most constraining of the 13 general
    //   relationships that is true if either *this or other are true. This means that if the
    //   relationships are not identical, the merged relationship will be closer to TOP than
    //   either of the originals. Returning a different relationship means that we will be
    //   responsible for the fixpoint to reloop, but we can only do this at most 13 times since
    //   that's how "deep" the general relationship lattice is.
    //
    // Note that C being constrained to -1,0,1 also ensures that we never have to return a
    // combination of Lt and Gt, as in for example this<other+C && this>other-D. The only possible
    // values of C and D where this would work are -1 and 1, but in that case we just say
    // this==other. That said, the logic for merging two == relationships, like this==other+C ||
    // this==other+D is to attempt to create these two relationships: this>other+min(C,D)-1 &&
    // this<other+max(C,D)+1. But only one of these relationships will belong to the set of general
    // relationships.
    //
    // Here's an example of this in action:
    //
    // for (var i = a; ; ++i) { }
    //
    // Without C being constrained to -1,0,1, we could end up looping forever: first we'd say
    // that i==a, then we might say that i<a+2, then i<a+3, then i<a+4, etc. We won't do this
    // because i<a+2 is not a valid general relationship: so when we merge i==a from the first
    // iteration and i==a+1 from the second iteration, we create i>a-1 and i<a+2 but then
    // realize that only i>a-1 is a valid general relationship. This gives us exactly what we
    // want: a statement that i>=a.
    //
    // However, this may return a pair of relationships when merging relationships involving
    // constants. For example, if given:
    //
    //     @x == @c
    //     @x == @d
    //
    // where @c and @d are constants, then this may pass two relationships to the functor:
    //
    //     @x > min(@c, @d) - 1
    //     @x < max(@c, @d) + 1
    //
    // This still allows for convergence, because just as when merging relationships over
    // variables, this always picks from a set of general relationships. Hence although this may
    // produce two relationships as a result of the merge, the total number of relationships that
    // can be present at head of block is limited by O(graph.size^2).
    template<typename Functor>
    void merge(const Relationship& other, const Functor& functor) const
    {
        // Handle the super obvious case first.
        if (*this == other) {
            functor(*this);
            return;
        }
        
        if (m_left != other.m_left)
            return;
        
        if (m_right != other.m_right) {
            mergeConstantsImpl(other, functor);
            return;
        }
        
        ASSERT(sameNodesAs(other));
        
        // This does some interesting permutations to reduce the amount of duplicate code. For
        // example:
        //
        // initially: @a != @b, @a > @b
        //            @b != @a, @b < @a
        //            @b < @a, @b != @a
        //   finally: @b != a, @b < @a
        //
        // Another example:
        //
        // initially: @a < @b, @a != @b
        //   finally: @a != @b, @a < @b

        Relationship a = *this;
        Relationship b = other;
        bool needFlip = false;
        
        // Get rid of GreaterThan.
        if (a.m_kind == GreaterThan || b.m_kind == GreaterThan) {
            a = a.flipped();
            b = b.flipped();
            
            // In rare cases, we might not be able to flip. Just give up on life in those
            // cases.
            if (!a || !b)
                return;
            
            needFlip = true;
            
            // If we still have GreaterThan, then it means that we started with @a < @b and
            // @a > @b. That's pretty much always a tautology; we don't attempt to do smart
            // things for that case for now.
            if (a.m_kind == GreaterThan || b.m_kind == GreaterThan)
                return;
        }
        
        // Make sure that if we have a LessThan, then it's first.
        if (b.m_kind == LessThan)
            std::swap(a, b);
        
        // Make sure that if we have a NotEqual, then it's first.
        if (b.m_kind == NotEqual)
            std::swap(a, b);
        
        Relationship result = a.mergeImpl(b);
        if (!result)
            return;
        
        if (needFlip)
            result = result.flipped();
        
        functor(result);
    }
    
    // Attempts to construct one Relationship that adequately summarizes the intersection of
    // this and other. Returns a null relationship if the filtration should be expressed as two
    // different relationships. Returning null is always safe because relationship lists in
    // this phase always imply intersection. So, you could soundly skip calling this method and
    // just put both relationships into the list. But, that could lead the fixpoint to diverge.
    // Hence this will attempt to combine the two relationships into one as a convergence hack.
    // In some cases, it will do something conservative. It's always safe for this to return
    // *this, or to return other. It'll do that sometimes, mainly to accelerate convergence for
    // things that we don't think are important enough to slow down the analysis.
    Relationship filter(const Relationship& other) const
    {
        // We are only interested in merging relationships over the same nodes.
        ASSERT(sameNodesAs(other));
        
        if (*this == other)
            return *this;
        
        // From here we can assume that the two relationships are not identical. Usually we use
        // this to assume that we have different offsets anytime that everything but the offset
        // is identical.
        
        // We want equality to take precedent over everything else, and we don't want multiple
        // independent claims of equality. That would just be a contradiction. When it does
        // happen, we will be conservative in the sense that we will pick one.
        if (m_kind == Equal)
            return *this;
        if (other.m_kind == Equal)
            return other;
        
        // Useful helper for flipping.
        auto filterFlipped = [&] () -> Relationship {
            // If we cannot flip, then just conservatively return *this.
            Relationship a = flipped();
            Relationship b = other.flipped();
            if (!a || !b)
                return *this;
            Relationship result = a.filter(b);
            if (!result)
                return Relationship();
            result = result.flipped();
            if (!result)
                return *this;
            return result;
        };
        
        if (m_kind == NotEqual) {
            if (other.m_kind == NotEqual) {
                // We could do something smarter here. We could even keep both NotEqual's. We
                // would need to make sure that we correctly collapsed them when merging. But
                // for now, we just pick one of them and hope for the best.
                return *this;
            }
            
            if (other.m_kind == GreaterThan) {
                // Implement this in terms of NotEqual.filter(LessThan). 
                return filterFlipped();
            }
            
            ASSERT(other.m_kind == LessThan);
            // We have two claims:
            //     @a != @b + C
            //     @a  < @b + D
            //
            // If C >= D, then the NotEqual is redundant.
            // If C < D - 1, then we could keep both, but for now we just keep the LessThan.
            // If C == D - 1, then the LessThan can be turned into:
            //
            //     @a < @b + C
            //
            // Note that C == this.m_offset, D == other.m_offset.
            
            if (m_offset == other.m_offset - 1)
                return Relationship(m_left, m_right, LessThan, m_offset);
            
            return other;
        }
        
        if (other.m_kind == NotEqual)
            return other.filter(*this);
        
        if (m_kind == LessThan) {
            if (other.m_kind == LessThan) {
                return Relationship(
                    m_left, m_right, LessThan, std::min(m_offset, other.m_offset));
            }
            
            ASSERT(other.m_kind == GreaterThan);
            if (sumOverflows<int>(m_offset, -1))
                return Relationship();
            if (sumOverflows<int>(other.m_offset, 1))
                return Relationship();
            if (m_offset - 1 == other.m_offset + 1)
                return Relationship(m_left, m_right, Equal, m_offset - 1);
            
            return Relationship();
        }
        
        ASSERT(m_kind == GreaterThan);
        return filterFlipped();
    }

    // Come up with a relationship that is the best description of this && other, provided that left() is
    // the same and right() is a constant. Also requires that this is at least as vague as other. It may
    // return this or it may return something else, but whatever it returns, it will have the same nodes as
    // this. This is not automatically done by filter() because it currently only makes sense to call this
    // during a very particular part of setOneSide().
    Relationship filterConstant(const Relationship& other) const
    {
        ASSERT(m_left == other.m_left);
        ASSERT(m_right->isInt32Constant());
        ASSERT(other.m_right->isInt32Constant());
        ASSERT(vagueness() >= other.vagueness());

        if (vagueness() == other.vagueness())
            return *this;

        int thisRight = m_right->asInt32();
        int otherRight = other.m_right->asInt32();
        
        // Ignore funny business.
        if (sumOverflows<int>(otherRight, other.m_offset))
            return *this;

        int otherEffectiveRight = otherRight + other.m_offset;

        switch (other.m_kind) {
        case Equal:
            if (differenceOverflows<int>(otherEffectiveRight, thisRight))
                return *this;

            // Return a version of *this that is Equal to other's constant.
            return Relationship(m_left, m_right, Equal, otherEffectiveRight - thisRight);

        case LessThan:
        case GreaterThan:
            ASSERT(m_kind == NotEqual);
            // We could do smart things here. But we don't currently have an example of when it would be
            // valuable. Note that you have to be careful. We could refine NotEqual to LessThan, but only
            // if the LessThan subsumes the NotEqual.
            return *this;
            
        case NotEqual:
            RELEASE_ASSERT_NOT_REACHED();
            return Relationship();
        }

        RELEASE_ASSERT_NOT_REACHED();
        return Relationship();
    }
    
    int minValueOfLeft() const
    {
        if (m_left->isInt32Constant())
            return m_left->asInt32();
        
        if (m_kind == LessThan || m_kind == NotEqual)
            return std::numeric_limits<int>::min();
        
        int minRightValue = std::numeric_limits<int>::min();
        if (m_right->isInt32Constant())
            minRightValue = m_right->asInt32();
        
        if (m_kind == GreaterThan)
            return clampedSum(minRightValue, m_offset, 1);
        ASSERT(m_kind == Equal);
        return clampedSum(minRightValue, m_offset);
    }
    
    int maxValueOfLeft() const
    {
        if (m_left->isInt32Constant())
            return m_left->asInt32();
        
        if (m_kind == GreaterThan || m_kind == NotEqual)
            return std::numeric_limits<int>::max();
        
        int maxRightValue = std::numeric_limits<int>::max();
        if (m_right->isInt32Constant())
            maxRightValue = m_right->asInt32();
        
        if (m_kind == LessThan)
            return clampedSum(maxRightValue, m_offset, -1);
        ASSERT(m_kind == Equal);
        return clampedSum(maxRightValue, m_offset);
    }
    
    void dump(PrintStream& out) const
    {
        // This prints out the relationship without any whitespace, like @x<@y+42. This
        // optimizes for the clarity of a list of relationships. It's easier to read something
        // like [@1<@2+3, @4==@5-6] than it would be if there was whitespace inside the
        // relationships.
        
        if (!*this) {
            out.print("null");
            return;
        }
        
        out.print(m_left);
        switch (m_kind) {
        case LessThan:
            out.print("<");
            break;
        case Equal:
            out.print("==");
            break;
        case NotEqual:
            out.print("!=");
            break;
        case GreaterThan:
            out.print(">");
            break;
        }
        out.print(m_right);
        if (m_offset > 0)
            out.print("+", m_offset);
        else if (m_offset < 0)
            out.print("-", -static_cast<int64_t>(m_offset));
    }
    
private:
    Relationship mergeImpl(const Relationship& other) const
    {
        ASSERT(sameNodesAs(other));
        ASSERT(m_kind != GreaterThan);
        ASSERT(other.m_kind != GreaterThan);
        ASSERT(*this != other);
        
        // The purpose of this method is to guarantee that:
        //
        // - We avoid having more than one Relationship over the same two nodes. Therefore, if
        //   the merge could be expressed as two Relationships, we prefer to instead pick the
        //   less precise single Relationship form even if that means TOP.
        //
        // - If the difference between two Relationships is just the m_offset, then we create a
        //   Relationship that has an offset of -1, 0, or 1. This is an essential convergence
        //   hack. We need -1 and 1 to support <= and >=.
        
        // From here we can assume that the two relationships are not identical. Usually we use
        // this to assume that we have different offsets anytime that everything but the offset
        // is identical.
        
        if (m_kind == NotEqual) {
            if (other.m_kind == NotEqual)
                return Relationship(); // Different offsets, so tautology.
            
            if (other.m_kind == Equal) {
                if (m_offset != other.m_offset) {
                    // Saying that you might be B when you've already said that you're anything
                    // but A, where A and B are different, is a tautology. You could just say
                    // that you're anything but A. Adding "(a == b + 1)" to "(a != b + 5)" has
                    // no value.
                    return *this;
                }
                // Otherwise, same offsets: we're saying that you're either A or you're not
                // equal to A.
                
                return Relationship();
            }
            
            RELEASE_ASSERT(other.m_kind == LessThan);
            // We have these claims, and we're merging them:
            //     @a != @b + C
            //     @a < @b + D
            //
            // If we have C == D, then the merge is clearly just the NotEqual.
            // If we have C < D, then the merge is a tautology.
            // If we have C > D, then we could keep both claims, but we are cheap, so we
            // don't. We just use the NotEqual.
            
            if (m_offset < other.m_offset)
                return Relationship();
            
            return *this;
        }
        
        if (m_kind == LessThan) {
            if (other.m_kind == LessThan) {
                // Figure out what offset to select to merge them. The appropriate offsets are
                // -1, 0, or 1.
                
                // First figure out what offset we'd like to use.
                int bestOffset = std::max(m_offset, other.m_offset);
                
                // We have something like @a < @b + 2. We can't represent this under the
                // -1,0,1 rule.
                if (isGeneralOffset(bestOffset))
                    return Relationship(m_left, m_right, LessThan, std::max(bestOffset, -1));
                
                return Relationship();
            }
            
            // The only thing left is Equal. We would have eliminated the GreaterThan's, and
            // if we merge LessThan and NotEqual, the NotEqual always comes first.
            RELEASE_ASSERT(other.m_kind == Equal);
            
            // This is the really interesting case. We have:
            //
            //     @a < @b + C
            //
            // and:
            //
            //     @a == @b + D
            //
            // Therefore we'd like to return:
            //
            //     @a < @b + max(C, D + 1)
            
            if (sumOverflows<int32_t>(other.m_offset, 1))
                return Relationship();

            int bestOffset = std::max(m_offset, other.m_offset + 1);
            
            // We have something like @a < @b + 2. We can't do it.
            if (isGeneralOffset(bestOffset))
                return Relationship(m_left, m_right, LessThan, std::max(bestOffset, -1));

            return Relationship();
        }
        
        // The only thing left is Equal, since we would have gotten rid of the GreaterThan's.
        RELEASE_ASSERT(m_kind == Equal);
        
        // We would never see NotEqual, because those always come first. We would never
        // see GreaterThan, because we would have eliminated those. We would never see
        // LessThan, because those always come first.
        
        RELEASE_ASSERT(other.m_kind == Equal);
        // We have @a == @b + C and @a == @b + D, where C != D. Turn this into some
        // inequality that involves a constant that is -1,0,1. Note that we will never have
        // lessThan and greaterThan because the constants are constrained to -1,0,1. The only
        // way for both of them to be valid is a<b+1 and a>b-1, but then we would have said
        // a==b.

        Relationship lessThan;
        Relationship greaterThan;
        
        int lessThanEqOffset = std::max(m_offset, other.m_offset);
        if (lessThanEqOffset >= -2 && lessThanEqOffset <= 0) {
            lessThan = Relationship(
                m_left, other.m_right, LessThan, lessThanEqOffset + 1);
            
            ASSERT(isGeneralOffset(lessThan.offset()));
        }
        
        int greaterThanEqOffset = std::min(m_offset, other.m_offset);
        if (greaterThanEqOffset >= 0 && greaterThanEqOffset <= 2) {
            greaterThan = Relationship(
                m_left, other.m_right, GreaterThan, greaterThanEqOffset - 1);
            
            ASSERT(isGeneralOffset(greaterThan.offset()));
        }
        
        if (lessThan) {
            // Both relationships cannot be valid; see above.
            RELEASE_ASSERT(!greaterThan);
            
            return lessThan;
        }
        
        return greaterThan;
    }

    template<typename Functor>
    void mergeConstantsImpl(const Relationship& other, const Functor& functor) const
    {
        ASSERT(m_left == other.m_left);

        // Only deal with constant right.
        if (!m_right->isInt32Constant() || !other.m_right->isInt32Constant())
            return;

        // What follows is a fairly conservative merge. We could tune this phase to come up with
        // all possible inequalities between variables and constants, but we focus mainly on cheap
        // cases for now.

        // Here are some of the arrangements we can merge usefully assuming @c < @d:
        //
        //     @x == @c || @x == @d   =>   @x >= c && @x <= @d
        //     @x >= @c || @x <= @d   =>   TOP
        //     @x == @c || @x != @d   =>   @x != @d

        int thisRight = m_right->asInt32();
        int otherRight = other.m_right->asInt32();

        // Ignore funny business.
        if (sumOverflows<int>(thisRight, m_offset))
            return;
        if (sumOverflows<int>(otherRight, other.m_offset))
            return;

        int thisEffectiveRight = thisRight + m_offset;
        int otherEffectiveRight = otherRight + other.m_offset;

        auto makeUpper = [&] (int64_t upper) {
            if (upper <= thisRight) {
                // We want m_right + offset to be equal to upper. Hence we want offset to cancel
                // with m_right. But there's more to it, since we want +1 to turn the LessThan into
                // a LessThanOrEqual, and we want to make sure we don't end up with non-general
                // offsets. 
                int offset = static_cast<int>(std::max(
                    static_cast<int64_t>(1) + upper - static_cast<int64_t>(thisRight),
                    static_cast<int64_t>(-1)));
                functor(Relationship(m_left, m_right, LessThan, offset));
            }
            if (upper <= otherRight) {
                int offset = static_cast<int>(std::max(
                    static_cast<int64_t>(1) + upper - static_cast<int64_t>(otherRight),
                    static_cast<int64_t>(-1)));
                functor(Relationship(m_left, other.m_right, LessThan, offset));
            }
        };
        auto makeLower = [&] (int64_t lower) {
            if (lower >= thisRight) {
                // We want m_right + offset to be equal to lower. Hence we want offset to cancel with
                // m_right. But there's more to it, since we want -1 to turn the GreaterThan into a
                // GreaterThanOrEqual, and we want to make sure we don't end up with non-general
                // offsets.
                int offset = static_cast<int>(std::min(
                    static_cast<int64_t>(-1) + lower - static_cast<int64_t>(thisRight),
                    static_cast<int64_t>(1)));
                functor(Relationship(m_left, m_right, GreaterThan, offset));
            }
            if (lower >= otherRight) {
                int offset = static_cast<int>(std::min(
                    static_cast<int64_t>(-1) + lower - static_cast<int64_t>(otherRight),
                    static_cast<int64_t>(1)));
                functor(Relationship(m_left, other.m_right, GreaterThan, offset));
            }
        };

        switch (m_kind) {
        case Equal: {
            switch (other.m_kind) {
            case Equal: {
                if (thisEffectiveRight == otherEffectiveRight) {
                    // This probably won't arise often. We can keep whichever relationship is general.
                    if (isGeneralOffset(m_offset))
                        functor(*this);
                    if (isGeneralOffset(other.m_offset))
                        functor(other);
                    return;
                }

                // What follows is the only case where a merge will create more rules than what it
                // started with. This is fine for convergence because the LessThan/GreaterThan
                // rules that this creates are general (i.e. have small offsets) and they never
                // spawn more rules upon subsequent merging.

                makeUpper(std::max(thisEffectiveRight, otherEffectiveRight));
                makeLower(std::min(thisEffectiveRight, otherEffectiveRight));
                return;
            }

            case LessThan: {
                // Either the LessThan condition subsumes the equality, or the LessThan condition
                // and equality merge together to create a looser LessThan condition.

                // This is @x == thisEffectiveRight
                // Other is: @x < otherEffectiveRight

                // We want to create @x <= upper. Figure out the value of upper.
                makeUpper(std::max(
                    static_cast<int64_t>(thisEffectiveRight),
                    static_cast<int64_t>(otherEffectiveRight) - 1));
                return;
            }

            case GreaterThan: {
                // Opposite of the LessThan case, above.

                // This is: @x == thisEffectiveRight
                // Other is: @x > otherEffectiveRight

                makeLower(std::min(
                    static_cast<int64_t>(thisEffectiveRight),
                    static_cast<int64_t>(otherEffectiveRight) + 1));
                return;
            }

            case NotEqual: {
                // We keep the NotEqual so long as it doesn't contradict our Equal.
                if (otherEffectiveRight == thisEffectiveRight)
                    return;

                // But, we only keep the NotEqual if it is general. This simplifies reasoning about
                // convergence: merging never introduces a new rule unless that rule is general.
                if (!isGeneralOffset(other.m_offset))
                    return;
                
                functor(other);
                return;
            } }

            RELEASE_ASSERT_NOT_REACHED();
            return;
        }

        case LessThan: {
            switch (other.m_kind) {
            case Equal: {
                other.mergeConstantsImpl(*this, functor);
                return;
            }

            case LessThan: {
                makeUpper(std::max(
                    static_cast<int64_t>(thisEffectiveRight) - 1,
                    static_cast<int64_t>(otherEffectiveRight) - 1));
                return;
            }

            case GreaterThan: {
                // We have a claim that @x > @c || @x < @d. If @d > @c, this is the tautology. If
                // @d <= @c, it's sort of uninteresting. Just ignore this.
                return;
            }

            case NotEqual: {
                // We have a claim that @x < @c || @x != @d. This isn't interesting.
                return;
            } }
            
            RELEASE_ASSERT_NOT_REACHED();
            return;
        }

        case GreaterThan: {
            switch (other.m_kind) {
            case Equal: {
                other.mergeConstantsImpl(*this, functor);
                return;
            }

            case LessThan: {
                // Not interesting, see above.
                return;
            }

            case GreaterThan: {
                makeLower(std::min(
                    static_cast<int64_t>(thisEffectiveRight) + 1,
                    static_cast<int64_t>(otherEffectiveRight) + 1));
                return;
            }

            case NotEqual: {
                // Not interesting, see above.
                return;
            } }

            RELEASE_ASSERT_NOT_REACHED();
            return;
        }

        case NotEqual: {
            if (other.m_kind == Equal)
                other.mergeConstantsImpl(*this, functor);
            return;
        } }

        RELEASE_ASSERT_NOT_REACHED();
    }
    
    NodeFlowProjection m_left;
    NodeFlowProjection m_right;
    Kind m_kind;
    int m_offset; // This offset can be arbitrarily large.
};

typedef HashMap<NodeFlowProjection, Vector<Relationship>> RelationshipMap;

class IntegerRangeOptimizationPhase : public Phase {
public:
    IntegerRangeOptimizationPhase(Graph& graph)
        : Phase(graph, "integer range optimization")
        , m_zero(nullptr)
        , m_relationshipsAtHead(graph)
        , m_insertionSet(graph)
    {
    }
    
    bool run()
    {
        ASSERT(m_graph.m_form == SSA);
        
        // Before we do anything, make sure that we have a zero constant at the top.
        for (Node* node : *m_graph.block(0)) {
            if (node->isInt32Constant() && !node->asInt32()) {
                m_zero = node;
                break;
            }
        }
        if (!m_zero) {
            m_zero = m_insertionSet.insertConstant(0, m_graph.block(0)->at(0)->origin, jsNumber(0));
            m_insertionSet.execute(m_graph.block(0));
        }
        
        if (DFGIntegerRangeOptimizationPhaseInternal::verbose) {
            dataLog("Graph before integer range optimization:\n");
            m_graph.dump();
        }
        
        // This performs a fixpoint over the blocks in reverse post-order. Logically, we
        // maintain a list of relationships at each point in the program. The list should be
        // read as an intersection. For example if we have {rel1, rel2, ..., relN}, you should
        // read this as:
        //
        //     TOP && rel1 && rel2 && ... && relN
        //
        // This allows us to express things like:
        //
        //     @a > @b - 42 && @a < @b + 25
        //
        // But not things like:
        //
        //     @a < @b - 42 || @a > @b + 25
        //
        // We merge two lists by merging each relationship in one list with each relationship
        // in the other list. Merging two relationships will yield a relationship list; as with
        // all such lists it is an intersection. Merging relationships over different variables
        // always yields the empty list (i.e. TOP). This merge style is sound because if we
        // have:
        //
        //     (A && B && C) || (D && E && F)
        //
        // Then a valid merge is just one that will return true if A, B, C are all true, or
        // that will return true if D, E, F are all true. Our merge style essentially does:
        //
        //     (A || D) && (A || E) && (A || F) && (B || D) && (B || E) && (B || F) &&
        //         (C || D) && (C || E) && (C || F)
        //
        // If A && B && C is true, then this returns true. If D && E && F is true, this also
        // returns true.
        //
        // While this appears at first like a kind of expression explosion, in practice it
        // isn't. The code that handles this knows that the merge of two relationships over
        // different variables is TOP (i.e. the empty list). For example if A above is @a < @b
        // and B above is @c > @d, where @a, @b, @c, and @d are different nodes, the merge will
        // yield nothing. In fact, the merge algorithm will skip such merges entirely because
        // the relationship lists are actually keyed by node.
        //
        // Note that it's always safe to drop any of relationship from the relationship list.
        // This merely increases the likelihood of the "expression" yielding true, i.e. being
        // closer to TOP. Optimizations are only performed if we can establish that the
        // expression implied by the relationship list is false for all of those cases where
        // some check would have failed.
        //
        // There is no notion of BOTTOM because we treat blocks that haven't had their
        // state-at-head set as a special case: we just transfer all live relationships to such
        // a block. After the head of a block is set, we perform the merging as above. In all
        // other places where we would ordinarily need BOTTOM, we approximate it by having some
        // non-BOTTOM relationship.
        
        BlockList postOrder = m_graph.blocksInPostOrder();

        // This loop analyzes the IR to give us m_relationshipsAtHead for each block. This
        // may reexecute blocks many times, but it is guaranteed to converge. The state of
        // the relationshipsAtHead over any pair of nodes converge monotonically towards the
        // TOP relationship (i.e. no relationships in the relationship list). The merge rule
        // when between the current relationshipsAtHead and the relationships being propagated
        // from a predecessor ensures monotonicity by converting disagreements into one of a
        // small set of "general" relationships. There are 12 such relationships, plus TOP. See
        // the comment above Relationship::merge() for details.
        bool changed = true;
        while (changed) {
            ++m_iterations;
            if (m_iterations >= giveUpThreshold) {
                // This case is not necessarily wrong but it can be a sign that this phase
                // does not converge. The value giveUpThreshold was chosen emperically based on
                // current tests and real world JS.
                // If you hit this case for a legitimate reason, update the giveUpThreshold
                // to the smallest values that converges.

                // Do not risk holding the thread for too long since this phase is really slow.
                return false;
            }

            changed = false;
            for (unsigned postOrderIndex = postOrder.size(); postOrderIndex--;) {
                BasicBlock* block = postOrder[postOrderIndex];
                DFG_ASSERT(
                    m_graph, nullptr,
                    block == m_graph.block(0) || m_seenBlocks.contains(block));
            
                m_relationships = m_relationshipsAtHead[block];
            
                for (auto* node : *block) {
                    if (DFGIntegerRangeOptimizationPhaseInternal::verbose)
                        dataLog("Analysis: at ", node, ": ", listDump(sortedRelationships()), "\n");
                    executeNode(node);
                }
                
                // Now comes perhaps the most important piece of cleverness: if we Branch, and
                // the predicate involves some relation over integers, we propagate different
                // information to the taken and notTaken paths. This handles:
                // - Branch on int32.
                // - Branch on LogicalNot on int32.
                // - Branch on compare on int32's.
                // - Branch on LogicalNot of compare on int32's.
                Node* terminal = block->terminal();
                bool alreadyMerged = false;
                if (terminal->op() == Branch) {
                    Relationship relationshipForTrue;
                    BranchData* branchData = terminal->branchData();
                    
                    bool invert = false;
                    if (terminal->child1()->op() == LogicalNot) {
                        terminal = terminal->child1().node();
                        invert = true;
                    }
                    
                    if (terminal->child1().useKind() == Int32Use) {
                        relationshipForTrue = Relationship::safeCreate(
                            terminal->child1().node(), m_zero, Relationship::NotEqual, 0);
                    } else {
                        // FIXME: Handle CompareBelow and CompareBelowEq.
                        Node* compare = terminal->child1().node();
                        switch (compare->op()) {
                        case CompareEq:
                        case CompareStrictEq:
                        case CompareLess:
                        case CompareLessEq:
                        case CompareGreater:
                        case CompareGreaterEq: {
                            if (!compare->isBinaryUseKind(Int32Use))
                                break;
                    
                            switch (compare->op()) {
                            case CompareEq:
                            case CompareStrictEq:
                                relationshipForTrue = Relationship::safeCreate(
                                    compare->child1().node(), compare->child2().node(),
                                    Relationship::Equal, 0);
                                break;
                            case CompareLess:
                                relationshipForTrue = Relationship::safeCreate(
                                    compare->child1().node(), compare->child2().node(),
                                    Relationship::LessThan, 0);
                                break;
                            case CompareLessEq:
                                relationshipForTrue = Relationship::safeCreate(
                                    compare->child1().node(), compare->child2().node(),
                                    Relationship::LessThan, 1);
                                break;
                            case CompareGreater:
                                relationshipForTrue = Relationship::safeCreate(
                                    compare->child1().node(), compare->child2().node(),
                                    Relationship::GreaterThan, 0);
                                break;
                            case CompareGreaterEq:
                                relationshipForTrue = Relationship::safeCreate(
                                    compare->child1().node(), compare->child2().node(),
                                    Relationship::GreaterThan, -1);
                                break;
                            default:
                                DFG_CRASH(m_graph, compare, "Invalid comparison node type");
                                break;
                            }
                            break;
                        }
                    
                        default:
                            break;
                        }
                    }
                    
                    if (invert)
                        relationshipForTrue = relationshipForTrue.inverse();
                    
                    if (relationshipForTrue) {
                        RelationshipMap forTrue = m_relationships;
                        RelationshipMap forFalse = m_relationships;
                        
                        if (DFGIntegerRangeOptimizationPhaseInternal::verbose)
                            dataLog("Dealing with true:\n");
                        setRelationship(forTrue, relationshipForTrue);
                        if (Relationship relationshipForFalse = relationshipForTrue.inverse()) {
                            if (DFGIntegerRangeOptimizationPhaseInternal::verbose)
                                dataLog("Dealing with false:\n");
                            setRelationship(forFalse, relationshipForFalse);
                        }
                        
                        changed |= mergeTo(forTrue, branchData->taken.block);
                        changed |= mergeTo(forFalse, branchData->notTaken.block);
                        alreadyMerged = true;
                    }
                }

                if (!alreadyMerged) {
                    for (BasicBlock* successor : block->successors())
                        changed |= mergeTo(m_relationships, successor);
                }
            }
        }
        
        // Now we transform the code based on the results computed in the previous loop.
        changed = false;
        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
            m_relationships = m_relationshipsAtHead[block];
            for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
                Node* node = block->at(nodeIndex);
                if (DFGIntegerRangeOptimizationPhaseInternal::verbose)
                    dataLog("Transformation: at ", node, ": ", listDump(sortedRelationships()), "\n");
                
                // This ends up being pretty awkward to write because we need to decide if we
                // optimize by using the relationships before the operation, but we need to
                // call executeNode() before we optimize.
                switch (node->op()) {
                case ArithAbs: {
                    if (node->child1().useKind() != Int32Use)
                        break;

                    auto iter = m_relationships.find(node->child1().node());
                    if (iter == m_relationships.end())
                        break;

                    int minValue = std::numeric_limits<int>::min();
                    int maxValue = std::numeric_limits<int>::max();
                    for (Relationship relationship : iter->value) {
                        minValue = std::max(minValue, relationship.minValueOfLeft());
                        maxValue = std::min(maxValue, relationship.maxValueOfLeft());
                    }

                    executeNode(block->at(nodeIndex));

                    if (minValue >= 0) {
                        node->convertToIdentityOn(node->child1().node());
                        changed = true;
                        break;
                    }
                    bool absIsUnchecked = !shouldCheckOverflow(node->arithMode());
                    if (maxValue < 0 || (absIsUnchecked && maxValue <= 0)) {
                        node->convertToArithNegate();
                        if (absIsUnchecked || minValue > std::numeric_limits<int>::min())
                            node->setArithMode(Arith::Unchecked);
                        changed = true;
                        break;
                    }
                    if (minValue > std::numeric_limits<int>::min()) {
                        node->setArithMode(Arith::Unchecked);
                        changed = true;
                        break;
                    }

                    break;
                }
                case ArithAdd: {
                    if (!node->isBinaryUseKind(Int32Use))
                        break;
                    if (node->arithMode() != Arith::CheckOverflow)
                        break;
                    if (!node->child2()->isInt32Constant())
                        break;
                    
                    auto iter = m_relationships.find(node->child1().node());
                    if (iter == m_relationships.end())
                        break;
                    
                    int minValue = std::numeric_limits<int>::min();
                    int maxValue = std::numeric_limits<int>::max();
                    for (Relationship relationship : iter->value) {
                        minValue = std::max(minValue, relationship.minValueOfLeft());
                        maxValue = std::min(maxValue, relationship.maxValueOfLeft());
                    }

                    if (DFGIntegerRangeOptimizationPhaseInternal::verbose)
                        dataLog("    minValue = ", minValue, ", maxValue = ", maxValue, "\n");
                    
                    if (sumOverflows<int>(minValue, node->child2()->asInt32()) ||
                        sumOverflows<int>(maxValue, node->child2()->asInt32()))
                        break;

                    if (DFGIntegerRangeOptimizationPhaseInternal::verbose)
                        dataLog("    It's in bounds.\n");
                    
                    executeNode(block->at(nodeIndex));
                    node->setArithMode(Arith::Unchecked);
                    changed = true;
                    break;
                }
                    
                case CheckInBounds: {
                    auto iter = m_relationships.find(node->child1().node());
                    if (iter == m_relationships.end())
                        break;
                    
                    bool nonNegative = false;
                    bool lessThanLength = false;
                    for (Relationship relationship : iter->value) {
                        if (relationship.minValueOfLeft() >= 0)
                            nonNegative = true;
                        
                        if (relationship.right() == node->child2().node()) {
                            if (relationship.kind() == Relationship::Equal
                                && relationship.offset() < 0)
                                lessThanLength = true;
                            
                            if (relationship.kind() == Relationship::LessThan
                                && relationship.offset() <= 0)
                                lessThanLength = true;
                        }
                    }

                    if (DFGIntegerRangeOptimizationPhaseInternal::verbose)
                        dataLogLn("CheckInBounds ", node, " has: ", nonNegative, " ", lessThanLength);
                    
                    if (nonNegative && lessThanLength) {
                        executeNode(block->at(nodeIndex));
                        if (UNLIKELY(Options::validateBoundsCheckElimination()) && node->op() == CheckInBounds)
                            m_insertionSet.insertNode(nodeIndex, SpecNone, AssertInBounds, node->origin, node->child1(), node->child2());
                        // We just need to make sure we are a value-producing node.
                        node->convertToIdentityOn(node->child1().node());
                        changed = true;
                    }
                    break;
                }

                case EnumeratorGetByVal:
                case GetByVal: {
                    if (node->arrayMode().type() != Array::Undecided)
                        break;

                    auto iter = m_relationships.find(m_graph.varArgChild(node, 1).node());
                    if (iter == m_relationships.end())
                        break;

                    int minValue = std::numeric_limits<int>::min();
                    for (Relationship relationship : iter->value)
                        minValue = std::max(minValue, relationship.minValueOfLeft());

                    if (minValue < 0)
                        break;

                    executeNode(block->at(nodeIndex));
                    m_graph.convertToConstant(node, jsUndefined());
                    changed = true;
                    break;
                }

                default:
                    break;
                }
                
                executeNode(block->at(nodeIndex));
            }
        }
        
        return changed;
    }

private:
    void executeNode(Node* node)
    {
        switch (node->op()) {
        // FIXME: Teach this about EnumeratorNextExtractIndex.
        case CheckInBounds: {
            setRelationship(Relationship::safeCreate(node->child1().node(), node->child2().node(), Relationship::LessThan));
            setRelationship(Relationship::safeCreate(node->child1().node(), m_zero, Relationship::GreaterThan, -1));
            break;
        }

        case ArithAbs: {
            if (node->child1().useKind() != Int32Use)
                break;

            // If ArithAbs cares about overflow, then INT32_MIN input will cause OSR exit.
            // Thus we can safely say `x >= 0`.
            if (shouldCheckOverflow(node->arithMode())) {
                setRelationship(Relationship(node, m_zero, Relationship::GreaterThan, -1));
                break;
            }

            // If ArithAbs does not care about overflow, it can return INT32_MIN if the input is INT32_MIN.
            // If minValue is not INT32_MIN, we can still say it is `x >= 0`.
            int minValue = std::numeric_limits<int>::min();
            auto iter = m_relationships.find(node->child1().node());
            if (iter != m_relationships.end()) {
                for (Relationship relationship : iter->value)
                    minValue = std::max(minValue, relationship.minValueOfLeft());
            }

            if (minValue > std::numeric_limits<int>::min())
                setRelationship(Relationship(node, m_zero, Relationship::GreaterThan, -1));
            break;
        }
            
        case ArithAdd: {
            // We're only interested in int32 additions and we currently only know how to
            // handle the non-wrapping ones.
            if (!node->isBinaryUseKind(Int32Use))
                break;
            
            // FIXME: We could handle the unchecked arithmetic case. We just do it don't right
            // now.
            if (node->arithMode() != Arith::CheckOverflow)
                break;
            
            // Handle add: @value + constant.
            if (!node->child2()->isInt32Constant())
                break;
            
            int offset = node->child2()->asInt32();
            
            // We add a relationship for @add == @value + constant, and then we copy the
            // relationships for @value. This gives us a one-deep view of @value's existing
            // relationships, which matches the one-deep search in setRelationship().
            
            setRelationship(
                Relationship(node, node->child1().node(), Relationship::Equal, offset));
            
            auto iter = m_relationships.find(node->child1().node());
            if (iter != m_relationships.end()) {
                Vector<Relationship> toAdd;
                for (Relationship relationship : iter->value) {
                    // We have:
                    //     add: ArithAdd(@x, C)
                    //     @x op @y + D
                    //
                    // The following certainly holds:
                    //     @x == @add - C
                    //
                    // Which allows us to substitute:
                    //     @add - C op @y + D
                    //
                    // And then carry the C over:
                    //     @add op @y + D + C
                    
                    Relationship newRelationship = relationship;
                    ASSERT(newRelationship.left() == node->child1().node());
                    
                    if (newRelationship.right() == node)
                        continue;
                    newRelationship.setLeft(node);
                    if (newRelationship.addToOffset(offset))
                        toAdd.append(newRelationship);
                }
                for (Relationship relationship : toAdd)
                    setRelationship(relationship, 0);
            }
            
            // Now we want to establish that both the input and the output of the addition are
            // within a particular range of integers.
            
            if (offset > 0) {
                // If we have "add: @value + 1" then we know that @value <= max - 1, i.e. that
                // @value < max.
                if (!sumOverflows<int>(std::numeric_limits<int>::max(), -offset, 1)) {
                    setRelationship(
                        Relationship::safeCreate(
                            node->child1().node(), m_zero, Relationship::LessThan,
                            std::numeric_limits<int>::max() - offset + 1),
                        0);
                }
                    
                // If we have "add: @value + 1" then we know that @add >= min + 1, i.e. that
                // @add > min.
                if (!sumOverflows<int>(std::numeric_limits<int>::min(), offset, -1)) {
                    setRelationship(
                        Relationship(
                            node, m_zero, Relationship::GreaterThan,
                            std::numeric_limits<int>::min() + offset - 1),
                        0);
                }
            }
            
            if (offset < 0 && offset != std::numeric_limits<int>::min()) {
                // If we have "add: @value - 1" then we know that @value >= min + 1, i.e. that
                // @value > min.
                if (!sumOverflows<int>(std::numeric_limits<int>::min(), offset, -1)) {
                    setRelationship(
                        Relationship::safeCreate(
                            node->child1().node(), m_zero, Relationship::GreaterThan,
                            std::numeric_limits<int>::min() + offset - 1),
                        0);
                }
                
                // If we have "add: @value + 1" then we know that @add <= max - 1, i.e. that
                // @add < max.
                if (!sumOverflows<int>(std::numeric_limits<int>::max(), -offset, 1)) {
                    setRelationship(
                        Relationship(
                            node, m_zero, Relationship::LessThan,
                            std::numeric_limits<int>::max() - offset + 1),
                        0);
                }
            }
            break;
        }
            
        case GetArrayLength:
        case GetVectorLength: {
            setRelationship(Relationship(node, m_zero, Relationship::GreaterThan, -1));
            break;
        }
            
        case Upsilon: {
            auto shadowNode = NodeFlowProjection(node->phi(), NodeFlowProjection::Shadow);
            // We must first remove all relationships involving the shadow node, because setEquivalence does not overwrite them.
            // Overwriting is only required here because the shadowNodes are not in SSA form (can be written to by several Upsilons).
            // Another way to think of it, is that we are maintaining the invariant that relationshipMaps are pruned by liveness.
            kill(shadowNode);
            setEquivalence(node->child1().node(), shadowNode);
            break;
        }
            
        case Phi: {
            setEquivalence(
                NodeFlowProjection(node, NodeFlowProjection::Shadow),
                node);
            break;
        }
            
        default:
            break;
        }
    }

    void kill(NodeFlowProjection node)
    {
        m_relationships.remove(node);

        for (auto& relationships : m_relationships.values()) {
            unsigned i = 0, j = 0;
            while (i < relationships.size()) {
                const Relationship& rel = relationships[i++];
                ASSERT(rel.left() != node);
                if (rel.right() != node)
                    relationships[j++] = rel;
            }
            relationships.shrink(j);
        }
    }
    
    void setEquivalence(NodeFlowProjection oldNode, NodeFlowProjection newNode)
    {
        setRelationship(Relationship::safeCreate(oldNode, newNode, Relationship::Equal, 0));
        
        auto iter = m_relationships.find(oldNode);
        if (iter != m_relationships.end()) {
            Vector<Relationship> toAdd;
            for (Relationship relationship : iter->value) {
                Relationship newRelationship = relationship;
                // Avoid creating any kind of self-relationship.
                if (newNode.node() == newRelationship.right().node())
                    continue;
                newRelationship.setLeft(newNode);
                toAdd.append(newRelationship);
            }
            for (Relationship relationship : toAdd)
                setRelationship(relationship);
        }
    }
            
    void setRelationship(Relationship relationship, unsigned timeToLive = 1)
    {
        setRelationship(m_relationships, relationship, timeToLive);
    }
    
    void setRelationship(
        RelationshipMap& relationshipMap, Relationship relationship, unsigned timeToLive = 1)
    {
        setOneSide(relationshipMap, relationship, timeToLive);
        setOneSide(relationshipMap, relationship.flipped(), timeToLive);
    }
    
    void setOneSide(
        RelationshipMap& relationshipMap, Relationship relationship, unsigned timeToLive = 1)
    {
        if (!relationship)
            return;
        
        if (DFGIntegerRangeOptimizationPhaseInternal::verbose)
            dataLogLn("    Setting: ", relationship, " (ttl = ", timeToLive, ")");

        auto result = relationshipMap.add(
            relationship.left(), Vector<Relationship>());
        Vector<Relationship>& relationships = result.iterator->value;

        if (relationship.right()->isInt32Constant()) {
            // We want to do some work to refine relationships over constants. This is necessary because
            // when we introduce a constant into the IR, we don't automatically create relationships
            // between that constant and the other constants. That means that when we do introduce
            // relationships between a non-constant and a constant, we need to check the other
            // relationships between that non-constant and other constants to see if we can make some
            // refinements. Possible constant statement filtrations:
            //
            // - @x == @c and @x != @d, where @c > @d:
            //       @x == @c and @x > @d
            //
            // but actually we are more aggressive:
            //
            // - @x == @c and @x op @d where @c == @d + k
            //       @x == @c and @x == @d + k
            //
            // And this is also possible:
            //
            // - @x > @c and @x != @d where @c == @d + k and k >= 0
            //
            //       @x > @c and @x > @d + k
            //
            // So, here's what we should do depending on the kind of relationship we're introducing:
            //
            // Equal constant: Find all LessThan, NotEqual, and GreaterThan constant operations and refine
            //     them to be Equal constant. Don't worry about contradictions.
            //
            // LessThan, GreaterThan constant: See if there is any Equal constant, and if so, refine to
            //     that. Otherwise, find all NotEqual constant operations and refine them to be LessThan or
            //     GreaterThan constant if possible.
            //
            // NotEqual constant: See if there is any Equal constant, and if so, refine to that. Otherwise,
            //     see if there is any LessThan or GreaterThan constant operation, and if so, attempt to
            //     refine to that.
            //
            // Seems that the key thing is to have a filterConstant() operation that returns a refined
            // version of *this based on other. The code here accomplishes this by using the vagueness
            // index (Relationship::vagueness()) to first find less vague relationships and refine this one
            // using them, and then find more vague relationships and refine those to this.

            if (relationship.vagueness() != Relationship::minVagueness) {
                // We're not minimally vague (maximally specific), so try to refine ourselves based on what
                // we already know.
                for (Relationship& otherRelationship : relationships) {
                    if (otherRelationship.vagueness() < relationship.vagueness()
                        && otherRelationship.right()->isInt32Constant()) {
                        Relationship newRelationship = relationship.filterConstant(otherRelationship);
                        if (DFGIntegerRangeOptimizationPhaseInternal::verbose && newRelationship != relationship)
                            dataLog("      Refined to: ", newRelationship, " based on ", otherRelationship, "\n");
                        relationship = newRelationship;
                    }
                }
            }

            if (relationship.vagueness() != Relationship::maxVagueness) {
                // We're not maximally value (minimally specific), so try to refine other relationships
                // based on this one.
                for (Relationship& otherRelationship : relationships) {
                    if (otherRelationship.vagueness() > relationship.vagueness()
                        && otherRelationship.right()->isInt32Constant()) {
                        Relationship newRelationship = otherRelationship.filterConstant(relationship);
                        if (DFGIntegerRangeOptimizationPhaseInternal::verbose && newRelationship != otherRelationship)
                            dataLog("      Refined ", otherRelationship, " to: ", newRelationship, "\n");
                        otherRelationship = newRelationship;
                    }
                }
            }
        }

        Vector<Relationship> toAdd;
        bool found = false;
        for (Relationship& otherRelationship : relationships) {
            if (otherRelationship.sameNodesAs(relationship)) {
                if (Relationship filtered = otherRelationship.filter(relationship)) {
                    ASSERT(filtered.left() == relationship.left());
                    otherRelationship = filtered;
                    if (DFGIntegerRangeOptimizationPhaseInternal::verbose)
                        dataLogLn("      filtered: ", filtered);
                    found = true;
                }
            }

            // FIXME: Also add filtration over statements about constants. For example, if we have
            // @x == @c and @x != @d, where @d > @c, then we want to turn @x != @d into @x < @d.
            
            if (timeToLive && otherRelationship.kind() == Relationship::Equal) {
                if (DFGIntegerRangeOptimizationPhaseInternal::verbose)
                    dataLog("      Considering (lhs): ", otherRelationship, "\n");
                
                // We have:
                //     @a op @b + C
                //     @a == @c + D
                //
                // This implies:
                //     @c + D op @b + C
                //     @c op @b + C - D
                //
                // Where: @a == relationship.left(), @b == relationship.right(),
                // @a == otherRelationship.left(), @c == otherRelationship.right().
                
                if (otherRelationship.offset() != std::numeric_limits<int>::min()) {
                    Relationship newRelationship = relationship;
                    if (newRelationship.right() != otherRelationship.right()) {
                        newRelationship.setLeft(otherRelationship.right());
                        if (newRelationship.addToOffset(-otherRelationship.offset()))
                            toAdd.append(newRelationship);
                    }
                }
            }
        }

        if (timeToLive && relationship.kind() != Relationship::Equal) {
            for (Relationship& possibleEquality : relationshipMap.get(relationship.right())) {
                if (possibleEquality.kind() != Relationship::Equal
                    || possibleEquality.offset() == std::numeric_limits<int>::min()
                    || possibleEquality.right() == relationship.left())
                    continue;
                if (DFGIntegerRangeOptimizationPhaseInternal::verbose)
                    dataLog("      Considering (rhs): ", possibleEquality, "\n");

                // We have:
                //     @a op @b + C
                //     @b == @c + D
                //
                // This implies:
                //     @a op @c + (C + D)
                //
                // Where: @a == relationship.left(), @b == relationship.right()

                Relationship newRelationship = relationship;
                newRelationship.setRight(possibleEquality.right());
                if (newRelationship.addToOffset(possibleEquality.offset()))
                    toAdd.append(newRelationship);
            }
        }

        if (!found)
            relationships.append(relationship);
        
        for (Relationship anotherRelationship : toAdd) {
            ASSERT(timeToLive);
            setOneSide(relationshipMap, anotherRelationship, timeToLive - 1);
        }
    }
    
    bool mergeTo(RelationshipMap& relationshipMap, BasicBlock* target)
    {
        if (DFGIntegerRangeOptimizationPhaseInternal::verbose) {
            dataLog("Merging to ", pointerDump(target), ":\n");
            dataLog("    Incoming: ", listDump(sortedRelationships(relationshipMap)), "\n");
            dataLog("    At head: ", listDump(sortedRelationships(m_relationshipsAtHead[target])), "\n");
        }
        
        if (m_seenBlocks.add(target)) {
            // This is a new block. We copy subject to liveness pruning.
            auto isLive = [&] (NodeFlowProjection node) {
                if (node == m_zero)
                    return true;
                return target->ssa->liveAtHead.contains(node);
            };
            
            for (auto& entry : relationshipMap) {
                if (!isLive(entry.key))
                    continue;
                
                Vector<Relationship> values;
                for (Relationship relationship : entry.value) {
                    ASSERT(relationship.left() == entry.key);
                    if (isLive(relationship.right())) {
                        if (DFGIntegerRangeOptimizationPhaseInternal::verbose)
                            dataLog("  Propagating ", relationship, "\n");
                        values.append(relationship);
                    }
                }
                
                std::sort(values.begin(), values.end());
                m_relationshipsAtHead[target].add(entry.key, values);
            }
            return true;
        }
        
        // Merge by intersecting. We have no notion of BOTTOM, so we use the omission of
        // relationships for a pair of nodes to mean TOP. The reason why we don't need BOTTOM
        // is (1) we just overapproximate contradictions and (2) a value never having been
        // assigned would only happen if we have not processed the node's predecessor. We
        // shouldn't process blocks until we have processed the block's predecessor because we
        // are using reverse postorder.
        Vector<NodeFlowProjection> toRemove;
        bool changed = false;
        for (auto& entry : m_relationshipsAtHead[target]) {
            auto iter = relationshipMap.find(entry.key);
            if (iter == relationshipMap.end()) {
                toRemove.append(entry.key);
                changed = true;
                continue;
            }

            Vector<Relationship> constantRelationshipsAtHead;
            for (Relationship& relationshipAtHead : entry.value) {
                if (relationshipAtHead.right()->isInt32Constant())
                    constantRelationshipsAtHead.append(relationshipAtHead);
            }

            Vector<Relationship> mergedRelationships;
            for (Relationship targetRelationship : entry.value) {
                for (Relationship sourceRelationship : iter->value) {
                    if (DFGIntegerRangeOptimizationPhaseInternal::verbose)
                        dataLog("  Merging ", targetRelationship, " and ", sourceRelationship, ":\n");
                    targetRelationship.merge(
                        sourceRelationship,
                        [&] (Relationship newRelationship) {
                            if (DFGIntegerRangeOptimizationPhaseInternal::verbose)
                                dataLog("    Got ", newRelationship, "\n");

                            if (newRelationship.right()->isInt32Constant()) {
                                // We can produce a relationship with a constant equivalent to
                                // an existing relationship yet of a different form. For example:
                                //
                                //     @a == @b(42) + 0
                                //     @a == @c(41) + 1
                                //
                                // We do not want to perpetually switch between those two forms,
                                // so we always prefer the one already at head.

                                for (Relationship& existingRelationshipAtHead : constantRelationshipsAtHead) {
                                    if (existingRelationshipAtHead.isEquivalentTo(newRelationship)) {
                                        newRelationship = existingRelationshipAtHead;
                                        break;
                                    }
                                }
                            }
                            
                            // We need to filter() to avoid exponential explosion of identical
                            // relationships. We do this here to avoid making setOneSide() do
                            // more work, since we expect setOneSide() will be called more
                            // frequently. Here's an example. At some point someone might start
                            // with two relationships like @a > @b - C and @a < @b + D. Then
                            // someone does a setRelationship() passing something that turns
                            // both of these into @a == @b. Now we have @a == @b duplicated.
                            // Let's say that this duplicate @a == @b ends up at the head of a
                            // loop. If we didn't have this rule, then the loop would propagate
                            // duplicate @a == @b's onto the existing duplicate @a == @b's.
                            // There would be four pairs of @a == @b, each of which would
                            // create a new @a == @b. Now we'd have four of these duplicates
                            // and the next time around we'd have 8, then 16, etc. We avoid
                            // this here by doing this filtration. That might be a bit of
                            // overkill, since it's probably just the identical duplicate
                            // relationship case we want' to avoid. But, I'll keep this until
                            // we have evidence that this is a performance problem. Remember -
                            // we are already dealing with a list that is pruned down to
                            // relationships with identical left operand. It shouldn't be a
                            // large list.
                            bool found = false;
                            for (Relationship& existingRelationship : mergedRelationships) {
                                if (existingRelationship.sameNodesAs(newRelationship)) {
                                    Relationship filtered =
                                        existingRelationship.filter(newRelationship);
                                    if (filtered) {
                                        existingRelationship = filtered;
                                        found = true;
                                        break;
                                    }
                                }
                            }
                            
                            if (!found)
                                mergedRelationships.append(newRelationship);
                        });
                }
            }
            std::sort(mergedRelationships.begin(), mergedRelationships.end());
            if (entry.value == mergedRelationships)
                continue;
            
            entry.value = mergedRelationships;
            changed = true;
        }
        for (NodeFlowProjection node : toRemove)
            m_relationshipsAtHead[target].remove(node);
        
        return changed;
    }
        
    Vector<Relationship> sortedRelationships(const RelationshipMap& relationships)
    {
        Vector<Relationship> result;
        for (auto& entry : relationships)
            result.appendVector(entry.value);
        std::sort(result.begin(), result.end());
        return result;
    }
    
    Vector<Relationship> sortedRelationships()
    {
        return sortedRelationships(m_relationships);
    }
    
    Node* m_zero;
    RelationshipMap m_relationships;
    BlockSet m_seenBlocks;
    BlockMap<RelationshipMap> m_relationshipsAtHead;
    InsertionSet m_insertionSet;

    unsigned m_iterations { 0 };
};
    
} // anonymous namespace

bool performIntegerRangeOptimization(Graph& graph)
{
    return runPhase<IntegerRangeOptimizationPhase>(graph);
}

} } // namespace JSC::DFG

#endif // ENABLE(DFG_JIT)

