//===-- PredicateSimplifier.cpp - Path Sensitive Simplifier ---------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by Nick Lewycky and is distributed under the
// University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Path-sensitive optimizer. In a branch where x == y, replace uses of
// x with y. Permits further optimization, such as the elimination of
// the unreachable call:
//
// void test(int *p, int *q)
// {
//   if (p != q)
//     return;
// 
//   if (*p != *q)
//     foo(); // unreachable
// }
//
//===----------------------------------------------------------------------===//
//
// The InequalityGraph focusses on four properties; equals, not equals,
// less-than and less-than-or-equals-to. The greater-than forms are also held
// just to allow walking from a lesser node to a greater one. These properties
// are stored in a lattice; LE can become LT or EQ, NE can become LT or GT.
//
// These relationships define a graph between values of the same type. Each
// Value is stored in a map table that retrieves the associated Node. This
// is how EQ relationships are stored; the map contains pointers from equal
// Value to the same node. The node contains a most canonical Value* form
// and the list of known relationships with other nodes.
//
// If two nodes are known to be inequal, then they will contain pointers to
// each other with an "NE" relationship. If node getNode(%x) is less than
// getNode(%y), then the %x node will contain <%y, GT> and %y will contain
// <%x, LT>. This allows us to tie nodes together into a graph like this:
//
//   %a < %b < %c < %d
//
// with four nodes representing the properties. The InequalityGraph provides
// querying with "isRelatedBy" and mutators "addEquality" and "addInequality".
// To find a relationship, we start with one of the nodes any binary search
// through its list to find where the relationships with the second node start.
// Then we iterate through those to find the first relationship that dominates
// our context node.
//
// To create these properties, we wait until a branch or switch instruction
// implies that a particular value is true (or false). The VRPSolver is
// responsible for analyzing the variable and seeing what new inferences
// can be made from each property. For example:
//
//   %P = icmp ne i32* %ptr, null
//   %a = and i1 %P, %Q
//   br i1 %a label %cond_true, label %cond_false
//
// For the true branch, the VRPSolver will start with %a EQ true and look at
// the definition of %a and find that it can infer that %P and %Q are both
// true. From %P being true, it can infer that %ptr NE null. For the false
// branch it can't infer anything from the "and" instruction.
//
// Besides branches, we can also infer properties from instruction that may
// have undefined behaviour in certain cases. For example, the dividend of
// a division may never be zero. After the division instruction, we may assume
// that the dividend is not equal to zero.
//
//===----------------------------------------------------------------------===//
//
// The ValueRanges class stores the known integer bounds of a Value. When we
// encounter i8 %a u< %b, the ValueRanges stores that %a = [1, 255] and
// %b = [0, 254].
//
// It never stores an empty range, because that means that the code is
// unreachable. It never stores a single-element range since that's an equality
// relationship and better stored in the InequalityGraph, nor an empty range
// since that is better stored in UnreachableBlocks.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "predsimplify"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Instructions.h"
#include "llvm/Pass.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/SetOperations.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ConstantRange.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/InstVisitor.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Transforms/Utils/Local.h"
#include <algorithm>
#include <deque>
#include <sstream>
#include <stack>
using namespace llvm;

STATISTIC(NumVarsReplaced, "Number of argument substitutions");
STATISTIC(NumInstruction , "Number of instructions removed");
STATISTIC(NumSimple      , "Number of simple replacements");
STATISTIC(NumBlocks      , "Number of blocks marked unreachable");
STATISTIC(NumSnuggle     , "Number of comparisons snuggled");

namespace {
  class DomTreeDFS {
  public:
    class Node {
      friend class DomTreeDFS;
    public:
      typedef std::vector<Node *>::iterator       iterator;
      typedef std::vector<Node *>::const_iterator const_iterator;

      unsigned getDFSNumIn()  const { return DFSin;  }
      unsigned getDFSNumOut() const { return DFSout; }

      BasicBlock *getBlock() const { return BB; }

      iterator begin() { return Children.begin(); }
      iterator end()   { return Children.end();   }

      const_iterator begin() const { return Children.begin(); }
      const_iterator end()   const { return Children.end();   }

      bool dominates(const Node *N) const {
        return DFSin <= N->DFSin && DFSout >= N->DFSout;
      }

      bool DominatedBy(const Node *N) const {
        return N->dominates(this);
      }

      /// Sorts by the number of descendants. With this, you can iterate
      /// through a sorted list and the first matching entry is the most
      /// specific match for your basic block. The order provided is stable;
      /// DomTreeDFS::Nodes with the same number of descendants are sorted by
      /// DFS in number.
      bool operator<(const Node &N) const {
        unsigned   spread =   DFSout -   DFSin;
        unsigned N_spread = N.DFSout - N.DFSin;
        if (spread == N_spread) return DFSin < N.DFSin;
        return spread < N_spread;
      }
      bool operator>(const Node &N) const { return N < *this; }

    private:
      unsigned DFSin, DFSout;
      BasicBlock *BB;

      std::vector<Node *> Children;
    };

    // XXX: this may be slow. Instead of using "new" for each node, consider
    // putting them in a vector to keep them contiguous.
    explicit DomTreeDFS(DominatorTree *DT) {
      std::stack<std::pair<Node *, DomTreeNode *> > S;

      Entry = new Node;
      Entry->BB = DT->getRootNode()->getBlock();
      S.push(std::make_pair(Entry, DT->getRootNode()));

      NodeMap[Entry->BB] = Entry;

      while (!S.empty()) {
        std::pair<Node *, DomTreeNode *> &Pair = S.top();
        Node *N = Pair.first;
        DomTreeNode *DTNode = Pair.second;
        S.pop();

        for (DomTreeNode::iterator I = DTNode->begin(), E = DTNode->end();
             I != E; ++I) {
          Node *NewNode = new Node;
          NewNode->BB = (*I)->getBlock();
          N->Children.push_back(NewNode);
          S.push(std::make_pair(NewNode, *I));

          NodeMap[NewNode->BB] = NewNode;
        }
      }

      renumber();

#ifndef NDEBUG
      DEBUG(dump());
#endif
    }

#ifndef NDEBUG
    virtual
#endif
    ~DomTreeDFS() {
      std::stack<Node *> S;

      S.push(Entry);
      while (!S.empty()) {
        Node *N = S.top(); S.pop();

        for (Node::iterator I = N->begin(), E = N->end(); I != E; ++I)
          S.push(*I);

        delete N;
      }
    }

    /// getRootNode - This returns the entry node for the CFG of the function.
    Node *getRootNode() const { return Entry; }

    /// getNodeForBlock - return the node for the specified basic block.
    Node *getNodeForBlock(BasicBlock *BB) const {
      if (!NodeMap.count(BB)) return 0;
      return const_cast<DomTreeDFS*>(this)->NodeMap[BB];
    }

    /// dominates - returns true if the basic block for I1 dominates that of
    /// the basic block for I2. If the instructions belong to the same basic
    /// block, the instruction first instruction sequentially in the block is
    /// considered dominating.
    bool dominates(Instruction *I1, Instruction *I2) {
      BasicBlock *BB1 = I1->getParent(),
                 *BB2 = I2->getParent();
      if (BB1 == BB2) {
        if (isa<TerminatorInst>(I1)) return false;
        if (isa<TerminatorInst>(I2)) return true;
        if ( isa<PHINode>(I1) && !isa<PHINode>(I2)) return true;
        if (!isa<PHINode>(I1) &&  isa<PHINode>(I2)) return false;

        for (BasicBlock::const_iterator I = BB2->begin(), E = BB2->end();
             I != E; ++I) {
          if (&*I == I1) return true;
          else if (&*I == I2) return false;
        }
        assert(!"Instructions not found in parent BasicBlock?");
      } else {
        Node *Node1 = getNodeForBlock(BB1),
             *Node2 = getNodeForBlock(BB2);
        return Node1 && Node2 && Node1->dominates(Node2);
      }
    }

  private:
    /// renumber - calculates the depth first search numberings and applies
    /// them onto the nodes.
    void renumber() {
      std::stack<std::pair<Node *, Node::iterator> > S;
      unsigned n = 0;

      Entry->DFSin = ++n;
      S.push(std::make_pair(Entry, Entry->begin()));

      while (!S.empty()) {
        std::pair<Node *, Node::iterator> &Pair = S.top();
        Node *N = Pair.first;
        Node::iterator &I = Pair.second;

        if (I == N->end()) {
          N->DFSout = ++n;
          S.pop();
        } else {
          Node *Next = *I++;
          Next->DFSin = ++n;
          S.push(std::make_pair(Next, Next->begin()));
        }
      }
    }

#ifndef NDEBUG
    virtual void dump() const {
      dump(*cerr.stream());
    }

    void dump(std::ostream &os) const {
      os << "Predicate simplifier DomTreeDFS: \n";
      dump(Entry, 0, os);
      os << "\n\n";
    }

    void dump(Node *N, int depth, std::ostream &os) const {
      ++depth;
      for (int i = 0; i < depth; ++i) { os << " "; }
      os << "[" << depth << "] ";

      os << N->getBlock()->getName() << " (" << N->getDFSNumIn()
         << ", " << N->getDFSNumOut() << ")\n";

      for (Node::iterator I = N->begin(), E = N->end(); I != E; ++I)
        dump(*I, depth, os);
    }
#endif

    Node *Entry;
    std::map<BasicBlock *, Node *> NodeMap;
  };

  // SLT SGT ULT UGT EQ
  //   0   1   0   1  0 -- GT                  10
  //   0   1   0   1  1 -- GE                  11
  //   0   1   1   0  0 -- SGTULT              12
  //   0   1   1   0  1 -- SGEULE              13
  //   0   1   1   1  0 -- SGT                 14
  //   0   1   1   1  1 -- SGE                 15
  //   1   0   0   1  0 -- SLTUGT              18
  //   1   0   0   1  1 -- SLEUGE              19
  //   1   0   1   0  0 -- LT                  20
  //   1   0   1   0  1 -- LE                  21
  //   1   0   1   1  0 -- SLT                 22
  //   1   0   1   1  1 -- SLE                 23
  //   1   1   0   1  0 -- UGT                 26
  //   1   1   0   1  1 -- UGE                 27
  //   1   1   1   0  0 -- ULT                 28
  //   1   1   1   0  1 -- ULE                 29
  //   1   1   1   1  0 -- NE                  30
  enum LatticeBits {
    EQ_BIT = 1, UGT_BIT = 2, ULT_BIT = 4, SGT_BIT = 8, SLT_BIT = 16
  };
  enum LatticeVal {
    GT = SGT_BIT | UGT_BIT,
    GE = GT | EQ_BIT,
    LT = SLT_BIT | ULT_BIT,
    LE = LT | EQ_BIT,
    NE = SLT_BIT | SGT_BIT | ULT_BIT | UGT_BIT,
    SGTULT = SGT_BIT | ULT_BIT,
    SGEULE = SGTULT | EQ_BIT,
    SLTUGT = SLT_BIT | UGT_BIT,
    SLEUGE = SLTUGT | EQ_BIT,
    ULT = SLT_BIT | SGT_BIT | ULT_BIT,
    UGT = SLT_BIT | SGT_BIT | UGT_BIT,
    SLT = SLT_BIT | ULT_BIT | UGT_BIT,
    SGT = SGT_BIT | ULT_BIT | UGT_BIT,
    SLE = SLT | EQ_BIT,
    SGE = SGT | EQ_BIT,
    ULE = ULT | EQ_BIT,
    UGE = UGT | EQ_BIT
  };

  /// validPredicate - determines whether a given value is actually a lattice
  /// value. Only used in assertions or debugging.
  static bool validPredicate(LatticeVal LV) {
    switch (LV) {
      case GT: case GE: case LT: case LE: case NE:
      case SGTULT: case SGT: case SGEULE:
      case SLTUGT: case SLT: case SLEUGE:
      case ULT: case UGT:
      case SLE: case SGE: case ULE: case UGE:
        return true;
      default:
        return false;
    }
  }

  /// reversePredicate - reverse the direction of the inequality
  static LatticeVal reversePredicate(LatticeVal LV) {
    unsigned reverse = LV ^ (SLT_BIT|SGT_BIT|ULT_BIT|UGT_BIT); //preserve EQ_BIT

    if ((reverse & (SLT_BIT|SGT_BIT)) == 0)
      reverse |= (SLT_BIT|SGT_BIT);

    if ((reverse & (ULT_BIT|UGT_BIT)) == 0)
      reverse |= (ULT_BIT|UGT_BIT);

    LatticeVal Rev = static_cast<LatticeVal>(reverse);
    assert(validPredicate(Rev) && "Failed reversing predicate.");
    return Rev;
  }

  /// ValueNumbering stores the scope-specific value numbers for a given Value.
  class VISIBILITY_HIDDEN ValueNumbering {

