/*
 * Copyright (C) 2015-2019 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 "DFGPredictionPropagationPhase.h"
#include "DFGVariableAccessDataDump.h"
#include "JSCInlines.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())
            return (m_right->asInt32() + m_offset) == (other.m_right->asInt32() + 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:
            // 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)
            
            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));
                        // We just need to make sure we are a value-producing node.
                        node->convertToIdentityOn(node->child1().node());
                        changed = true;
                    }
                    break;
                }

                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()) {
        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;
            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: {
            setEquivalence(
                node->child1().node(),
                NodeFlowProjection(node->phi(), NodeFlowProjection::Shadow));
            break;
        }
            
        case Phi: {
            setEquivalence(
                NodeFlowProjection(node, NodeFlowProjection::Shadow),
                node);
            break;
        }
            
        default:
            break;
        }
    }
    
    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)
            dataLog("    Setting: ", relationship, " (ttl = ", timeToLive, ")\n");

        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;
                    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)