    /// VNPair is a tuple of {Value, index number, DomTreeDFS::Node}. It
    /// includes the comparison operators necessary to allow you to store it
    /// in a sorted vector.
    class VISIBILITY_HIDDEN VNPair {
    public:
      Value *V;
      unsigned index;
      DomTreeDFS::Node *Subtree;

      VNPair(Value *V, unsigned index, DomTreeDFS::Node *Subtree)
        : V(V), index(index), Subtree(Subtree) {}

      bool operator==(const VNPair &RHS) const {
        return V == RHS.V && Subtree == RHS.Subtree;
      }

      bool operator<(const VNPair &RHS) const {
        if (V != RHS.V) return V < RHS.V;
        return *Subtree < *RHS.Subtree;
      }

      bool operator<(Value *RHS) const {
        return V < RHS;
      }

      bool operator>(Value *RHS) const {
        return V > RHS;
      }

      friend bool operator<(Value *RHS, const VNPair &pair) {
        return pair.operator>(RHS);
      }
    };

    typedef std::vector<VNPair> VNMapType;
    VNMapType VNMap;

    /// The canonical choice for value number at index.
    std::vector<Value *> Values;

    DomTreeDFS *DTDFS;

  public:
#ifndef NDEBUG
    virtual ~ValueNumbering() {}
    virtual void dump() {
      dump(*cerr.stream());
    }

    void dump(std::ostream &os) {
      for (unsigned i = 1; i <= Values.size(); ++i) {
        os << i << " = ";
        WriteAsOperand(os, Values[i-1]);
        os << " {";
        for (unsigned j = 0; j < VNMap.size(); ++j) {
          if (VNMap[j].index == i) {
            WriteAsOperand(os, VNMap[j].V);
            os << " (" << VNMap[j].Subtree->getDFSNumIn() << ")  ";
          }
        }
        os << "}\n";
      }
    }
#endif

    /// compare - returns true if V1 is a better canonical value than V2.
    bool compare(Value *V1, Value *V2) const {
      if (isa<Constant>(V1))
        return !isa<Constant>(V2);
      else if (isa<Constant>(V2))
        return false;
      else if (isa<Argument>(V1))
        return !isa<Argument>(V2);
      else if (isa<Argument>(V2))
        return false;

      Instruction *I1 = dyn_cast<Instruction>(V1);
      Instruction *I2 = dyn_cast<Instruction>(V2);

      if (!I1 || !I2)
        return V1->getNumUses() < V2->getNumUses();

      return DTDFS->dominates(I1, I2);
    }

    ValueNumbering(DomTreeDFS *DTDFS) : DTDFS(DTDFS) {}

    /// valueNumber - finds the value number for V under the Subtree. If
    /// there is no value number, returns zero.
    unsigned valueNumber(Value *V, DomTreeDFS::Node *Subtree) {
      if (!(isa<Constant>(V) || isa<Argument>(V) || isa<Instruction>(V))
          || V->getType() == Type::VoidTy) return 0;

      VNMapType::iterator E = VNMap.end();
      VNPair pair(V, 0, Subtree);
      VNMapType::iterator I = std::lower_bound(VNMap.begin(), E, pair);
      while (I != E && I->V == V) {
        if (I->Subtree->dominates(Subtree))
          return I->index;
        ++I;
      }
      return 0;
    }

    /// getOrInsertVN - always returns a value number, creating it if necessary.
    unsigned getOrInsertVN(Value *V, DomTreeDFS::Node *Subtree) {
      if (unsigned n = valueNumber(V, Subtree))
        return n;
      else
        return newVN(V);
    }

    /// newVN - creates a new value number. Value V must not already have a
    /// value number assigned.
    unsigned newVN(Value *V) {
      assert((isa<Constant>(V) || isa<Argument>(V) || isa<Instruction>(V)) &&
             "Bad Value for value numbering.");
      assert(V->getType() != Type::VoidTy && "Won't value number a void value");

      Values.push_back(V);

      VNPair pair = VNPair(V, Values.size(), DTDFS->getRootNode());
      VNMapType::iterator I = std::lower_bound(VNMap.begin(), VNMap.end(), pair);
      assert((I == VNMap.end() || value(I->index) != V) &&
             "Attempt to create a duplicate value number.");
      VNMap.insert(I, pair);

      return Values.size();
    }

    /// value - returns the Value associated with a value number.
    Value *value(unsigned index) const {
      assert(index != 0 && "Zero index is reserved for not found.");
      assert(index <= Values.size() && "Index out of range.");
      return Values[index-1];
    }

    /// canonicalize - return a Value that is equal to V under Subtree.
    Value *canonicalize(Value *V, DomTreeDFS::Node *Subtree) {
      if (isa<Constant>(V)) return V;

      if (unsigned n = valueNumber(V, Subtree))
        return value(n);
      else
        return V;
    }

    /// addEquality - adds that value V belongs to the set of equivalent
    /// values defined by value number n under Subtree.
    void addEquality(unsigned n, Value *V, DomTreeDFS::Node *Subtree) {
      assert(canonicalize(value(n), Subtree) == value(n) &&
             "Node's 'canonical' choice isn't best within this subtree.");

      // Suppose that we are given "%x -> node #1 (%y)". The problem is that
      // we may already have "%z -> node #2 (%x)" somewhere above us in the
      // graph. We need to find those edges and add "%z -> node #1 (%y)"
      // to keep the lookups canonical.

      std::vector<Value *> ToRepoint(1, V);

      if (unsigned Conflict = valueNumber(V, Subtree)) {
        for (VNMapType::iterator I = VNMap.begin(), E = VNMap.end();
             I != E; ++I) {
          if (I->index == Conflict && I->Subtree->dominates(Subtree))
            ToRepoint.push_back(I->V);
        }
      }

      for (std::vector<Value *>::iterator VI = ToRepoint.begin(),
           VE = ToRepoint.end(); VI != VE; ++VI) {
        Value *V = *VI;

        VNPair pair(V, n, Subtree);
        VNMapType::iterator B = VNMap.begin(), E = VNMap.end();
        VNMapType::iterator I = std::lower_bound(B, E, pair);
        if (I != E && I->V == V && I->Subtree == Subtree)
          I->index = n; // Update best choice
        else
          VNMap.insert(I, pair); // New Value

        // XXX: we currently don't have to worry about updating values with
        // more specific Subtrees, but we will need to for PHI node support.

#ifndef NDEBUG
        Value *V_n = value(n);
        if (isa<Constant>(V) && isa<Constant>(V_n)) {
          assert(V == V_n && "Constant equals different constant?");
        }
#endif
      }
    }

    /// remove - removes all references to value V.
    void remove(Value *V) {
      VNMapType::iterator B = VNMap.begin(), E = VNMap.end();
      VNPair pair(V, 0, DTDFS->getRootNode());
      VNMapType::iterator J = std::upper_bound(B, E, pair);
      VNMapType::iterator I = J;

      while (I != B && (I == E || I->V == V)) --I;

      VNMap.erase(I, J);
    }
  };

  /// The InequalityGraph stores the relationships between values.
  /// Each Value in the graph is assigned to a Node. Nodes are pointer
  /// comparable for equality. The caller is expected to maintain the logical
  /// consistency of the system.
  ///
  /// The InequalityGraph class may invalidate Node*s after any mutator call.
  /// @brief The InequalityGraph stores the relationships between values.
  class VISIBILITY_HIDDEN InequalityGraph {
    ValueNumbering &VN;
    DomTreeDFS::Node *TreeRoot;

    InequalityGraph();                  // DO NOT IMPLEMENT
    InequalityGraph(InequalityGraph &); // DO NOT IMPLEMENT
  public:
    InequalityGraph(ValueNumbering &VN, DomTreeDFS::Node *TreeRoot)
      : VN(VN), TreeRoot(TreeRoot) {}

    class Node;

    /// An Edge is contained inside a Node making one end of the edge implicit
    /// and contains a pointer to the other end. The edge contains a lattice
    /// value specifying the relationship and an DomTreeDFS::Node specifying
    /// the root in the dominator tree to which this edge applies.
    class VISIBILITY_HIDDEN Edge {
    public:
      Edge(unsigned T, LatticeVal V, DomTreeDFS::Node *ST)
        : To(T), LV(V), Subtree(ST) {}

      unsigned To;
      LatticeVal LV;
      DomTreeDFS::Node *Subtree;

      bool operator<(const Edge &edge) const {
        if (To != edge.To) return To < edge.To;
        return *Subtree < *edge.Subtree;
      }

      bool operator<(unsigned to) const {
        return To < to;
      }

      bool operator>(unsigned to) const {
        return To > to;
      }

      friend bool operator<(unsigned to, const Edge &edge) {
        return edge.operator>(to);
      }
    };

    /// A single node in the InequalityGraph. This stores the canonical Value
    /// for the node, as well as the relationships with the neighbours.
    ///
    /// @brief A single node in the InequalityGraph.
    class VISIBILITY_HIDDEN Node {
      friend class InequalityGraph;

      typedef SmallVector<Edge, 4> RelationsType;
      RelationsType Relations;

      // TODO: can this idea improve performance?
      //friend class std::vector<Node>;
      //Node(Node &N) { RelationsType.swap(N.RelationsType); }

    public:
      typedef RelationsType::iterator       iterator;
      typedef RelationsType::const_iterator const_iterator;

#ifndef NDEBUG
      virtual ~Node() {}
      virtual void dump() const {
        dump(*cerr.stream());
      }
    private:
      void dump(std::ostream &os) const {
        static const std::string names[32] =
          { "000000", "000001", "000002", "000003", "000004", "000005",
            "000006", "000007", "000008", "000009", "     >", "    >=",
            "  s>u<", "s>=u<=", "    s>", "   s>=", "000016", "000017",
            "  s<u>", "s<=u>=", "     <", "    <=", "    s<", "   s<=",
            "000024", "000025", "    u>", "   u>=", "    u<", "   u<=",
            "    !=", "000031" };
        for (Node::const_iterator NI = begin(), NE = end(); NI != NE; ++NI) {
          os << names[NI->LV] << " " << NI->To
             << " (" << NI->Subtree->getDFSNumIn() << "), ";
        }
      }
    public:
#endif

      iterator begin()             { return Relations.begin(); }
      iterator end()               { return Relations.end();   }
      const_iterator begin() const { return Relations.begin(); }
      const_iterator end()   const { return Relations.end();   }

      iterator find(unsigned n, DomTreeDFS::Node *Subtree) {
        iterator E = end();
        for (iterator I = std::lower_bound(begin(), E, n);
             I != E && I->To == n; ++I) {
          if (Subtree->DominatedBy(I->Subtree))
            return I;
        }
        return E;
      }

      const_iterator find(unsigned n, DomTreeDFS::Node *Subtree) const {
        const_iterator E = end();
        for (const_iterator I = std::lower_bound(begin(), E, n);
             I != E && I->To == n; ++I) {
          if (Subtree->DominatedBy(I->Subtree))
            return I;
        }
        return E;
      }

      /// update - updates the lattice value for a given node, creating a new
      /// entry if one doesn't exist. The new lattice value must not be
      /// inconsistent with any previously existing value.
      void update(unsigned n, LatticeVal R, DomTreeDFS::Node *Subtree) {
        assert(validPredicate(R) && "Invalid predicate.");

        Edge edge(n, R, Subtree);
        iterator B = begin(), E = end();
        iterator I = std::lower_bound(B, E, edge);

        iterator J = I;
        while (J != E && J->To == n) {
          if (Subtree->DominatedBy(J->Subtree))
            break;
          ++J;
        }

        if (J != E && J->To == n) {
          edge.LV = static_cast<LatticeVal>(J->LV & R);
          assert(validPredicate(edge.LV) && "Invalid union of lattice values.");

          if (edge.LV == J->LV)
            return; // This update adds nothing new.
	}

        if (I != B) {
          // We also have to tighten any edge beneath our update.
          for (iterator K = I - 1; K->To == n; --K) {
            if (K->Subtree->DominatedBy(Subtree)) {
              LatticeVal LV = static_cast<LatticeVal>(K->LV & edge.LV);
              assert(validPredicate(LV) && "Invalid union of lattice values");
              K->LV = LV;
            }
            if (K == B) break;
          }
	}

        // Insert new edge at Subtree if it isn't already there.
        if (I == E || I->To != n || Subtree != I->Subtree)
          Relations.insert(I, edge);
      }
    };

  private:

    std::vector<Node> Nodes;

  public:
    /// node - returns the node object at a given value number. The pointer
    /// returned may be invalidated on the next call to node().
    Node *node(unsigned index) {
      assert(VN.value(index)); // This triggers the necessary checks.
      if (Nodes.size() < index) Nodes.resize(index);
      return &Nodes[index-1];
    }

    /// isRelatedBy - true iff n1 op n2
    bool isRelatedBy(unsigned n1, unsigned n2, DomTreeDFS::Node *Subtree,
                     LatticeVal LV) {
      if (n1 == n2) return LV & EQ_BIT;

      Node *N1 = node(n1);
      Node::iterator I = N1->find(n2, Subtree), E = N1->end();
      if (I != E) return (I->LV & LV) == I->LV;

      return false;
    }

    // The add* methods assume that your input is logically valid and may 
    // assertion-fail or infinitely loop if you attempt a contradiction.

    /// addInequality - Sets n1 op n2.
    /// It is also an error to call this on an inequality that is already true.
    void addInequality(unsigned n1, unsigned n2, DomTreeDFS::Node *Subtree,
                       LatticeVal LV1) {
      assert(n1 != n2 && "A node can't be inequal to itself.");

      if (LV1 != NE)
        assert(!isRelatedBy(n1, n2, Subtree, reversePredicate(LV1)) &&
               "Contradictory inequality.");

      // Suppose we're adding %n1 < %n2. Find all the %a < %n1 and
      // add %a < %n2 too. This keeps the graph fully connected.
      if (LV1 != NE) {
        // Break up the relationship into signed and unsigned comparison parts.
        // If the signed parts of %a op1 %n1 match that of %n1 op2 %n2, and
        // op1 and op2 aren't NE, then add %a op3 %n2. The new relationship
        // should have the EQ_BIT iff it's set for both op1 and op2.

        unsigned LV1_s = LV1 & (SLT_BIT|SGT_BIT);
        unsigned LV1_u = LV1 & (ULT_BIT|UGT_BIT);

        for (Node::iterator I = node(n1)->begin(), E = node(n1)->end(); I != E; ++I) {
          if (I->LV != NE && I->To != n2) {

            DomTreeDFS::Node *Local_Subtree = NULL;
            if (Subtree->DominatedBy(I->Subtree))
              Local_Subtree = Subtree;
            else if (I->Subtree->DominatedBy(Subtree))
              Local_Subtree = I->Subtree;

            if (Local_Subtree) {
              unsigned new_relationship = 0;
              LatticeVal ILV = reversePredicate(I->LV);
              unsigned ILV_s = ILV & (SLT_BIT|SGT_BIT);
              unsigned ILV_u = ILV & (ULT_BIT|UGT_BIT);

              if (LV1_s != (SLT_BIT|SGT_BIT) && ILV_s == LV1_s)
                new_relationship |= ILV_s;
              if (LV1_u != (ULT_BIT|UGT_BIT) && ILV_u == LV1_u)
                new_relationship |= ILV_u;

              if (new_relationship) {
                if ((new_relationship & (SLT_BIT|SGT_BIT)) == 0)
                  new_relationship |= (SLT_BIT|SGT_BIT);
                if ((new_relationship & (ULT_BIT|UGT_BIT)) == 0)
                  new_relationship |= (ULT_BIT|UGT_BIT);
                if ((LV1 & EQ_BIT) && (ILV & EQ_BIT))
                  new_relationship |= EQ_BIT;

                LatticeVal NewLV = static_cast<LatticeVal>(new_relationship);

                node(I->To)->update(n2, NewLV, Local_Subtree);
                node(n2)->update(I->To, reversePredicate(NewLV), Local_Subtree);
              }
            }
          }
        }

        for (Node::iterator I = node(n2)->begin(), E = node(n2)->end(); I != E; ++I) {
          if (I->LV != NE && I->To != n1) {
            DomTreeDFS::Node *Local_Subtree = NULL;
            if (Subtree->DominatedBy(I->Subtree))
              Local_Subtree = Subtree;
            else if (I->Subtree->DominatedBy(Subtree))
              Local_Subtree = I->Subtree;

            if (Local_Subtree) {
              unsigned new_relationship = 0;
              unsigned ILV_s = I->LV & (SLT_BIT|SGT_BIT);
              unsigned ILV_u = I->LV & (ULT_BIT|UGT_BIT);

              if (LV1_s != (SLT_BIT|SGT_BIT) && ILV_s == LV1_s)
                new_relationship |= ILV_s;

              if (LV1_u != (ULT_BIT|UGT_BIT) && ILV_u == LV1_u)
                new_relationship |= ILV_u;

              if (new_relationship) {
                if ((new_relationship & (SLT_BIT|SGT_BIT)) == 0)
                  new_relationship |= (SLT_BIT|SGT_BIT);
                if ((new_relationship & (ULT_BIT|UGT_BIT)) == 0)
                  new_relationship |= (ULT_BIT|UGT_BIT);
                if ((LV1 & EQ_BIT) && (I->LV & EQ_BIT))
                  new_relationship |= EQ_BIT;

                LatticeVal NewLV = static_cast<LatticeVal>(new_relationship);

                node(n1)->update(I->To, NewLV, Local_Subtree);
                node(I->To)->update(n1, reversePredicate(NewLV), Local_Subtree);
              }
            }
          }
        }
      }

      node(n1)->update(n2, LV1, Subtree);
      node(n2)->update(n1, reversePredicate(LV1), Subtree);
    }

    /// remove - removes a node from the graph by removing all references to
    /// and from it.
    void remove(unsigned n) {
      Node *N = node(n);
      for (Node::iterator NI = N->begin(), NE = N->end(); NI != NE; ++NI) {
        Node::iterator Iter = node(NI->To)->find(n, TreeRoot);
        do {
          node(NI->To)->Relations.erase(Iter);
          Iter = node(NI->To)->find(n, TreeRoot);
        } while (Iter != node(NI->To)->end());
      }
      N->Relations.clear();
    }

#ifndef NDEBUG
    virtual ~InequalityGraph() {}
    virtual void dump() {
      dump(*cerr.stream());
    }

    void dump(std::ostream &os) {
      for (unsigned i = 1; i <= Nodes.size(); ++i) {
        os << i << " = {";
        node(i)->dump(os);
        os << "}\n";
      }
    }
#endif
  };

  class VRPSolver;

  /// ValueRanges tracks the known integer ranges and anti-ranges of the nodes
  /// in the InequalityGraph.
  class VISIBILITY_HIDDEN ValueRanges {
    ValueNumbering &VN;
    TargetData *TD;

    class VISIBILITY_HIDDEN ScopedRange {
      typedef std::vector<std::pair<DomTreeDFS::Node *, ConstantRange> >
              RangeListType;
      RangeListType RangeList;

      static bool swo(const std::pair<DomTreeDFS::Node *, ConstantRange> &LHS,
                      const std::pair<DomTreeDFS::Node *, ConstantRange> &RHS) {
        return *LHS.first < *RHS.first;
      }

    public:
#ifndef NDEBUG
      virtual ~ScopedRange() {}
      virtual void dump() const {
        dump(*cerr.stream());
      }

      void dump(std::ostream &os) const {
        os << "{";
        for (const_iterator I = begin(), E = end(); I != E; ++I) {
          os << I->second << " (" << I->first->getDFSNumIn() << "), ";
        }
        os << "}";
      }
#endif

      typedef RangeListType::iterator       iterator;
      typedef RangeListType::const_iterator const_iterator;

      iterator begin() { return RangeList.begin(); }
      iterator end()   { return RangeList.end(); }
      const_iterator begin() const { return RangeList.begin(); }
      const_iterator end()   const { return RangeList.end(); }

      iterator find(DomTreeDFS::Node *Subtree) {
        static ConstantRange empty(1, false);
        iterator E = end();
        iterator I = std::lower_bound(begin(), E,
                                      std::make_pair(Subtree, empty), swo);

        while (I != E && !I->first->dominates(Subtree)) ++I;
        return I;
      }

      const_iterator find(DomTreeDFS::Node *Subtree) const {
        static const ConstantRange empty(1, false);
        const_iterator E = end();
        const_iterator I = std::lower_bound(begin(), E,
                                            std::make_pair(Subtree, empty), swo);

        while (I != E && !I->first->dominates(Subtree)) ++I;
        return I;
      }

      void update(const ConstantRange &CR, DomTreeDFS::Node *Subtree) {
        assert(!CR.isEmptySet() && "Empty ConstantRange.");
        assert(!CR.isSingleElement() && "Refusing to store single element.");

        static ConstantRange empty(1, false);
        iterator E = end();
        iterator I =
            std::lower_bound(begin(), E, std::make_pair(Subtree, empty), swo);

        if (I != end() && I->first == Subtree) {
          ConstantRange CR2 = I->second.maximalIntersectWith(CR);
          assert(!CR2.isEmptySet() && !CR2.isSingleElement() &&
                 "Invalid union of ranges.");
          I->second = CR2;
        } else
          RangeList.insert(I, std::make_pair(Subtree, CR));
      }
    };

    std::vector<ScopedRange> Ranges;

    void update(unsigned n, const ConstantRange &CR, DomTreeDFS::Node *Subtree){
      if (CR.isFullSet()) return;
      if (Ranges.size() < n) Ranges.resize(n);
      Ranges[n-1].update(CR, Subtree);
    }

    /// create - Creates a ConstantRange that matches the given LatticeVal
    /// relation with a given integer.
    ConstantRange create(LatticeVal LV, const ConstantRange &CR) {
      assert(!CR.isEmptySet() && "Can't deal with empty set.");

      if (LV == NE)
        return makeConstantRange(ICmpInst::ICMP_NE, CR);

      unsigned LV_s = LV & (SGT_BIT|SLT_BIT);
      unsigned LV_u = LV & (UGT_BIT|ULT_BIT);
      bool hasEQ = LV & EQ_BIT;

      ConstantRange Range(CR.getBitWidth());

      if (LV_s == SGT_BIT) {
        Range = Range.maximalIntersectWith(makeConstantRange(
                    hasEQ ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_SGT, CR));
      } else if (LV_s == SLT_BIT) {
        Range = Range.maximalIntersectWith(makeConstantRange(
                    hasEQ ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_SLT, CR));
      }

      if (LV_u == UGT_BIT) {
        Range = Range.maximalIntersectWith(makeConstantRange(
                    hasEQ ? ICmpInst::ICMP_UGE : ICmpInst::ICMP_UGT, CR));
      } else if (LV_u == ULT_BIT) {
        Range = Range.maximalIntersectWith(makeConstantRange(
                    hasEQ ? ICmpInst::ICMP_ULE : ICmpInst::ICMP_ULT, CR));
      }

      return Range;
    }

    /// makeConstantRange - Creates a ConstantRange representing the set of all
    /// value that match the ICmpInst::Predicate with any of the values in CR.
    ConstantRange makeConstantRange(ICmpInst::Predicate ICmpOpcode,
                                    const ConstantRange &CR) {
      uint32_t W = CR.getBitWidth();
      switch (ICmpOpcode) {
        default: assert(!"Invalid ICmp opcode to makeConstantRange()");
        case ICmpInst::ICMP_EQ:
          return ConstantRange(CR.getLower(), CR.getUpper());
        case ICmpInst::ICMP_NE:
          if (CR.isSingleElement())
            return ConstantRange(CR.getUpper(), CR.getLower());
          return ConstantRange(W);
        case ICmpInst::ICMP_ULT:
          return ConstantRange(APInt::getMinValue(W), CR.getUnsignedMax());
        case ICmpInst::ICMP_SLT:
          return ConstantRange(APInt::getSignedMinValue(W), CR.getSignedMax());
        case ICmpInst::ICMP_ULE: {
          APInt UMax(CR.getUnsignedMax());
          if (UMax.isMaxValue())
            return ConstantRange(W);
          return ConstantRange(APInt::getMinValue(W), UMax + 1);
        }
        case ICmpInst::ICMP_SLE: {
          APInt SMax(CR.getSignedMax());
          if (SMax.isMaxSignedValue() || (SMax+1).isMaxSignedValue())
            return ConstantRange(W);
          return ConstantRange(APInt::getSignedMinValue(W), SMax + 1);
        }
        case ICmpInst::ICMP_UGT:
          return ConstantRange(CR.getUnsignedMin() + 1, APInt::getNullValue(W));
        case ICmpInst::ICMP_SGT:
          return ConstantRange(CR.getSignedMin() + 1,
                               APInt::getSignedMinValue(W));
        case ICmpInst::ICMP_UGE: {
          APInt UMin(CR.getUnsignedMin());
          if (UMin.isMinValue())
            return ConstantRange(W);
          return ConstantRange(UMin, APInt::getNullValue(W));
        }
        case ICmpInst::ICMP_SGE: {
          APInt SMin(CR.getSignedMin());
          if (SMin.isMinSignedValue())
            return ConstantRange(W);
          return ConstantRange(SMin, APInt::getSignedMinValue(W));
        }
      }
    }

#ifndef NDEBUG
    bool isCanonical(Value *V, DomTreeDFS::Node *Subtree) {
      return V == VN.canonicalize(V, Subtree);
    }
#endif

  public:

    ValueRanges(ValueNumbering &VN, TargetData *TD) : VN(VN), TD(TD) {}

#ifndef NDEBUG
    virtual ~ValueRanges() {}

    virtual void dump() const {
      dump(*cerr.stream());
    }

    void dump(std::ostream &os) const {
      for (unsigned i = 0, e = Ranges.size(); i != e; ++i) {
        os << (i+1) << " = ";
        Ranges[i].dump(os);
        os << "\n";
      }
    }
#endif

    /// range - looks up the ConstantRange associated with a value number.
    ConstantRange range(unsigned n, DomTreeDFS::Node *Subtree) {
      assert(VN.value(n)); // performs range checks

      if (n <= Ranges.size()) {
        ScopedRange::iterator I = Ranges[n-1].find(Subtree);
        if (I != Ranges[n-1].end()) return I->second;
      }

      Value *V = VN.value(n);
      ConstantRange CR = range(V);
      return CR;
    }

    /// range - determine a range from a Value without performing any lookups.
    ConstantRange range(Value *V) const {
      if (ConstantInt *C = dyn_cast<ConstantInt>(V))
        return ConstantRange(C->getValue());
      else if (isa<ConstantPointerNull>(V))
        return ConstantRange(APInt::getNullValue(typeToWidth(V->getType())));
      else
        return typeToWidth(V->getType());
    }

    // typeToWidth - returns the number of bits necessary to store a value of
    // this type, or zero if unknown.
    uint32_t typeToWidth(const Type *Ty) const {
      if (TD)
        return TD->getTypeSizeInBits(Ty);

      if (const IntegerType *ITy = dyn_cast<IntegerType>(Ty))
        return ITy->getBitWidth();

      return 0;
    }

    static bool isRelatedBy(const ConstantRange &CR1, const ConstantRange &CR2,
                            LatticeVal LV) {
      switch (LV) {
      default: assert(!"Impossible lattice value!");
      case NE:
        return CR1.maximalIntersectWith(CR2).isEmptySet();
      case ULT:
        return CR1.getUnsignedMax().ult(CR2.getUnsignedMin());
      case ULE:
        return CR1.getUnsignedMax().ule(CR2.getUnsignedMin());
      case UGT:
        return CR1.getUnsignedMin().ugt(CR2.getUnsignedMax());
      case UGE:
        return CR1.getUnsignedMin().uge(CR2.getUnsignedMax());
      case SLT:
        return CR1.getSignedMax().slt(CR2.getSignedMin());
      case SLE:
        return CR1.getSignedMax().sle(CR2.getSignedMin());
      case SGT:
        return CR1.getSignedMin().sgt(CR2.getSignedMax());
      case SGE:
        return CR1.getSignedMin().sge(CR2.getSignedMax());
      case LT:
        return CR1.getUnsignedMax().ult(CR2.getUnsignedMin()) &&
               CR1.getSignedMax().slt(CR2.getUnsignedMin());
      case LE:
        return CR1.getUnsignedMax().ule(CR2.getUnsignedMin()) &&
               CR1.getSignedMax().sle(CR2.getUnsignedMin());
      case GT:
        return CR1.getUnsignedMin().ugt(CR2.getUnsignedMax()) &&
               CR1.getSignedMin().sgt(CR2.getSignedMax());
      case GE:
        return CR1.getUnsignedMin().uge(CR2.getUnsignedMax()) &&
               CR1.getSignedMin().sge(CR2.getSignedMax());
      case SLTUGT:
        return CR1.getSignedMax().slt(CR2.getSignedMin()) &&
               CR1.getUnsignedMin().ugt(CR2.getUnsignedMax());
      case SLEUGE:
        return CR1.getSignedMax().sle(CR2.getSignedMin()) &&
               CR1.getUnsignedMin().uge(CR2.getUnsignedMax());
      case SGTULT:
        return CR1.getSignedMin().sgt(CR2.getSignedMax()) &&
               CR1.getUnsignedMax().ult(CR2.getUnsignedMin());
      case SGEULE:
        return CR1.getSignedMin().sge(CR2.getSignedMax()) &&
               CR1.getUnsignedMax().ule(CR2.getUnsignedMin());
      }
    }

    bool isRelatedBy(unsigned n1, unsigned n2, DomTreeDFS::Node *Subtree,
                     LatticeVal LV) {
      ConstantRange CR1 = range(n1, Subtree);
      ConstantRange CR2 = range(n2, Subtree);

      // True iff all values in CR1 are LV to all values in CR2.
      return isRelatedBy(CR1, CR2, LV);
    }

    void addToWorklist(Value *V, Constant *C, ICmpInst::Predicate Pred,
                       VRPSolver *VRP);
    void markBlock(VRPSolver *VRP);

    void mergeInto(Value **I, unsigned n, unsigned New,
                   DomTreeDFS::Node *Subtree, VRPSolver *VRP) {
      ConstantRange CR_New = range(New, Subtree);
      ConstantRange Merged = CR_New;

      for (; n != 0; ++I, --n) {
        unsigned i = VN.valueNumber(*I, Subtree);
        ConstantRange CR_Kill = i ? range(i, Subtree) : range(*I);
        if (CR_Kill.isFullSet()) continue;
        Merged = Merged.maximalIntersectWith(CR_Kill);
      }

      if (Merged.isFullSet() || Merged == CR_New) return;

      applyRange(New, Merged, Subtree, VRP);
    }

    void applyRange(unsigned n, const ConstantRange &CR,
                    DomTreeDFS::Node *Subtree, VRPSolver *VRP) {
      ConstantRange Merged = CR.maximalIntersectWith(range(n, Subtree));
      if (Merged.isEmptySet()) {
        markBlock(VRP);
        return;
      }

      if (const APInt *I = Merged.getSingleElement()) {
        Value *V = VN.value(n); // XXX: redesign worklist.
        const Type *Ty = V->getType();
        if (Ty->isInteger()) {
          addToWorklist(V, ConstantInt::get(*I), ICmpInst::ICMP_EQ, VRP);
          return;
        } else if (const PointerType *PTy = dyn_cast<PointerType>(Ty)) {
          assert(*I == 0 && "Pointer is null but not zero?");
          addToWorklist(V, ConstantPointerNull::get(PTy),
                        ICmpInst::ICMP_EQ, VRP);
          return;
        }
      }

      update(n, Merged, Subtree);
    }

    void addNotEquals(unsigned n1, unsigned n2, DomTreeDFS::Node *Subtree,
                      VRPSolver *VRP) {
      ConstantRange CR1 = range(n1, Subtree);
      ConstantRange CR2 = range(n2, Subtree);

      uint32_t W = CR1.getBitWidth();

      if (const APInt *I = CR1.getSingleElement()) {
        if (CR2.isFullSet()) {
          ConstantRange NewCR2(CR1.getUpper(), CR1.getLower());
          applyRange(n2, NewCR2, Subtree, VRP);
        } else if (*I == CR2.getLower()) {
          APInt NewLower(CR2.getLower() + 1),
                NewUpper(CR2.getUpper());
          if (NewLower == NewUpper)
            NewLower = NewUpper = APInt::getMinValue(W);

          ConstantRange NewCR2(NewLower, NewUpper);
          applyRange(n2, NewCR2, Subtree, VRP);
        } else if (*I == CR2.getUpper() - 1) {
          APInt NewLower(CR2.getLower()),
                NewUpper(CR2.getUpper() - 1);
          if (NewLower == NewUpper)
            NewLower = NewUpper = APInt::getMinValue(W);

          ConstantRange NewCR2(NewLower, NewUpper);
          applyRange(n2, NewCR2, Subtree, VRP);
        }
      }

      if (const APInt *I = CR2.getSingleElement()) {
        if (CR1.isFullSet()) {
          ConstantRange NewCR1(CR2.getUpper(), CR2.getLower());
          applyRange(n1, NewCR1, Subtree, VRP);
        } else if (*I == CR1.getLower()) {
          APInt NewLower(CR1.getLower() + 1),
                NewUpper(CR1.getUpper());
          if (NewLower == NewUpper)
            NewLower = NewUpper = APInt::getMinValue(W);

          ConstantRange NewCR1(NewLower, NewUpper);
          applyRange(n1, NewCR1, Subtree, VRP);
        } else if (*I == CR1.getUpper() - 1) {
          APInt NewLower(CR1.getLower()),
                NewUpper(CR1.getUpper() - 1);
          if (NewLower == NewUpper)
            NewLower = NewUpper = APInt::getMinValue(W);

          ConstantRange NewCR1(NewLower, NewUpper);
          applyRange(n1, NewCR1, Subtree, VRP);
        }
      }
    }

    void addInequality(unsigned n1, unsigned n2, DomTreeDFS::Node *Subtree,
                       LatticeVal LV, VRPSolver *VRP) {
      assert(!isRelatedBy(n1, n2, Subtree, LV) && "Asked to do useless work.");

      if (LV == NE) {
        addNotEquals(n1, n2, Subtree, VRP);
        return;
      }

      ConstantRange CR1 = range(n1, Subtree);
      ConstantRange CR2 = range(n2, Subtree);

      if (!CR1.isSingleElement()) {
        ConstantRange NewCR1 = CR1.maximalIntersectWith(create(LV, CR2));
        if (NewCR1 != CR1)
          applyRange(n1, NewCR1, Subtree, VRP);
      }

      if (!CR2.isSingleElement()) {
        ConstantRange NewCR2 = CR2.maximalIntersectWith(
                                       create(reversePredicate(LV), CR1));
        if (NewCR2 != CR2)
          applyRange(n2, NewCR2, Subtree, VRP);
      }
    }
  };

  /// UnreachableBlocks keeps tracks of blocks that are for one reason or
  /// another discovered to be unreachable. This is used to cull the graph when
  /// analyzing instructions, and to mark blocks with the "unreachable"
  /// terminator instruction after the function has executed.
  class VISIBILITY_HIDDEN UnreachableBlocks {
  private:
    std::vector<BasicBlock *> DeadBlocks;

  public:
    /// mark - mark a block as dead
    void mark(BasicBlock *BB) {
      std::vector<BasicBlock *>::iterator E = DeadBlocks.end();
      std::vector<BasicBlock *>::iterator I =
        std::lower_bound(DeadBlocks.begin(), E, BB);

      if (I == E || *I != BB) DeadBlocks.insert(I, BB);
    }

    /// isDead - returns whether a block is known to be dead already
    bool isDead(BasicBlock *BB) {
      std::vector<BasicBlock *>::iterator E = DeadBlocks.end();
      std::vector<BasicBlock *>::iterator I =
        std::lower_bound(DeadBlocks.begin(), E, BB);

      return I != E && *I == BB;
    }

    /// kill - replace the dead blocks' terminator with an UnreachableInst.
    bool kill() {
      bool modified = false;
      for (std::vector<BasicBlock *>::iterator I = DeadBlocks.begin(),
           E = DeadBlocks.end(); I != E; ++I) {
        BasicBlock *BB = *I;

        DOUT << "unreachable block: " << BB->getName() << "\n";

        for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB);
             SI != SE; ++SI) {
          BasicBlock *Succ = *SI;
          Succ->removePredecessor(BB);
        }

        TerminatorInst *TI = BB->getTerminator();
        TI->replaceAllUsesWith(UndefValue::get(TI->getType()));
        TI->eraseFromParent();
        new UnreachableInst(BB);
        ++NumBlocks;
        modified = true;
      }
      DeadBlocks.clear();
      return modified;
    }
  };

  /// VRPSolver keeps track of how changes to one variable affect other
  /// variables, and forwards changes along to the InequalityGraph. It
  /// also maintains the correct choice for "canonical" in the IG.
  /// @brief VRPSolver calculates inferences from a new relationship.
  class VISIBILITY_HIDDEN VRPSolver {
  private:
    friend class ValueRanges;

    struct Operation {
      Value *LHS, *RHS;
      ICmpInst::Predicate Op;

      BasicBlock *ContextBB; // XXX use a DomTreeDFS::Node instead
      Instruction *ContextInst;
    };
    std::deque<Operation> WorkList;

    ValueNumbering &VN;
    InequalityGraph &IG;
    UnreachableBlocks &UB;
    ValueRanges &VR;
    DomTreeDFS *DTDFS;
    DomTreeDFS::Node *Top;
    BasicBlock *TopBB;
    Instruction *TopInst;
    bool &modified;

    typedef InequalityGraph::Node Node;

    // below - true if the Instruction is dominated by the current context
    // block or instruction
    bool below(Instruction *I) {
      BasicBlock *BB = I->getParent();
      if (TopInst && TopInst->getParent() == BB) {
        if (isa<TerminatorInst>(TopInst)) return false;
        if (isa<TerminatorInst>(I)) return true;
        if ( isa<PHINode>(TopInst) && !isa<PHINode>(I)) return true;
        if (!isa<PHINode>(TopInst) &&  isa<PHINode>(I)) return false;

        for (BasicBlock::const_iterator Iter = BB->begin(), E = BB->end();
             Iter != E; ++Iter) {
          if (&*Iter == TopInst) return true;
          else if (&*Iter == I) return false;
        }
        assert(!"Instructions not found in parent BasicBlock?");
      } else {
        DomTreeDFS::Node *Node = DTDFS->getNodeForBlock(BB);
        if (!Node) return false;
        return Top->dominates(Node);
      }
    }

    // aboveOrBelow - true if the Instruction either dominates or is dominated
    // by the current context block or instruction
    bool aboveOrBelow(Instruction *I) {
      BasicBlock *BB = I->getParent();
      DomTreeDFS::Node *Node = DTDFS->getNodeForBlock(BB);
      if (!Node) return false;

      return Top == Node || Top->dominates(Node) || Node->dominates(Top);
    }

    bool makeEqual(Value *V1, Value *V2) {
      DOUT << "makeEqual(" << *V1 << ", " << *V2 << ")\n";
      DOUT << "context is ";
      if (TopInst) DOUT << "I: " << *TopInst << "\n";
      else DOUT << "BB: " << TopBB->getName()
                << "(" << Top->getDFSNumIn() << ")\n";

      assert(V1->getType() == V2->getType() &&
             "Can't make two values with different types equal.");

      if (V1 == V2) return true;

      if (isa<Constant>(V1) && isa<Constant>(V2))
        return false;

      unsigned n1 = VN.valueNumber(V1, Top), n2 = VN.valueNumber(V2, Top);

      if (n1 && n2) {
        if (n1 == n2) return true;
        if (IG.isRelatedBy(n1, n2, Top, NE)) return false;
      }

      if (n1) assert(V1 == VN.value(n1) && "Value isn't canonical.");
      if (n2) assert(V2 == VN.value(n2) && "Value isn't canonical.");

      assert(!VN.compare(V2, V1) && "Please order parameters to makeEqual.");

      assert(!isa<Constant>(V2) && "Tried to remove a constant.");

      SetVector<unsigned> Remove;
      if (n2) Remove.insert(n2);

      if (n1 && n2) {
        // Suppose we're being told that %x == %y, and %x <= %z and %y >= %z.
        // We can't just merge %x and %y because the relationship with %z would
        // be EQ and that's invalid. What we're doing is looking for any nodes
        // %z such that %x <= %z and %y >= %z, and vice versa.

        Node::iterator end = IG.node(n2)->end();

        // Find the intersection between N1 and N2 which is dominated by
        // Top. If we find %x where N1 <= %x <= N2 (or >=) then add %x to
        // Remove.
        for (Node::iterator I = IG.node(n1)->begin(), E = IG.node(n1)->end();
             I != E; ++I) {
          if (!(I->LV & EQ_BIT) || !Top->DominatedBy(I->Subtree)) continue;

          unsigned ILV_s = I->LV & (SLT_BIT|SGT_BIT);
          unsigned ILV_u = I->LV & (ULT_BIT|UGT_BIT);
          Node::iterator NI = IG.node(n2)->find(I->To, Top);
          if (NI != end) {
            LatticeVal NILV = reversePredicate(NI->LV);
            unsigned NILV_s = NILV & (SLT_BIT|SGT_BIT);
            unsigned NILV_u = NILV & (ULT_BIT|UGT_BIT);

            if ((ILV_s != (SLT_BIT|SGT_BIT) && ILV_s == NILV_s) ||
                (ILV_u != (ULT_BIT|UGT_BIT) && ILV_u == NILV_u))
              Remove.insert(I->To);
          }
        }

        // See if one of the nodes about to be removed is actually a better
        // canonical choice than n1.
        unsigned orig_n1 = n1;
        SetVector<unsigned>::iterator DontRemove = Remove.end();
        for (SetVector<unsigned>::iterator I = Remove.begin()+1 /* skip n2 */,
             E = Remove.end(); I != E; ++I) {
          unsigned n = *I;
          Value *V = VN.value(n);
          if (VN.compare(V, V1)) {
            V1 = V;
            n1 = n;
            DontRemove = I;
          }
        }
        if (DontRemove != Remove.end()) {
          unsigned n = *DontRemove;
          Remove.remove(n);
          Remove.insert(orig_n1);
        }
      }

      // We'd like to allow makeEqual on two values to perform a simple
      // substitution without every creating nodes in the IG whenever possible.
      //
      // The first iteration through this loop operates on V2 before going
      // through the Remove list and operating on those too. If all of the
      // iterations performed simple replacements then we exit early.
      bool mergeIGNode = false;
      unsigned i = 0;
      for (Value *R = V2; i == 0 || i < Remove.size(); ++i) {
        if (i) R = VN.value(Remove[i]); // skip n2.

        // Try to replace the whole instruction. If we can, we're done.
        Instruction *I2 = dyn_cast<Instruction>(R);
        if (I2 && below(I2)) {
          std::vector<Instruction *> ToNotify;
          for (Value::use_iterator UI = R->use_begin(), UE = R->use_end();
               UI != UE;) {
            Use &TheUse = UI.getUse();
            ++UI;
            if (Instruction *I = dyn_cast<Instruction>(TheUse.getUser()))
              ToNotify.push_back(I);
          }

          DOUT << "Simply removing " << *I2
               << ", replacing with " << *V1 << "\n";
          I2->replaceAllUsesWith(V1);
          // leave it dead; it'll get erased later.
          ++NumInstruction;
          modified = true;

          for (std::vector<Instruction *>::iterator II = ToNotify.begin(),
               IE = ToNotify.end(); II != IE; ++II) {
            opsToDef(*II);
          }

          continue;
        }

        // Otherwise, replace all dominated uses.
        for (Value::use_iterator UI = R->use_begin(), UE = R->use_end();
             UI != UE;) {
          Use &TheUse = UI.getUse();
          ++UI;
          if (Instruction *I = dyn_cast<Instruction>(TheUse.getUser())) {
            if (below(I)) {
              TheUse.set(V1);
              modified = true;
              ++NumVarsReplaced;
              opsToDef(I);
            }
          }
        }

        // If that killed the instruction, stop here.
        if (I2 && isInstructionTriviallyDead(I2)) {
          DOUT << "Killed all uses of " << *I2
               << ", replacing with " << *V1 << "\n";
          continue;
        }

        // If we make it to here, then we will need to create a node for N1.
        // Otherwise, we can skip out early!
        mergeIGNode = true;
      }

      if (!isa<Constant>(V1)) {
        if (Remove.empty()) {
          VR.mergeInto(&V2, 1, VN.getOrInsertVN(V1, Top), Top, this);
        } else {
          std::vector<Value*> RemoveVals;
          RemoveVals.reserve(Remove.size());

          for (SetVector<unsigned>::iterator I = Remove.begin(),
               E = Remove.end(); I != E; ++I) {
            Value *V = VN.value(*I);
            if (!V->use_empty())
              RemoveVals.push_back(V);
          }
          VR.mergeInto(&RemoveVals[0], RemoveVals.size(), 
                       VN.getOrInsertVN(V1, Top), Top, this);
        }
      }

      if (mergeIGNode) {
        // Create N1.
        if (!n1) n1 = VN.getOrInsertVN(V1, Top);

        // Migrate relationships from removed nodes to N1.
        for (SetVector<unsigned>::iterator I = Remove.begin(), E = Remove.end();
             I != E; ++I) {
          unsigned n = *I;
          for (Node::iterator NI = IG.node(n)->begin(), NE = IG.node(n)->end();
               NI != NE; ++NI) {
            if (NI->Subtree->DominatedBy(Top)) {
              if (NI->To == n1) {
                assert((NI->LV & EQ_BIT) && "Node inequal to itself.");
                continue;
              }
              if (Remove.count(NI->To))
                continue;

              IG.node(NI->To)->update(n1, reversePredicate(NI->LV), Top);
              IG.node(n1)->update(NI->To, NI->LV, Top);
            }
          }
        }

        // Point V2 (and all items in Remove) to N1.
        if (!n2)
          VN.addEquality(n1, V2, Top);
        else {
          for (SetVector<unsigned>::iterator I = Remove.begin(),
               E = Remove.end(); I != E; ++I) {
            VN.addEquality(n1, VN.value(*I), Top);
          }
        }

        // If !Remove.empty() then V2 = Remove[0]->getValue().
        // Even when Remove is empty, we still want to process V2.
        i = 0;
        for (Value *R = V2; i == 0 || i < Remove.size(); ++i) {
          if (i) R = VN.value(Remove[i]); // skip n2.

          if (Instruction *I2 = dyn_cast<Instruction>(R)) {
            if (aboveOrBelow(I2))
            defToOps(I2);
          }
          for (Value::use_iterator UI = V2->use_begin(), UE = V2->use_end();
               UI != UE;) {
            Use &TheUse = UI.getUse();
            ++UI;
            if (Instruction *I = dyn_cast<Instruction>(TheUse.getUser())) {
              if (aboveOrBelow(I))
                opsToDef(I);
            }
          }
        }
      }

      // re-opsToDef all dominated users of V1.
      if (Instruction *I = dyn_cast<Instruction>(V1)) {
        for (Value::use_iterator UI = I->use_begin(), UE = I->use_end();
             UI != UE;) {
          Use &TheUse = UI.getUse();
          ++UI;
          Value *V = TheUse.getUser();
          if (!V->use_empty()) {
            if (Instruction *Inst = dyn_cast<Instruction>(V)) {
              if (aboveOrBelow(Inst))
                opsToDef(Inst);
            }
          }
        }
      }

      return true;
    }

    /// cmpInstToLattice - converts an CmpInst::Predicate to lattice value
    /// Requires that the lattice value be valid; does not accept ICMP_EQ.
    static LatticeVal cmpInstToLattice(ICmpInst::Predicate Pred) {
      switch (Pred) {
        case ICmpInst::ICMP_EQ:
          assert(!"No matching lattice value.");
          return static_cast<LatticeVal>(EQ_BIT);
        default:
          assert(!"Invalid 'icmp' predicate.");
        case ICmpInst::ICMP_NE:
          return NE;
        case ICmpInst::ICMP_UGT:
          return UGT;
        case ICmpInst::ICMP_UGE:
          return UGE;
        case ICmpInst::ICMP_ULT:
          return ULT;
        case ICmpInst::ICMP_ULE:
          return ULE;
        case ICmpInst::ICMP_SGT:
          return SGT;
        case ICmpInst::ICMP_SGE:
          return SGE;
        case ICmpInst::ICMP_SLT:
          return SLT;
        case ICmpInst::ICMP_SLE:
          return SLE;
      }
    }

  public:
    VRPSolver(ValueNumbering &VN, InequalityGraph &IG, UnreachableBlocks &UB,
              ValueRanges &VR, DomTreeDFS *DTDFS, bool &modified,
              BasicBlock *TopBB)
      : VN(VN),
        IG(IG),
        UB(UB),
        VR(VR),
        DTDFS(DTDFS),
        Top(DTDFS->getNodeForBlock(TopBB)),
        TopBB(TopBB),
        TopInst(NULL),
        modified(modified)
    {
      assert(Top && "VRPSolver created for unreachable basic block.");
    }

    VRPSolver(ValueNumbering &VN, InequalityGraph &IG, UnreachableBlocks &UB,
              ValueRanges &VR, DomTreeDFS *DTDFS, bool &modified,
              Instruction *TopInst)
      : VN(VN),
        IG(IG),
        UB(UB),
        VR(VR),
        DTDFS(DTDFS),
        Top(DTDFS->getNodeForBlock(TopInst->getParent())),
        TopBB(TopInst->getParent()),
        TopInst(TopInst),
        modified(modified)
    {
      assert(Top && "VRPSolver created for unreachable basic block.");
      assert(Top->getBlock() == TopInst->getParent() && "Context mismatch.");
    }

    bool isRelatedBy(Value *V1, Value *V2, ICmpInst::Predicate Pred) const {
      if (Constant *C1 = dyn_cast<Constant>(V1))
        if (Constant *C2 = dyn_cast<Constant>(V2))
          return ConstantExpr::getCompare(Pred, C1, C2) ==
                 ConstantInt::getTrue();

      unsigned n1 = VN.valueNumber(V1, Top);
      unsigned n2 = VN.valueNumber(V2, Top);

      if (n1 && n2) {
        if (n1 == n2) return Pred == ICmpInst::ICMP_EQ ||
                             Pred == ICmpInst::ICMP_ULE ||
                             Pred == ICmpInst::ICMP_UGE ||
                             Pred == ICmpInst::ICMP_SLE ||
                             Pred == ICmpInst::ICMP_SGE;
        if (Pred == ICmpInst::ICMP_EQ) return false;
        if (IG.isRelatedBy(n1, n2, Top, cmpInstToLattice(Pred))) return true;
        if (VR.isRelatedBy(n1, n2, Top, cmpInstToLattice(Pred))) return true;
      }

      if ((n1 && !n2 && isa<Constant>(V2)) ||
          (n2 && !n1 && isa<Constant>(V1))) {
        ConstantRange CR1 = n1 ? VR.range(n1, Top) : VR.range(V1);
        ConstantRange CR2 = n2 ? VR.range(n2, Top) : VR.range(V2);

        if (Pred == ICmpInst::ICMP_EQ)
          return CR1.isSingleElement() &&
                 CR1.getSingleElement() == CR2.getSingleElement();

        return VR.isRelatedBy(CR1, CR2, cmpInstToLattice(Pred));
      }
      if (Pred == ICmpInst::ICMP_EQ) return V1 == V2;
      return false;
    }

    /// add - adds a new property to the work queue
    void add(Value *V1, Value *V2, ICmpInst::Predicate Pred,
             Instruction *I = NULL) {
      DOUT << "adding " << *V1 << " " << Pred << " " << *V2;
      if (I) DOUT << " context: " << *I;
      else DOUT << " default context (" << Top->getDFSNumIn() << ")";
      DOUT << "\n";

      assert(V1->getType() == V2->getType() &&
             "Can't relate two values with different types.");

      WorkList.push_back(Operation());
      Operation &O = WorkList.back();
      O.LHS = V1, O.RHS = V2, O.Op = Pred, O.ContextInst = I;
      O.ContextBB = I ? I->getParent() : TopBB;
    }

    /// defToOps - Given an instruction definition that we've learned something
    /// new about, find any new relationships between its operands.
    void defToOps(Instruction *I) {
      Instruction *NewContext = below(I) ? I : TopInst;
      Value *Canonical = VN.canonicalize(I, Top);

      if (BinaryOperator *BO = dyn_cast<BinaryOperator>(I)) {
        const Type *Ty = BO->getType();
        assert(!Ty->isFPOrFPVector() && "Float in work queue!");

        Value *Op0 = VN.canonicalize(BO->getOperand(0), Top);
        Value *Op1 = VN.canonicalize(BO->getOperand(1), Top);

        // TODO: "and i32 -1, %x" EQ %y then %x EQ %y.

        switch (BO->getOpcode()) {
          case Instruction::And: {
            // "and i32 %a, %b" EQ -1 then %a EQ -1 and %b EQ -1
            ConstantInt *CI = ConstantInt::getAllOnesValue(Ty);
            if (Canonical == CI) {
              add(CI, Op0, ICmpInst::ICMP_EQ, NewContext);
              add(CI, Op1, ICmpInst::ICMP_EQ, NewContext);
            }
          } break;
          case Instruction::Or: {
            // "or i32 %a, %b" EQ 0 then %a EQ 0 and %b EQ 0
            Constant *Zero = Constant::getNullValue(Ty);
            if (Canonical == Zero) {
              add(Zero, Op0, ICmpInst::ICMP_EQ, NewContext);
              add(Zero, Op1, ICmpInst::ICMP_EQ, NewContext);
            }
          } break;
          case Instruction::Xor: {
            // "xor i32 %c, %a" EQ %b then %a EQ %c ^ %b
            // "xor i32 %c, %a" EQ %c then %a EQ 0
            // "xor i32 %c, %a" NE %c then %a NE 0
            // Repeat the above, with order of operands reversed.
            Value *LHS = Op0;
            Value *RHS = Op1;
            if (!isa<Constant>(LHS)) std::swap(LHS, RHS);

            if (ConstantInt *CI = dyn_cast<ConstantInt>(Canonical)) {
              if (ConstantInt *Arg = dyn_cast<ConstantInt>(LHS)) {
                add(RHS, ConstantInt::get(CI->getValue() ^ Arg->getValue()),
                    ICmpInst::ICMP_EQ, NewContext);
              }
            }
            if (Canonical == LHS) {
              if (isa<ConstantInt>(Canonical))
                add(RHS, Constant::getNullValue(Ty), ICmpInst::ICMP_EQ,
                    NewContext);
            } else if (isRelatedBy(LHS, Canonical, ICmpInst::ICMP_NE)) {
              add(RHS, Constant::getNullValue(Ty), ICmpInst::ICMP_NE,
                  NewContext);
            }
          } break;
          default:
            break;
        }
      } else if (ICmpInst *IC = dyn_cast<ICmpInst>(I)) {
        // "icmp ult i32 %a, %y" EQ true then %a u< y
        // etc.

        if (Canonical == ConstantInt::getTrue()) {
          add(IC->getOperand(0), IC->getOperand(1), IC->getPredicate(),
              NewContext);
        } else if (Canonical == ConstantInt::getFalse()) {
          add(IC->getOperand(0), IC->getOperand(1),
              ICmpInst::getInversePredicate(IC->getPredicate()), NewContext);
        }
      } else if (SelectInst *SI = dyn_cast<SelectInst>(I)) {
        if (I->getType()->isFPOrFPVector()) return;

        // Given: "%a = select i1 %x, i32 %b, i32 %c"
        // %a EQ %b and %b NE %c then %x EQ true
        // %a EQ %c and %b NE %c then %x EQ false

        Value *True  = SI->getTrueValue();
        Value *False = SI->getFalseValue();
        if (isRelatedBy(True, False, ICmpInst::ICMP_NE)) {
          if (Canonical == VN.canonicalize(True, Top) ||
              isRelatedBy(Canonical, False, ICmpInst::ICMP_NE))
            add(SI->getCondition(), ConstantInt::getTrue(),
                ICmpInst::ICMP_EQ, NewContext);
          else if (Canonical == VN.canonicalize(False, Top) ||
                   isRelatedBy(Canonical, True, ICmpInst::ICMP_NE))
            add(SI->getCondition(), ConstantInt::getFalse(),
                ICmpInst::ICMP_EQ, NewContext);
        }
      } else if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(I)) {
        for (GetElementPtrInst::op_iterator OI = GEPI->idx_begin(),
             OE = GEPI->idx_end(); OI != OE; ++OI) {
          ConstantInt *Op = dyn_cast<ConstantInt>(VN.canonicalize(*OI, Top));
          if (!Op || !Op->isZero()) return;
        }
        // TODO: The GEPI indices are all zero. Copy from definition to operand,
        // jumping the type plane as needed.
        if (isRelatedBy(GEPI, Constant::getNullValue(GEPI->getType()),
                        ICmpInst::ICMP_NE)) {
          Value *Ptr = GEPI->getPointerOperand();
          add(Ptr, Constant::getNullValue(Ptr->getType()), ICmpInst::ICMP_NE,
              NewContext);
        }
      } else if (CastInst *CI = dyn_cast<CastInst>(I)) {
        const Type *SrcTy = CI->getSrcTy();

        unsigned ci = VN.getOrInsertVN(CI, Top);
        uint32_t W = VR.typeToWidth(SrcTy);
        if (!W) return;
        ConstantRange CR = VR.range(ci, Top);

        if (CR.isFullSet()) return;

        switch (CI->getOpcode()) {
          default: break;
          case Instruction::ZExt:
          case Instruction::SExt:
            VR.applyRange(VN.getOrInsertVN(CI->getOperand(0), Top),
                          CR.truncate(W), Top, this);
            break;
          case Instruction::BitCast:
            VR.applyRange(VN.getOrInsertVN(CI->getOperand(0), Top),
                          CR, Top, this);
            break;
        }
      }
    }

    /// opsToDef - A new relationship was discovered involving one of this
    /// instruction's operands. Find any new relationship involving the
    /// definition, or another operand.
    void opsToDef(Instruction *I) {
      Instruction *NewContext = below(I) ? I : TopInst;

      if (BinaryOperator *BO = dyn_cast<BinaryOperator>(I)) {
        Value *Op0 = VN.canonicalize(BO->getOperand(0), Top);
        Value *Op1 = VN.canonicalize(BO->getOperand(1), Top);

        if (ConstantInt *CI0 = dyn_cast<ConstantInt>(Op0))
          if (ConstantInt *CI1 = dyn_cast<ConstantInt>(Op1)) {
            add(BO, ConstantExpr::get(BO->getOpcode(), CI0, CI1),
                ICmpInst::ICMP_EQ, NewContext);
            return;
          }

        // "%y = and i1 true, %x" then %x EQ %y
        // "%y = or i1 false, %x" then %x EQ %y
        // "%x = add i32 %y, 0" then %x EQ %y
        // "%x = mul i32 %y, 0" then %x EQ 0

        Instruction::BinaryOps Opcode = BO->getOpcode();
        const Type *Ty = BO->getType();
        assert(!Ty->isFPOrFPVector() && "Float in work queue!");

        Constant *Zero = Constant::getNullValue(Ty);
        ConstantInt *AllOnes = ConstantInt::getAllOnesValue(Ty);

        switch (Opcode) {
          default: break;
          case Instruction::LShr:
          case Instruction::AShr:
          case Instruction::Shl:
          case Instruction::Sub:
            if (Op1 == Zero) {
              add(BO, Op0, ICmpInst::ICMP_EQ, NewContext);
              return;
            }
            break;
          case Instruction::Or:
            if (Op0 == AllOnes || Op1 == AllOnes) {
              add(BO, AllOnes, ICmpInst::ICMP_EQ, NewContext);
              return;
            } // fall-through
          case Instruction::Xor:
          case Instruction::Add:
            if (Op0 == Zero) {
              add(BO, Op1, ICmpInst::ICMP_EQ, NewContext);
              return;
            } else if (Op1 == Zero) {
              add(BO, Op0, ICmpInst::ICMP_EQ, NewContext);
              return;
            }
            break;
          case Instruction::And:
            if (Op0 == AllOnes) {
              add(BO, Op1, ICmpInst::ICMP_EQ, NewContext);
              return;
            } else if (Op1 == AllOnes) {
              add(BO, Op0, ICmpInst::ICMP_EQ, NewContext);
              return;
            }
            // fall-through
          case Instruction::Mul:
            if (Op0 == Zero || Op1 == Zero) {
              add(BO, Zero, ICmpInst::ICMP_EQ, NewContext);
              return;
            }
            break;
        }

        // "%x = add i32 %y, %z" and %x EQ %y then %z EQ 0
        // "%x = add i32 %y, %z" and %x EQ %z then %y EQ 0
        // "%x = shl i32 %y, %z" and %x EQ %y and %y NE 0 then %z EQ 0
        // "%x = udiv i32 %y, %z" and %x EQ %y then %z EQ 1

        Value *Known = Op0, *Unknown = Op1,
              *TheBO = VN.canonicalize(BO, Top);
        if (Known != TheBO) std::swap(Known, Unknown);
        if (Known == TheBO) {
          switch (Opcode) {
            default: break;
            case Instruction::LShr:
            case Instruction::AShr:
            case Instruction::Shl:
              if (!isRelatedBy(Known, Zero, ICmpInst::ICMP_NE)) break;
              // otherwise, fall-through.
            case Instruction::Sub:
              if (Unknown == Op1) break;
              // otherwise, fall-through.
            case Instruction::Xor:
            case Instruction::Add:
              add(Unknown, Zero, ICmpInst::ICMP_EQ, NewContext);
              break;
            case Instruction::UDiv:
            case Instruction::SDiv:
              if (Unknown == Op1) break;
              if (isRelatedBy(Known, Zero, ICmpInst::ICMP_NE)) {
                Constant *One = ConstantInt::get(Ty, 1);
                add(Unknown, One, ICmpInst::ICMP_EQ, NewContext);
              }
              break;
          }
        }

        // TODO: "%a = add i32 %b, 1" and %b > %z then %a >= %z.

      } else if (ICmpInst *IC = dyn_cast<ICmpInst>(I)) {
        // "%a = icmp ult i32 %b, %c" and %b u<  %c then %a EQ true
        // "%a = icmp ult i32 %b, %c" and %b u>= %c then %a EQ false
        // etc.

        Value *Op0 = VN.canonicalize(IC->getOperand(0), Top);
        Value *Op1 = VN.canonicalize(IC->getOperand(1), Top);

        ICmpInst::Predicate Pred = IC->getPredicate();
        if (isRelatedBy(Op0, Op1, Pred))
          add(IC, ConstantInt::getTrue(), ICmpInst::ICMP_EQ, NewContext);
        else if (isRelatedBy(Op0, Op1, ICmpInst::getInversePredicate(Pred)))
          add(IC, ConstantInt::getFalse(), ICmpInst::ICMP_EQ, NewContext);

      } else if (SelectInst *SI = dyn_cast<SelectInst>(I)) {
        if (I->getType()->isFPOrFPVector()) return;

        // Given: "%a = select i1 %x, i32 %b, i32 %c"
        // %x EQ true  then %a EQ %b
        // %x EQ false then %a EQ %c
        // %b EQ %c then %a EQ %b

        Value *Canonical = VN.canonicalize(SI->getCondition(), Top);
        if (Canonical == ConstantInt::getTrue()) {
          add(SI, SI->getTrueValue(), ICmpInst::ICMP_EQ, NewContext);
        } else if (Canonical == ConstantInt::getFalse()) {
          add(SI, SI->getFalseValue(), ICmpInst::ICMP_EQ, NewContext);
        } else if (VN.canonicalize(SI->getTrueValue(), Top) ==
                   VN.canonicalize(SI->getFalseValue(), Top)) {
          add(SI, SI->getTrueValue(), ICmpInst::ICMP_EQ, NewContext);
        }
      } else if (CastInst *CI = dyn_cast<CastInst>(I)) {
        const Type *DestTy = CI->getDestTy();
        if (DestTy->isFPOrFPVector()) return;

        Value *Op = VN.canonicalize(CI->getOperand(0), Top);
        Instruction::CastOps Opcode = CI->getOpcode();

        if (Constant *C = dyn_cast<Constant>(Op)) {
          add(CI, ConstantExpr::getCast(Opcode, C, DestTy),
              ICmpInst::ICMP_EQ, NewContext);
        }

        uint32_t W = VR.typeToWidth(DestTy);
        unsigned ci = VN.getOrInsertVN(CI, Top);
        ConstantRange CR = VR.range(VN.getOrInsertVN(Op, Top), Top);

        if (!CR.isFullSet()) {
          switch (Opcode) {
            default: break;
            case Instruction::ZExt:
              VR.applyRange(ci, CR.zeroExtend(W), Top, this);
              break;
            case Instruction::SExt:
              VR.applyRange(ci, CR.signExtend(W), Top, this);
              break;
            case Instruction::Trunc: {
              ConstantRange Result = CR.truncate(W);
              if (!Result.isFullSet())
                VR.applyRange(ci, Result, Top, this);
            } break;
            case Instruction::BitCast:
              VR.applyRange(ci, CR, Top, this);
              break;
            // TODO: other casts?
          }
        }
      } else if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(I)) {
        for (GetElementPtrInst::op_iterator OI = GEPI->idx_begin(),
             OE = GEPI->idx_end(); OI != OE; ++OI) {
          ConstantInt *Op = dyn_cast<ConstantInt>(VN.canonicalize(*OI, Top));
          if (!Op || !Op->isZero()) return;
        }
        // TODO: The GEPI indices are all zero. Copy from operand to definition,
        // jumping the type plane as needed.
        Value *Ptr = GEPI->getPointerOperand();
        if (isRelatedBy(Ptr, Constant::getNullValue(Ptr->getType()),
                        ICmpInst::ICMP_NE)) {
          add(GEPI, Constant::getNullValue(GEPI->getType()), ICmpInst::ICMP_NE,
              NewContext);
        }
      }
    }

    /// solve - process the work queue
    void solve() {
      //DOUT << "WorkList entry, size: " << WorkList.size() << "\n";
      while (!WorkList.empty()) {
        //DOUT << "WorkList size: " << WorkList.size() << "\n";

        Operation &O = WorkList.front();
        TopInst = O.ContextInst;
        TopBB = O.ContextBB;
        Top = DTDFS->getNodeForBlock(TopBB); // XXX move this into Context

        O.LHS = VN.canonicalize(O.LHS, Top);
        O.RHS = VN.canonicalize(O.RHS, Top);

        assert(O.LHS == VN.canonicalize(O.LHS, Top) && "Canonicalize isn't.");
        assert(O.RHS == VN.canonicalize(O.RHS, Top) && "Canonicalize isn't.");

        DOUT << "solving " << *O.LHS << " " << O.Op << " " << *O.RHS;
        if (O.ContextInst) DOUT << " context inst: " << *O.ContextInst;
        else DOUT << " context block: " << O.ContextBB->getName();
        DOUT << "\n";

        DEBUG(VN.dump());
        DEBUG(IG.dump());
        DEBUG(VR.dump());

        // If they're both Constant, skip it. Check for contradiction and mark
        // the BB as unreachable if so.
        if (Constant *CI_L = dyn_cast<Constant>(O.LHS)) {
          if (Constant *CI_R = dyn_cast<Constant>(O.RHS)) {
            if (ConstantExpr::getCompare(O.Op, CI_L, CI_R) ==
                ConstantInt::getFalse())
              UB.mark(TopBB);

            WorkList.pop_front();
            continue;
          }
        }

        if (VN.compare(O.LHS, O.RHS)) {
          std::swap(O.LHS, O.RHS);
          O.Op = ICmpInst::getSwappedPredicate(O.Op);
        }

        if (O.Op == ICmpInst::ICMP_EQ) {
          if (!makeEqual(O.RHS, O.LHS))
            UB.mark(TopBB);
        } else {
          LatticeVal LV = cmpInstToLattice(O.Op);

          if ((LV & EQ_BIT) &&
              isRelatedBy(O.LHS, O.RHS, ICmpInst::getSwappedPredicate(O.Op))) {
            if (!makeEqual(O.RHS, O.LHS))
              UB.mark(TopBB);
          } else {
            if (isRelatedBy(O.LHS, O.RHS, ICmpInst::getInversePredicate(O.Op))){
              UB.mark(TopBB);
              WorkList.pop_front();
              continue;
            }

            unsigned n1 = VN.getOrInsertVN(O.LHS, Top);
            unsigned n2 = VN.getOrInsertVN(O.RHS, Top);

            if (n1 == n2) {
              if (O.Op != ICmpInst::ICMP_UGE && O.Op != ICmpInst::ICMP_ULE &&
                  O.Op != ICmpInst::ICMP_SGE && O.Op != ICmpInst::ICMP_SLE)
                UB.mark(TopBB);

              WorkList.pop_front();
              continue;
            }

            if (VR.isRelatedBy(n1, n2, Top, LV) ||
                IG.isRelatedBy(n1, n2, Top, LV)) {
              WorkList.pop_front();
              continue;
            }

            VR.addInequality(n1, n2, Top, LV, this);
            if ((!isa<ConstantInt>(O.RHS) && !isa<ConstantInt>(O.LHS)) ||
                LV == NE)
              IG.addInequality(n1, n2, Top, LV);

            if (Instruction *I1 = dyn_cast<Instruction>(O.LHS)) {
              if (aboveOrBelow(I1))
                defToOps(I1);
            }
            if (isa<Instruction>(O.LHS) || isa<Argument>(O.LHS)) {
              for (Value::use_iterator UI = O.LHS->use_begin(),
                   UE = O.LHS->use_end(); UI != UE;) {
                Use &TheUse = UI.getUse();
                ++UI;
                if (Instruction *I = dyn_cast<Instruction>(TheUse.getUser())) {
                  if (aboveOrBelow(I))
                    opsToDef(I);
                }
              }
            }
            if (Instruction *I2 = dyn_cast<Instruction>(O.RHS)) {
              if (aboveOrBelow(I2))
              defToOps(I2);
            }
            if (isa<Instruction>(O.RHS) || isa<Argument>(O.RHS)) {
              for (Value::use_iterator UI = O.RHS->use_begin(),
                   UE = O.RHS->use_end(); UI != UE;) {
                Use &TheUse = UI.getUse();
                ++UI;
                if (Instruction *I = dyn_cast<Instruction>(TheUse.getUser())) {
                  if (aboveOrBelow(I))
                    opsToDef(I);
                }
              }
            }
          }
        }
        WorkList.pop_front();
      }
    }
  };

  void ValueRanges::addToWorklist(Value *V, Constant *C,
                                  ICmpInst::Predicate Pred, VRPSolver *VRP) {
    VRP->add(V, C, Pred, VRP->TopInst);
  }

  void ValueRanges::markBlock(VRPSolver *VRP) {
    VRP->UB.mark(VRP->TopBB);
  }

  /// PredicateSimplifier - This class is a simplifier that replaces
  /// one equivalent variable with another. It also tracks what
  /// can't be equal and will solve setcc instructions when possible.
  /// @brief Root of the predicate simplifier optimization.
  class VISIBILITY_HIDDEN PredicateSimplifier : public FunctionPass {
    DomTreeDFS *DTDFS;
    bool modified;
    ValueNumbering *VN;
    InequalityGraph *IG;
    UnreachableBlocks UB;
    ValueRanges *VR;

    std::vector<DomTreeDFS::Node *> WorkList;

  public:
    static char ID; // Pass identification, replacement for typeid
    PredicateSimplifier() : FunctionPass((intptr_t)&ID) {}

    bool runOnFunction(Function &F);

    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.addRequiredID(BreakCriticalEdgesID);
      AU.addRequired<DominatorTree>();
      AU.addRequired<TargetData>();
      AU.addPreserved<TargetData>();
    }

  private:
    /// Forwards - Adds new properties to VRPSolver and uses them to
    /// simplify instructions. Because new properties sometimes apply to
    /// a transition from one BasicBlock to another, this will use the
    /// PredicateSimplifier::proceedToSuccessor(s) interface to enter the
    /// basic block.
    /// @brief Performs abstract execution of the program.
    class VISIBILITY_HIDDEN Forwards : public InstVisitor<Forwards> {
      friend class InstVisitor<Forwards>;
      PredicateSimplifier *PS;
      DomTreeDFS::Node *DTNode;

    public:
      ValueNumbering &VN;
      InequalityGraph &IG;
      UnreachableBlocks &UB;
      ValueRanges &VR;

      Forwards(PredicateSimplifier *PS, DomTreeDFS::Node *DTNode)
        : PS(PS), DTNode(DTNode), VN(*PS->VN), IG(*PS->IG), UB(PS->UB),
          VR(*PS->VR) {}

      void visitTerminatorInst(TerminatorInst &TI);
      void visitBranchInst(BranchInst &BI);
      void visitSwitchInst(SwitchInst &SI);

      void visitAllocaInst(AllocaInst &AI);
      void visitLoadInst(LoadInst &LI);
      void visitStoreInst(StoreInst &SI);

      void visitSExtInst(SExtInst &SI);
      void visitZExtInst(ZExtInst &ZI);

      void visitBinaryOperator(BinaryOperator &BO);
      void visitICmpInst(ICmpInst &IC);
    };
  
    // Used by terminator instructions to proceed from the current basic
    // block to the next. Verifies that "current" dominates "next",
    // then calls visitBasicBlock.
    void proceedToSuccessors(DomTreeDFS::Node *Current) {
      for (DomTreeDFS::Node::iterator I = Current->begin(),
           E = Current->end(); I != E; ++I) {
        WorkList.push_back(*I);
      }
    }

    void proceedToSuccessor(DomTreeDFS::Node *Next) {
      WorkList.push_back(Next);
    }

    // Visits each instruction in the basic block.
    void visitBasicBlock(DomTreeDFS::Node *Node) {
      BasicBlock *BB = Node->getBlock();
      DOUT << "Entering Basic Block: " << BB->getName()
           << " (" << Node->getDFSNumIn() << ")\n";
      for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E;) {
        visitInstruction(I++, Node);
      }
    }

    // Tries to simplify each Instruction and add new properties.
    void visitInstruction(Instruction *I, DomTreeDFS::Node *DT) {
      DOUT << "Considering instruction " << *I << "\n";
      DEBUG(VN->dump());
      DEBUG(IG->dump());
      DEBUG(VR->dump());

      // Sometimes instructions are killed in earlier analysis.
      if (isInstructionTriviallyDead(I)) {
        ++NumSimple;
        modified = true;
        if (unsigned n = VN->valueNumber(I, DTDFS->getRootNode()))
          if (VN->value(n) == I) IG->remove(n);
        VN->remove(I);
        I->eraseFromParent();
        return;
      }

#ifndef NDEBUG
      // Try to replace the whole instruction.
      Value *V = VN->canonicalize(I, DT);
      assert(V == I && "Late instruction canonicalization.");
      if (V != I) {
        modified = true;
        ++NumInstruction;
        DOUT << "Removing " << *I << ", replacing with " << *V << "\n";
        if (unsigned n = VN->valueNumber(I, DTDFS->getRootNode()))
          if (VN->value(n) == I) IG->remove(n);
        VN->remove(I);
        I->replaceAllUsesWith(V);
        I->eraseFromParent();
        return;
      }

      // Try to substitute operands.
      for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
        Value *Oper = I->getOperand(i);
        Value *V = VN->canonicalize(Oper, DT);
        assert(V == Oper && "Late operand canonicalization.");
        if (V != Oper) {
          modified = true;
          ++NumVarsReplaced;
          DOUT << "Resolving " << *I;
          I->setOperand(i, V);
          DOUT << " into " << *I;
        }
      }
#endif

      std::string name = I->getParent()->getName();
      DOUT << "push (%" << name << ")\n";
      Forwards visit(this, DT);
      visit.visit(*I);
      DOUT << "pop (%" << name << ")\n";
    }
  };

  bool PredicateSimplifier::runOnFunction(Function &F) {
    DominatorTree *DT = &getAnalysis<DominatorTree>();
    DTDFS = new DomTreeDFS(DT);
    TargetData *TD = &getAnalysis<TargetData>();

    DOUT << "Entering Function: " << F.getName() << "\n";

    modified = false;
    DomTreeDFS::Node *Root = DTDFS->getRootNode();
    VN = new ValueNumbering(DTDFS);
    IG = new InequalityGraph(*VN, Root);
    VR = new ValueRanges(*VN, TD);
    WorkList.push_back(Root);

    do {
      DomTreeDFS::Node *DTNode = WorkList.back();
      WorkList.pop_back();
      if (!UB.isDead(DTNode->getBlock())) visitBasicBlock(DTNode);
    } while (!WorkList.empty());

    delete DTDFS;
    delete VR;
    delete IG;

    modified |= UB.kill();

    return modified;
  }

  void PredicateSimplifier::Forwards::visitTerminatorInst(TerminatorInst &TI) {
    PS->proceedToSuccessors(DTNode);
  }

  void PredicateSimplifier::Forwards::visitBranchInst(BranchInst &BI) {
    if (BI.isUnconditional()) {
      PS->proceedToSuccessors(DTNode);
      return;
    }

    Value *Condition = BI.getCondition();
    BasicBlock *TrueDest  = BI.getSuccessor(0);
    BasicBlock *FalseDest = BI.getSuccessor(1);

    if (isa<Constant>(Condition) || TrueDest == FalseDest) {
      PS->proceedToSuccessors(DTNode);
      return;
    }

    for (DomTreeDFS::Node::iterator I = DTNode->begin(), E = DTNode->end();
         I != E; ++I) {
      BasicBlock *Dest = (*I)->getBlock();
      DOUT << "Branch thinking about %" << Dest->getName()
           << "(" << PS->DTDFS->getNodeForBlock(Dest)->getDFSNumIn() << ")\n";

      if (Dest == TrueDest) {
        DOUT << "(" << DTNode->getBlock()->getName() << ") true set:\n";
        VRPSolver VRP(VN, IG, UB, VR, PS->DTDFS, PS->modified, Dest);
        VRP.add(ConstantInt::getTrue(), Condition, ICmpInst::ICMP_EQ);
        VRP.solve();
        DEBUG(VN.dump());
        DEBUG(IG.dump());
        DEBUG(VR.dump());
      } else if (Dest == FalseDest) {
        DOUT << "(" << DTNode->getBlock()->getName() << ") false set:\n";
        VRPSolver VRP(VN, IG, UB, VR, PS->DTDFS, PS->modified, Dest);
        VRP.add(ConstantInt::getFalse(), Condition, ICmpInst::ICMP_EQ);
        VRP.solve();
        DEBUG(VN.dump());
        DEBUG(IG.dump());
        DEBUG(VR.dump());
      }

      PS->proceedToSuccessor(*I);
    }
  }

  void PredicateSimplifier::Forwards::visitSwitchInst(SwitchInst &SI) {
    Value *Condition = SI.getCondition();

    // Set the EQProperty in each of the cases BBs, and the NEProperties
    // in the default BB.

    for (DomTreeDFS::Node::iterator I = DTNode->begin(), E = DTNode->end();
         I != E; ++I) {
      BasicBlock *BB = (*I)->getBlock();
      DOUT << "Switch thinking about BB %" << BB->getName()
           << "(" << PS->DTDFS->getNodeForBlock(BB)->getDFSNumIn() << ")\n";

      VRPSolver VRP(VN, IG, UB, VR, PS->DTDFS, PS->modified, BB);
      if (BB == SI.getDefaultDest()) {
        for (unsigned i = 1, e = SI.getNumCases(); i < e; ++i)
          if (SI.getSuccessor(i) != BB)
            VRP.add(Condition, SI.getCaseValue(i), ICmpInst::ICMP_NE);
        VRP.solve();
      } else if (ConstantInt *CI = SI.findCaseDest(BB)) {
        VRP.add(Condition, CI, ICmpInst::ICMP_EQ);
        VRP.solve();
      }
      PS->proceedToSuccessor(*I);
    }
  }

  void PredicateSimplifier::Forwards::visitAllocaInst(AllocaInst &AI) {
    VRPSolver VRP(VN, IG, UB, VR, PS->DTDFS, PS->modified, &AI);
    VRP.add(Constant::getNullValue(AI.getType()), &AI, ICmpInst::ICMP_NE);
    VRP.solve();
  }

  void PredicateSimplifier::Forwards::visitLoadInst(LoadInst &LI) {
    Value *Ptr = LI.getPointerOperand();
    // avoid "load uint* null" -> null NE null.
    if (isa<Constant>(Ptr)) return;

    VRPSolver VRP(VN, IG, UB, VR, PS->DTDFS, PS->modified, &LI);
    VRP.add(Constant::getNullValue(Ptr->getType()), Ptr, ICmpInst::ICMP_NE);
    VRP.solve();
  }

  void PredicateSimplifier::Forwards::visitStoreInst(StoreInst &SI) {
    Value *Ptr = SI.getPointerOperand();
    if (isa<Constant>(Ptr)) return;

    VRPSolver VRP(VN, IG, UB, VR, PS->DTDFS, PS->modified, &SI);
    VRP.add(Constant::getNullValue(Ptr->getType()), Ptr, ICmpInst::ICMP_NE);
    VRP.solve();
  }

  void PredicateSimplifier::Forwards::visitSExtInst(SExtInst &SI) {
    VRPSolver VRP(VN, IG, UB, VR, PS->DTDFS, PS->modified, &SI);
    uint32_t SrcBitWidth = cast<IntegerType>(SI.getSrcTy())->getBitWidth();
    uint32_t DstBitWidth = cast<IntegerType>(SI.getDestTy())->getBitWidth();
    APInt Min(APInt::getHighBitsSet(DstBitWidth, DstBitWidth-SrcBitWidth+1));
    APInt Max(APInt::getLowBitsSet(DstBitWidth, SrcBitWidth-1));
    VRP.add(ConstantInt::get(Min), &SI, ICmpInst::ICMP_SLE);
    VRP.add(ConstantInt::get(Max), &SI, ICmpInst::ICMP_SGE);
    VRP.solve();
  }

  void PredicateSimplifier::Forwards::visitZExtInst(ZExtInst &ZI) {
    VRPSolver VRP(VN, IG, UB, VR, PS->DTDFS, PS->modified, &ZI);
    uint32_t SrcBitWidth = cast<IntegerType>(ZI.getSrcTy())->getBitWidth();
    uint32_t DstBitWidth = cast<IntegerType>(ZI.getDestTy())->getBitWidth();
    APInt Max(APInt::getLowBitsSet(DstBitWidth, SrcBitWidth));
    VRP.add(ConstantInt::get(Max), &ZI, ICmpInst::ICMP_UGE);
    VRP.solve();
  }

  void PredicateSimplifier::Forwards::visitBinaryOperator(BinaryOperator &BO) {
    Instruction::BinaryOps ops = BO.getOpcode();

    switch (ops) {
    default: break;
      case Instruction::URem:
      case Instruction::SRem:
      case Instruction::UDiv:
      case Instruction::SDiv: {
        Value *Divisor = BO.getOperand(1);
        VRPSolver VRP(VN, IG, UB, VR, PS->DTDFS, PS->modified, &BO);
        VRP.add(Constant::getNullValue(Divisor->getType()), Divisor,
                ICmpInst::ICMP_NE);
        VRP.solve();
        break;
      }
    }

    switch (ops) {
      default: break;
      case Instruction::Shl: {
        VRPSolver VRP(VN, IG, UB, VR, PS->DTDFS, PS->modified, &BO);
        VRP.add(&BO, BO.getOperand(0), ICmpInst::ICMP_UGE);
        VRP.solve();
      } break;
      case Instruction::AShr: {
        VRPSolver VRP(VN, IG, UB, VR, PS->DTDFS, PS->modified, &BO);
        VRP.add(&BO, BO.getOperand(0), ICmpInst::ICMP_SLE);
        VRP.solve();
      } break;
      case Instruction::LShr:
      case Instruction::UDiv: {
        VRPSolver VRP(VN, IG, UB, VR, PS->DTDFS, PS->modified, &BO);
        VRP.add(&BO, BO.getOperand(0), ICmpInst::ICMP_ULE);
        VRP.solve();
      } break;
      case Instruction::URem: {
        VRPSolver VRP(VN, IG, UB, VR, PS->DTDFS, PS->modified, &BO);
        VRP.add(&BO, BO.getOperand(1), ICmpInst::ICMP_ULE);
        VRP.solve();
      } break;
      case Instruction::And: {
        VRPSolver VRP(VN, IG, UB, VR, PS->DTDFS, PS->modified, &BO);
        VRP.add(&BO, BO.getOperand(0), ICmpInst::ICMP_ULE);
        VRP.add(&BO, BO.getOperand(1), ICmpInst::ICMP_ULE);
        VRP.solve();
      } break;
      case Instruction::Or: {
        VRPSolver VRP(VN, IG, UB, VR, PS->DTDFS, PS->modified, &BO);
        VRP.add(&BO, BO.getOperand(0), ICmpInst::ICMP_UGE);
        VRP.add(&BO, BO.getOperand(1), ICmpInst::ICMP_UGE);
        VRP.solve();
      } break;
    }
  }

  void PredicateSimplifier::Forwards::visitICmpInst(ICmpInst &IC) {
    // If possible, squeeze the ICmp predicate into something simpler.
    // Eg., if x = [0, 4) and we're being asked icmp uge %x, 3 then change
    // the predicate to eq.

    // XXX: once we do full PHI handling, modifying the instruction in the
    // Forwards visitor will cause missed optimizations.

    ICmpInst::Predicate Pred = IC.getPredicate();

    switch (Pred) {
      default: break;
      case ICmpInst::ICMP_ULE: Pred = ICmpInst::ICMP_ULT; break;
      case ICmpInst::ICMP_UGE: Pred = ICmpInst::ICMP_UGT; break;
      case ICmpInst::ICMP_SLE: Pred = ICmpInst::ICMP_SLT; break;
      case ICmpInst::ICMP_SGE: Pred = ICmpInst::ICMP_SGT; break;
    }
    if (Pred != IC.getPredicate()) {
      VRPSolver VRP(VN, IG, UB, VR, PS->DTDFS, PS->modified, &IC);
      if (VRP.isRelatedBy(IC.getOperand(1), IC.getOperand(0),
                          ICmpInst::ICMP_NE)) {
        ++NumSnuggle;
        PS->modified = true;
        IC.setPredicate(Pred);
      }
    }

    Pred = IC.getPredicate();

    if (ConstantInt *Op1 = dyn_cast<ConstantInt>(IC.getOperand(1))) {
      ConstantInt *NextVal = 0;
      switch (Pred) {
        default: break;
        case ICmpInst::ICMP_SLT:
        case ICmpInst::ICMP_ULT:
          if (Op1->getValue() != 0)
            NextVal = ConstantInt::get(Op1->getValue()-1);
         break;
        case ICmpInst::ICMP_SGT:
        case ICmpInst::ICMP_UGT:
          if (!Op1->getValue().isAllOnesValue())
            NextVal = ConstantInt::get(Op1->getValue()+1);
         break;

      }
      if (NextVal) {
        VRPSolver VRP(VN, IG, UB, VR, PS->DTDFS, PS->modified, &IC);
        if (VRP.isRelatedBy(IC.getOperand(0), NextVal,
                            ICmpInst::getInversePredicate(Pred))) {
          ICmpInst *NewIC = new ICmpInst(ICmpInst::ICMP_EQ, IC.getOperand(0),
                                         NextVal, "", &IC);
          NewIC->takeName(&IC);
          IC.replaceAllUsesWith(NewIC);

          // XXX: prove this isn't necessary
          if (unsigned n = VN.valueNumber(&IC, PS->DTDFS->getRootNode()))
            if (VN.value(n) == &IC) IG.remove(n);
          VN.remove(&IC);

          IC.eraseFromParent();
          ++NumSnuggle;
          PS->modified = true;
        }
      }
    }
  }

  char PredicateSimplifier::ID = 0;
  RegisterPass<PredicateSimplifier> X("predsimplify",
                                      "Predicate Simplifier");
}

FunctionPass *llvm::createPredicateSimplifierPass() {
  return new PredicateSimplifier();
}
