//===-- SelectionDAG.cpp - Implement the SelectionDAG data structures -----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This implements the SelectionDAG class.
//
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/Constants.h"
#include "llvm/GlobalValue.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Target/MRegisterInfo.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include <iostream>
#include <set>
#include <cmath>
#include <algorithm>
using namespace llvm;

// Temporary boolean for testing the dag combiner
namespace llvm {
  extern bool CombinerEnabled;
}

static bool isCommutativeBinOp(unsigned Opcode) {
  switch (Opcode) {
  case ISD::ADD:
  case ISD::MUL:
  case ISD::FADD:
  case ISD::FMUL:
  case ISD::AND:
  case ISD::OR:
  case ISD::XOR: return true;
  default: return false; // FIXME: Need commutative info for user ops!
  }
}

static bool isAssociativeBinOp(unsigned Opcode) {
  switch (Opcode) {
  case ISD::ADD:
  case ISD::MUL:
  case ISD::AND:
  case ISD::OR:
  case ISD::XOR: return true;
  default: return false; // FIXME: Need associative info for user ops!
  }
}

// isInvertibleForFree - Return true if there is no cost to emitting the logical
// inverse of this node.
static bool isInvertibleForFree(SDOperand N) {
  if (isa<ConstantSDNode>(N.Val)) return true;
  if (N.Val->getOpcode() == ISD::SETCC && N.Val->hasOneUse())
    return true;
  return false;
}

//===----------------------------------------------------------------------===//
//                              ConstantFPSDNode Class
//===----------------------------------------------------------------------===//

/// isExactlyValue - We don't rely on operator== working on double values, as
/// it returns true for things that are clearly not equal, like -0.0 and 0.0.
/// As such, this method can be used to do an exact bit-for-bit comparison of
/// two floating point values.
bool ConstantFPSDNode::isExactlyValue(double V) const {
  return DoubleToBits(V) == DoubleToBits(Value);
}

//===----------------------------------------------------------------------===//
//                              ISD Class
//===----------------------------------------------------------------------===//

/// getSetCCSwappedOperands - Return the operation corresponding to (Y op X)
/// when given the operation for (X op Y).
ISD::CondCode ISD::getSetCCSwappedOperands(ISD::CondCode Operation) {
  // To perform this operation, we just need to swap the L and G bits of the
  // operation.
  unsigned OldL = (Operation >> 2) & 1;
  unsigned OldG = (Operation >> 1) & 1;
  return ISD::CondCode((Operation & ~6) |  // Keep the N, U, E bits
                       (OldL << 1) |       // New G bit
                       (OldG << 2));        // New L bit.
}

/// getSetCCInverse - Return the operation corresponding to !(X op Y), where
/// 'op' is a valid SetCC operation.
ISD::CondCode ISD::getSetCCInverse(ISD::CondCode Op, bool isInteger) {
  unsigned Operation = Op;
  if (isInteger)
    Operation ^= 7;   // Flip L, G, E bits, but not U.
  else
    Operation ^= 15;  // Flip all of the condition bits.
  if (Operation > ISD::SETTRUE2)
    Operation &= ~8;     // Don't let N and U bits get set.
  return ISD::CondCode(Operation);
}


/// isSignedOp - For an integer comparison, return 1 if the comparison is a
/// signed operation and 2 if the result is an unsigned comparison.  Return zero
/// if the operation does not depend on the sign of the input (setne and seteq).
static int isSignedOp(ISD::CondCode Opcode) {
  switch (Opcode) {
  default: assert(0 && "Illegal integer setcc operation!");
  case ISD::SETEQ:
  case ISD::SETNE: return 0;
  case ISD::SETLT:
  case ISD::SETLE:
  case ISD::SETGT:
  case ISD::SETGE: return 1;
  case ISD::SETULT:
  case ISD::SETULE:
  case ISD::SETUGT:
  case ISD::SETUGE: return 2;
  }
}

/// getSetCCOrOperation - Return the result of a logical OR between different
/// comparisons of identical values: ((X op1 Y) | (X op2 Y)).  This function
/// returns SETCC_INVALID if it is not possible to represent the resultant
/// comparison.
ISD::CondCode ISD::getSetCCOrOperation(ISD::CondCode Op1, ISD::CondCode Op2,
                                       bool isInteger) {
  if (isInteger && (isSignedOp(Op1) | isSignedOp(Op2)) == 3)
    // Cannot fold a signed integer setcc with an unsigned integer setcc.
    return ISD::SETCC_INVALID;

  unsigned Op = Op1 | Op2;  // Combine all of the condition bits.

  // If the N and U bits get set then the resultant comparison DOES suddenly
  // care about orderedness, and is true when ordered.
  if (Op > ISD::SETTRUE2)
    Op &= ~16;     // Clear the N bit.
  return ISD::CondCode(Op);
}

/// getSetCCAndOperation - Return the result of a logical AND between different
/// comparisons of identical values: ((X op1 Y) & (X op2 Y)).  This
/// function returns zero if it is not possible to represent the resultant
/// comparison.
ISD::CondCode ISD::getSetCCAndOperation(ISD::CondCode Op1, ISD::CondCode Op2,
                                        bool isInteger) {
  if (isInteger && (isSignedOp(Op1) | isSignedOp(Op2)) == 3)
    // Cannot fold a signed setcc with an unsigned setcc.
    return ISD::SETCC_INVALID;

  // Combine all of the condition bits.
  return ISD::CondCode(Op1 & Op2);
}

const TargetMachine &SelectionDAG::getTarget() const {
  return TLI.getTargetMachine();
}

//===----------------------------------------------------------------------===//
//                              SelectionDAG Class
//===----------------------------------------------------------------------===//

/// RemoveDeadNodes - This method deletes all unreachable nodes in the
/// SelectionDAG, including nodes (like loads) that have uses of their token
/// chain but no other uses and no side effect.  If a node is passed in as an
/// argument, it is used as the seed for node deletion.
void SelectionDAG::RemoveDeadNodes(SDNode *N) {
  std::set<SDNode*> AllNodeSet(AllNodes.begin(), AllNodes.end());

  // Create a dummy node (which is not added to allnodes), that adds a reference
  // to the root node, preventing it from being deleted.
  HandleSDNode Dummy(getRoot());

  // If we have a hint to start from, use it.
  if (N) DeleteNodeIfDead(N, &AllNodeSet);

 Restart:
  unsigned NumNodes = AllNodeSet.size();
  for (std::set<SDNode*>::iterator I = AllNodeSet.begin(), E = AllNodeSet.end();
       I != E; ++I) {
    // Try to delete this node.
    DeleteNodeIfDead(*I, &AllNodeSet);

    // If we actually deleted any nodes, do not use invalid iterators in
    // AllNodeSet.
    if (AllNodeSet.size() != NumNodes)
      goto Restart;
  }

  // Restore AllNodes.
  if (AllNodes.size() != NumNodes)
    AllNodes.assign(AllNodeSet.begin(), AllNodeSet.end());

  // If the root changed (e.g. it was a dead load, update the root).
  setRoot(Dummy.getValue());
}


void SelectionDAG::DeleteNodeIfDead(SDNode *N, void *NodeSet) {
  if (!N->use_empty())
    return;

  // Okay, we really are going to delete this node.  First take this out of the
  // appropriate CSE map.
  RemoveNodeFromCSEMaps(N);
  
  // Next, brutally remove the operand list.  This is safe to do, as there are
  // no cycles in the graph.
  while (!N->Operands.empty()) {
    SDNode *O = N->Operands.back().Val;
    N->Operands.pop_back();
    O->removeUser(N);
    
    // Now that we removed this operand, see if there are no uses of it left.
    DeleteNodeIfDead(O, NodeSet);
  }
  
  // Remove the node from the nodes set and delete it.
  std::set<SDNode*> &AllNodeSet = *(std::set<SDNode*>*)NodeSet;
  AllNodeSet.erase(N);
  
  // Now that the node is gone, check to see if any of the operands of this node
  // are dead now.
  delete N;  
}

void SelectionDAG::DeleteNode(SDNode *N) {
  assert(N->use_empty() && "Cannot delete a node that is not dead!");

  // First take this out of the appropriate CSE map.
  RemoveNodeFromCSEMaps(N);

  // Finally, remove uses due to operands of this node, remove from the 
  // AllNodes list, and delete the node.
  DeleteNodeNotInCSEMaps(N);
}

void SelectionDAG::DeleteNodeNotInCSEMaps(SDNode *N) {

  // Remove it from the AllNodes list.
  for (std::vector<SDNode*>::iterator I = AllNodes.begin(); ; ++I) {
    assert(I != AllNodes.end() && "Node not in AllNodes list??");
    if (*I == N) {
      // Erase from the vector, which is not ordered.
      std::swap(*I, AllNodes.back());
      AllNodes.pop_back();
      break;
    }
  }
    
  // Drop all of the operands and decrement used nodes use counts.
  while (!N->Operands.empty()) {
    SDNode *O = N->Operands.back().Val;
    N->Operands.pop_back();
    O->removeUser(N);
  }
  
  delete N;
}

/// RemoveNodeFromCSEMaps - Take the specified node out of the CSE map that
/// correspond to it.  This is useful when we're about to delete or repurpose
/// the node.  We don't want future request for structurally identical nodes
/// to return N anymore.
void SelectionDAG::RemoveNodeFromCSEMaps(SDNode *N) {
  bool Erased = false;
  switch (N->getOpcode()) {
  case ISD::HANDLENODE: return;  // noop.
  case ISD::Constant:
    Erased = Constants.erase(std::make_pair(cast<ConstantSDNode>(N)->getValue(),
                                            N->getValueType(0)));
    break;
  case ISD::TargetConstant:
    Erased = TargetConstants.erase(std::make_pair(
                                    cast<ConstantSDNode>(N)->getValue(),
                                                  N->getValueType(0)));
    break;
  case ISD::ConstantFP: {
    uint64_t V = DoubleToBits(cast<ConstantFPSDNode>(N)->getValue());
    Erased = ConstantFPs.erase(std::make_pair(V, N->getValueType(0)));
    break;
  }
  case ISD::CONDCODE:
    assert(CondCodeNodes[cast<CondCodeSDNode>(N)->get()] &&
           "Cond code doesn't exist!");
    Erased = CondCodeNodes[cast<CondCodeSDNode>(N)->get()] != 0;
    CondCodeNodes[cast<CondCodeSDNode>(N)->get()] = 0;
    break;
  case ISD::GlobalAddress:
    Erased = GlobalValues.erase(cast<GlobalAddressSDNode>(N)->getGlobal());
    break;
  case ISD::TargetGlobalAddress:
    Erased =TargetGlobalValues.erase(cast<GlobalAddressSDNode>(N)->getGlobal());
    break;
  case ISD::FrameIndex:
    Erased = FrameIndices.erase(cast<FrameIndexSDNode>(N)->getIndex());
    break;
  case ISD::TargetFrameIndex:
    Erased = TargetFrameIndices.erase(cast<FrameIndexSDNode>(N)->getIndex());
    break;
  case ISD::ConstantPool:
    Erased = ConstantPoolIndices.erase(cast<ConstantPoolSDNode>(N)->get());
    break;
  case ISD::TargetConstantPool:
    Erased =TargetConstantPoolIndices.erase(cast<ConstantPoolSDNode>(N)->get());
    break;
  case ISD::BasicBlock:
    Erased = BBNodes.erase(cast<BasicBlockSDNode>(N)->getBasicBlock());
    break;
  case ISD::ExternalSymbol:
    Erased = ExternalSymbols.erase(cast<ExternalSymbolSDNode>(N)->getSymbol());
    break;
  case ISD::VALUETYPE:
    Erased = ValueTypeNodes[cast<VTSDNode>(N)->getVT()] != 0;
    ValueTypeNodes[cast<VTSDNode>(N)->getVT()] = 0;
    break;
  case ISD::Register:
    Erased = RegNodes.erase(std::make_pair(cast<RegisterSDNode>(N)->getReg(),
                                           N->getValueType(0)));
    break;
  case ISD::SRCVALUE: {
    SrcValueSDNode *SVN = cast<SrcValueSDNode>(N);
    Erased =ValueNodes.erase(std::make_pair(SVN->getValue(), SVN->getOffset()));
    break;
  }    
  case ISD::LOAD:
    Erased = Loads.erase(std::make_pair(N->getOperand(1),
                                        std::make_pair(N->getOperand(0),
                                                       N->getValueType(0))));
    break;
  default:
    if (N->getNumValues() == 1) {
      if (N->getNumOperands() == 0) {
        Erased = NullaryOps.erase(std::make_pair(N->getOpcode(),
                                                 N->getValueType(0)));
      } else if (N->getNumOperands() == 1) {
        Erased = 
          UnaryOps.erase(std::make_pair(N->getOpcode(),
                                        std::make_pair(N->getOperand(0),
                                                       N->getValueType(0))));
      } else if (N->getNumOperands() == 2) {
        Erased = 
          BinaryOps.erase(std::make_pair(N->getOpcode(),
                                         std::make_pair(N->getOperand(0),
                                                        N->getOperand(1))));
      } else { 
        std::vector<SDOperand> Ops(N->op_begin(), N->op_end());
        Erased = 
          OneResultNodes.erase(std::make_pair(N->getOpcode(),
                                              std::make_pair(N->getValueType(0),
                                                             Ops)));
      }
    } else {
      // Remove the node from the ArbitraryNodes map.
      std::vector<MVT::ValueType> RV(N->value_begin(), N->value_end());
      std::vector<SDOperand>     Ops(N->op_begin(), N->op_end());
      Erased =
        ArbitraryNodes.erase(std::make_pair(N->getOpcode(),
                                            std::make_pair(RV, Ops)));
    }
    break;
  }
#ifndef NDEBUG
  // Verify that the node was actually in one of the CSE maps, unless it has a 
  // flag result (which cannot be CSE'd) or is one of the special cases that are
  // not subject to CSE.
  if (!Erased && N->getValueType(N->getNumValues()-1) != MVT::Flag &&
      N->getOpcode() != ISD::CALL && N->getOpcode() != ISD::CALLSEQ_START &&
      N->getOpcode() != ISD::CALLSEQ_END && !N->isTargetOpcode()) {
    
    N->dump();
    assert(0 && "Node is not in map!");
  }
#endif
}

/// AddNonLeafNodeToCSEMaps - Add the specified node back to the CSE maps.  It
/// has been taken out and modified in some way.  If the specified node already
/// exists in the CSE maps, do not modify the maps, but return the existing node
/// instead.  If it doesn't exist, add it and return null.
///
SDNode *SelectionDAG::AddNonLeafNodeToCSEMaps(SDNode *N) {
  assert(N->getNumOperands() && "This is a leaf node!");
  if (N->getOpcode() == ISD::LOAD) {
    SDNode *&L = Loads[std::make_pair(N->getOperand(1),
                                      std::make_pair(N->getOperand(0),
                                                     N->getValueType(0)))];
    if (L) return L;
    L = N;
  } else if (N->getOpcode() == ISD::HANDLENODE) {
    return 0;  // never add it.
  } else if (N->getNumOperands() == 1) {
    SDNode *&U = UnaryOps[std::make_pair(N->getOpcode(),
                                         std::make_pair(N->getOperand(0),
                                                        N->getValueType(0)))];
    if (U) return U;
    U = N;
  } else if (N->getNumOperands() == 2) {
    SDNode *&B = BinaryOps[std::make_pair(N->getOpcode(),
                                          std::make_pair(N->getOperand(0),
                                                         N->getOperand(1)))];
    if (B) return B;
    B = N;
  } else if (N->getNumValues() == 1) {
    std::vector<SDOperand> Ops(N->op_begin(), N->op_end());
    SDNode *&ORN = OneResultNodes[std::make_pair(N->getOpcode(),
                                  std::make_pair(N->getValueType(0), Ops))];
    if (ORN) return ORN;
    ORN = N;
  } else {
    // Remove the node from the ArbitraryNodes map.
    std::vector<MVT::ValueType> RV(N->value_begin(), N->value_end());
    std::vector<SDOperand>     Ops(N->op_begin(), N->op_end());
    SDNode *&AN = ArbitraryNodes[std::make_pair(N->getOpcode(),
                                                std::make_pair(RV, Ops))];
    if (AN) return AN;
    AN = N;
  }
  return 0;
  
}



SelectionDAG::~SelectionDAG() {
  for (unsigned i = 0, e = AllNodes.size(); i != e; ++i)
    delete AllNodes[i];
}

SDOperand SelectionDAG::getZeroExtendInReg(SDOperand Op, MVT::ValueType VT) {
  if (Op.getValueType() == VT) return Op;
  int64_t Imm = ~0ULL >> (64-MVT::getSizeInBits(VT));
  return getNode(ISD::AND, Op.getValueType(), Op,
                 getConstant(Imm, Op.getValueType()));
}

SDOperand SelectionDAG::getConstant(uint64_t Val, MVT::ValueType VT) {
  assert(MVT::isInteger(VT) && "Cannot create FP integer constant!");
  // Mask out any bits that are not valid for this constant.
  if (VT != MVT::i64)
    Val &= ((uint64_t)1 << MVT::getSizeInBits(VT)) - 1;

  SDNode *&N = Constants[std::make_pair(Val, VT)];
  if (N) return SDOperand(N, 0);
  N = new ConstantSDNode(false, Val, VT);
  AllNodes.push_back(N);
  return SDOperand(N, 0);
}

SDOperand SelectionDAG::getTargetConstant(uint64_t Val, MVT::ValueType VT) {
  assert(MVT::isInteger(VT) && "Cannot create FP integer constant!");
  // Mask out any bits that are not valid for this constant.
  if (VT != MVT::i64)
    Val &= ((uint64_t)1 << MVT::getSizeInBits(VT)) - 1;
  
  SDNode *&N = TargetConstants[std::make_pair(Val, VT)];
  if (N) return SDOperand(N, 0);
  N = new ConstantSDNode(true, Val, VT);
  AllNodes.push_back(N);
  return SDOperand(N, 0);
}

SDOperand SelectionDAG::getConstantFP(double Val, MVT::ValueType VT) {
  assert(MVT::isFloatingPoint(VT) && "Cannot create integer FP constant!");
  if (VT == MVT::f32)
    Val = (float)Val;  // Mask out extra precision.

  // Do the map lookup using the actual bit pattern for the floating point
  // value, so that we don't have problems with 0.0 comparing equal to -0.0, and
  // we don't have issues with SNANs.
  SDNode *&N = ConstantFPs[std::make_pair(DoubleToBits(Val), VT)];
  if (N) return SDOperand(N, 0);
  N = new ConstantFPSDNode(Val, VT);
  AllNodes.push_back(N);
  return SDOperand(N, 0);
}



SDOperand SelectionDAG::getGlobalAddress(const GlobalValue *GV,
                                         MVT::ValueType VT) {
  SDNode *&N = GlobalValues[GV];
  if (N) return SDOperand(N, 0);
  N = new GlobalAddressSDNode(false, GV, VT);
  AllNodes.push_back(N);
  return SDOperand(N, 0);
}

SDOperand SelectionDAG::getTargetGlobalAddress(const GlobalValue *GV,
                                               MVT::ValueType VT) {
  SDNode *&N = TargetGlobalValues[GV];
  if (N) return SDOperand(N, 0);
  N = new GlobalAddressSDNode(true, GV, VT);
  AllNodes.push_back(N);
  return SDOperand(N, 0);
}

SDOperand SelectionDAG::getFrameIndex(int FI, MVT::ValueType VT) {
  SDNode *&N = FrameIndices[FI];
  if (N) return SDOperand(N, 0);
  N = new FrameIndexSDNode(FI, VT, false);
  AllNodes.push_back(N);
  return SDOperand(N, 0);
}

SDOperand SelectionDAG::getTargetFrameIndex(int FI, MVT::ValueType VT) {
  SDNode *&N = TargetFrameIndices[FI];
  if (N) return SDOperand(N, 0);
  N = new FrameIndexSDNode(FI, VT, true);
  AllNodes.push_back(N);
  return SDOperand(N, 0);
}

SDOperand SelectionDAG::getConstantPool(Constant *C, MVT::ValueType VT) {
  SDNode *&N = ConstantPoolIndices[C];
  if (N) return SDOperand(N, 0);
  N = new ConstantPoolSDNode(C, VT, false);
  AllNodes.push_back(N);
  return SDOperand(N, 0);
}

SDOperand SelectionDAG::getTargetConstantPool(Constant *C, MVT::ValueType VT) {
  SDNode *&N = TargetConstantPoolIndices[C];
  if (N) return SDOperand(N, 0);
  N = new ConstantPoolSDNode(C, VT, true);
  AllNodes.push_back(N);
  return SDOperand(N, 0);
}

SDOperand SelectionDAG::getBasicBlock(MachineBasicBlock *MBB) {
  SDNode *&N = BBNodes[MBB];
  if (N) return SDOperand(N, 0);
  N = new BasicBlockSDNode(MBB);
  AllNodes.push_back(N);
  return SDOperand(N, 0);
}

SDOperand SelectionDAG::getValueType(MVT::ValueType VT) {
  if ((unsigned)VT >= ValueTypeNodes.size())
    ValueTypeNodes.resize(VT+1);
  if (ValueTypeNodes[VT] == 0) {
    ValueTypeNodes[VT] = new VTSDNode(VT);
    AllNodes.push_back(ValueTypeNodes[VT]);
  }

  return SDOperand(ValueTypeNodes[VT], 0);
}

SDOperand SelectionDAG::getExternalSymbol(const char *Sym, MVT::ValueType VT) {
  SDNode *&N = ExternalSymbols[Sym];
  if (N) return SDOperand(N, 0);
  N = new ExternalSymbolSDNode(Sym, VT);
  AllNodes.push_back(N);
  return SDOperand(N, 0);
}

SDOperand SelectionDAG::getCondCode(ISD::CondCode Cond) {
  if ((unsigned)Cond >= CondCodeNodes.size())
    CondCodeNodes.resize(Cond+1);
  
  if (CondCodeNodes[Cond] == 0) {
    CondCodeNodes[Cond] = new CondCodeSDNode(Cond);
    AllNodes.push_back(CondCodeNodes[Cond]);
  }
  return SDOperand(CondCodeNodes[Cond], 0);
}

SDOperand SelectionDAG::getRegister(unsigned RegNo, MVT::ValueType VT) {
  RegisterSDNode *&Reg = RegNodes[std::make_pair(RegNo, VT)];
  if (!Reg) {
    Reg = new RegisterSDNode(RegNo, VT);
    AllNodes.push_back(Reg);
  }
  return SDOperand(Reg, 0);
}

/// MaskedValueIsZero - Return true if 'V & Mask' is known to be zero.  We use
/// this predicate to simplify operations downstream.  V and Mask are known to
/// be the same type.
static bool MaskedValueIsZero(const SDOperand &Op, uint64_t Mask,
                              const TargetLowering &TLI) {
  unsigned SrcBits;
  if (Mask == 0) return true;
  
  // If we know the result of a setcc has the top bits zero, use this info.
  switch (Op.getOpcode()) {
    case ISD::Constant:
      return (cast<ConstantSDNode>(Op)->getValue() & Mask) == 0;
      
    case ISD::SETCC:
      return ((Mask & 1) == 0) &&
      TLI.getSetCCResultContents() == TargetLowering::ZeroOrOneSetCCResult;
      
    case ISD::ZEXTLOAD:
      SrcBits = MVT::getSizeInBits(cast<VTSDNode>(Op.getOperand(3))->getVT());
      return (Mask & ((1ULL << SrcBits)-1)) == 0; // Returning only the zext bits.
    case ISD::ZERO_EXTEND:
      SrcBits = MVT::getSizeInBits(Op.getOperand(0).getValueType());
      return MaskedValueIsZero(Op.getOperand(0),Mask & ((1ULL << SrcBits)-1),TLI);
    case ISD::AssertZext:
      SrcBits = MVT::getSizeInBits(cast<VTSDNode>(Op.getOperand(1))->getVT());
      return (Mask & ((1ULL << SrcBits)-1)) == 0; // Returning only the zext bits.
    case ISD::AND:
      // (X & C1) & C2 == 0   iff   C1 & C2 == 0.
      if (ConstantSDNode *AndRHS = dyn_cast<ConstantSDNode>(Op.getOperand(1)))
        return MaskedValueIsZero(Op.getOperand(0),AndRHS->getValue() & Mask, TLI);
      
      // FALL THROUGH
    case ISD::OR:
    case ISD::XOR:
      return MaskedValueIsZero(Op.getOperand(0), Mask, TLI) &&
      MaskedValueIsZero(Op.getOperand(1), Mask, TLI);
    case ISD::SELECT:
      return MaskedValueIsZero(Op.getOperand(1), Mask, TLI) &&
      MaskedValueIsZero(Op.getOperand(2), Mask, TLI);
    case ISD::SELECT_CC:
      return MaskedValueIsZero(Op.getOperand(2), Mask, TLI) &&
      MaskedValueIsZero(Op.getOperand(3), Mask, TLI);
    case ISD::SRL:
      // (ushr X, C1) & C2 == 0   iff  X & (C2 << C1) == 0
      if (ConstantSDNode *ShAmt = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
        uint64_t NewVal = Mask << ShAmt->getValue();
        SrcBits = MVT::getSizeInBits(Op.getValueType());
        if (SrcBits != 64) NewVal &= (1ULL << SrcBits)-1;
        return MaskedValueIsZero(Op.getOperand(0), NewVal, TLI);
      }
      return false;
    case ISD::SHL:
      // (ushl X, C1) & C2 == 0   iff  X & (C2 >> C1) == 0
      if (ConstantSDNode *ShAmt = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
        uint64_t NewVal = Mask >> ShAmt->getValue();
        return MaskedValueIsZero(Op.getOperand(0), NewVal, TLI);
      }
      return false;
    case ISD::CTTZ:
    case ISD::CTLZ:
    case ISD::CTPOP:
      // Bit counting instructions can not set the high bits of the result
      // register.  The max number of bits sets depends on the input.
      return (Mask & (MVT::getSizeInBits(Op.getValueType())*2-1)) == 0;
      
      // TODO we could handle some SRA cases here.
    default: break;
  }
  
  return false;
}



SDOperand SelectionDAG::SimplifySetCC(MVT::ValueType VT, SDOperand N1,
                                      SDOperand N2, ISD::CondCode Cond) {
  // These setcc operations always fold.
  switch (Cond) {
  default: break;
  case ISD::SETFALSE:
  case ISD::SETFALSE2: return getConstant(0, VT);
  case ISD::SETTRUE:
  case ISD::SETTRUE2:  return getConstant(1, VT);
  }

  if (ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2.Val)) {
    uint64_t C2 = N2C->getValue();
    if (ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.Val)) {
      uint64_t C1 = N1C->getValue();

      // Sign extend the operands if required
      if (ISD::isSignedIntSetCC(Cond)) {
        C1 = N1C->getSignExtended();
        C2 = N2C->getSignExtended();
      }

      switch (Cond) {
      default: assert(0 && "Unknown integer setcc!");
      case ISD::SETEQ:  return getConstant(C1 == C2, VT);
      case ISD::SETNE:  return getConstant(C1 != C2, VT);
      case ISD::SETULT: return getConstant(C1 <  C2, VT);
      case ISD::SETUGT: return getConstant(C1 >  C2, VT);
      case ISD::SETULE: return getConstant(C1 <= C2, VT);
      case ISD::SETUGE: return getConstant(C1 >= C2, VT);
      case ISD::SETLT:  return getConstant((int64_t)C1 <  (int64_t)C2, VT);
      case ISD::SETGT:  return getConstant((int64_t)C1 >  (int64_t)C2, VT);
      case ISD::SETLE:  return getConstant((int64_t)C1 <= (int64_t)C2, VT);
      case ISD::SETGE:  return getConstant((int64_t)C1 >= (int64_t)C2, VT);
      }
    } else {
      // If the LHS is a ZERO_EXTEND, perform the comparison on the input.
      if (N1.getOpcode() == ISD::ZERO_EXTEND) {
        unsigned InSize = MVT::getSizeInBits(N1.getOperand(0).getValueType());

        // If the comparison constant has bits in the upper part, the
        // zero-extended value could never match.
        if (C2 & (~0ULL << InSize)) {
          unsigned VSize = MVT::getSizeInBits(N1.getValueType());
          switch (Cond) {
          case ISD::SETUGT:
          case ISD::SETUGE:
          case ISD::SETEQ: return getConstant(0, VT);
          case ISD::SETULT:
          case ISD::SETULE:
          case ISD::SETNE: return getConstant(1, VT);
          case ISD::SETGT:
          case ISD::SETGE:
            // True if the sign bit of C2 is set.
            return getConstant((C2 & (1ULL << VSize)) != 0, VT);
          case ISD::SETLT:
          case ISD::SETLE:
            // True if the sign bit of C2 isn't set.
            return getConstant((C2 & (1ULL << VSize)) == 0, VT);
          default:
            break;
          }
        }

        // Otherwise, we can perform the comparison with the low bits.
        switch (Cond) {
        case ISD::SETEQ:
        case ISD::SETNE:
        case ISD::SETUGT:
        case ISD::SETUGE:
        case ISD::SETULT:
        case ISD::SETULE:
          return getSetCC(VT, N1.getOperand(0),
                          getConstant(C2, N1.getOperand(0).getValueType()),
                          Cond);
        default:
          break;   // todo, be more careful with signed comparisons
        }
      } else if (N1.getOpcode() == ISD::SIGN_EXTEND_INREG &&
                 (Cond == ISD::SETEQ || Cond == ISD::SETNE)) {
        MVT::ValueType ExtSrcTy = cast<VTSDNode>(N1.getOperand(1))->getVT();
        unsigned ExtSrcTyBits = MVT::getSizeInBits(ExtSrcTy);
        MVT::ValueType ExtDstTy = N1.getValueType();
        unsigned ExtDstTyBits = MVT::getSizeInBits(ExtDstTy);

        // If the extended part has any inconsistent bits, it cannot ever
        // compare equal.  In other words, they have to be all ones or all
        // zeros.
        uint64_t ExtBits =
          (~0ULL >> (64-ExtSrcTyBits)) & (~0ULL << (ExtDstTyBits-1));
        if ((C2 & ExtBits) != 0 && (C2 & ExtBits) != ExtBits)
          return getConstant(Cond == ISD::SETNE, VT);
        
        // Otherwise, make this a use of a zext.
        return getSetCC(VT, getZeroExtendInReg(N1.getOperand(0), ExtSrcTy),
                        getConstant(C2 & (~0ULL>>(64-ExtSrcTyBits)), ExtDstTy),
                        Cond);
      }

      uint64_t MinVal, MaxVal;
      unsigned OperandBitSize = MVT::getSizeInBits(N2C->getValueType(0));
      if (ISD::isSignedIntSetCC(Cond)) {
        MinVal = 1ULL << (OperandBitSize-1);
        if (OperandBitSize != 1)   // Avoid X >> 64, which is undefined.
          MaxVal = ~0ULL >> (65-OperandBitSize);
        else
          MaxVal = 0;
      } else {
        MinVal = 0;
        MaxVal = ~0ULL >> (64-OperandBitSize);
      }

      // Canonicalize GE/LE comparisons to use GT/LT comparisons.
      if (Cond == ISD::SETGE || Cond == ISD::SETUGE) {
        if (C2 == MinVal) return getConstant(1, VT);   // X >= MIN --> true
        --C2;                                          // X >= C1 --> X > (C1-1)
        return getSetCC(VT, N1, getConstant(C2, N2.getValueType()),
                        (Cond == ISD::SETGE) ? ISD::SETGT : ISD::SETUGT);
      }

      if (Cond == ISD::SETLE || Cond == ISD::SETULE) {
        if (C2 == MaxVal) return getConstant(1, VT);   // X <= MAX --> true
        ++C2;                                          // X <= C1 --> X < (C1+1)
        return getSetCC(VT, N1, getConstant(C2, N2.getValueType()),
                        (Cond == ISD::SETLE) ? ISD::SETLT : ISD::SETULT);
      }

      if ((Cond == ISD::SETLT || Cond == ISD::SETULT) && C2 == MinVal)
        return getConstant(0, VT);      // X < MIN --> false

      // Canonicalize setgt X, Min --> setne X, Min
      if ((Cond == ISD::SETGT || Cond == ISD::SETUGT) && C2 == MinVal)
        return getSetCC(VT, N1, N2, ISD::SETNE);

      // If we have setult X, 1, turn it into seteq X, 0
      if ((Cond == ISD::SETLT || Cond == ISD::SETULT) && C2 == MinVal+1)
        return getSetCC(VT, N1, getConstant(MinVal, N1.getValueType()),
                        ISD::SETEQ);
      // If we have setugt X, Max-1, turn it into seteq X, Max
      else if ((Cond == ISD::SETGT || Cond == ISD::SETUGT) && C2 == MaxVal-1)
        return getSetCC(VT, N1, getConstant(MaxVal, N1.getValueType()),
                        ISD::SETEQ);

      // If we have "setcc X, C1", check to see if we can shrink the immediate
      // by changing cc.

      // SETUGT X, SINTMAX  -> SETLT X, 0
      if (Cond == ISD::SETUGT && OperandBitSize != 1 &&
          C2 == (~0ULL >> (65-OperandBitSize)))
        return getSetCC(VT, N1, getConstant(0, N2.getValueType()), ISD::SETLT);

      // FIXME: Implement the rest of these.


      // Fold bit comparisons when we can.
      if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) &&
          VT == N1.getValueType() && N1.getOpcode() == ISD::AND)
        if (ConstantSDNode *AndRHS =
                    dyn_cast<ConstantSDNode>(N1.getOperand(1))) {
          if (Cond == ISD::SETNE && C2 == 0) {// (X & 8) != 0  -->  (X & 8) >> 3
            // Perform the xform if the AND RHS is a single bit.
            if ((AndRHS->getValue() & (AndRHS->getValue()-1)) == 0) {
              return getNode(ISD::SRL, VT, N1,
                             getConstant(Log2_64(AndRHS->getValue()),
                                                   TLI.getShiftAmountTy()));
            }
          } else if (Cond == ISD::SETEQ && C2 == AndRHS->getValue()) {
            // (X & 8) == 8  -->  (X & 8) >> 3
            // Perform the xform if C2 is a single bit.
            if ((C2 & (C2-1)) == 0) {
              return getNode(ISD::SRL, VT, N1,
                             getConstant(Log2_64(C2),TLI.getShiftAmountTy()));
            }
          }
        }
    }
  } else if (isa<ConstantSDNode>(N1.Val)) {
      // Ensure that the constant occurs on the RHS.
    return getSetCC(VT, N2, N1, ISD::getSetCCSwappedOperands(Cond));
  }

  if (ConstantFPSDNode *N1C = dyn_cast<ConstantFPSDNode>(N1.Val))
    if (ConstantFPSDNode *N2C = dyn_cast<ConstantFPSDNode>(N2.Val)) {
      double C1 = N1C->getValue(), C2 = N2C->getValue();

      switch (Cond) {
      default: break; // FIXME: Implement the rest of these!
      case ISD::SETEQ:  return getConstant(C1 == C2, VT);
      case ISD::SETNE:  return getConstant(C1 != C2, VT);
      case ISD::SETLT:  return getConstant(C1 < C2, VT);
      case ISD::SETGT:  return getConstant(C1 > C2, VT);
      case ISD::SETLE:  return getConstant(C1 <= C2, VT);
      case ISD::SETGE:  return getConstant(C1 >= C2, VT);
      }
    } else {
      // Ensure that the constant occurs on the RHS.
      return getSetCC(VT, N2, N1, ISD::getSetCCSwappedOperands(Cond));
    }

  if (!CombinerEnabled) {
  if (N1 == N2) {
    // We can always fold X == Y for integer setcc's.
    if (MVT::isInteger(N1.getValueType()))
      return getConstant(ISD::isTrueWhenEqual(Cond), VT);
    unsigned UOF = ISD::getUnorderedFlavor(Cond);
    if (UOF == 2)   // FP operators that are undefined on NaNs.
      return getConstant(ISD::isTrueWhenEqual(Cond), VT);
    if (UOF == unsigned(ISD::isTrueWhenEqual(Cond)))
      return getConstant(UOF, VT);
    // Otherwise, we can't fold it.  However, we can simplify it to SETUO/SETO
    // if it is not already.
    ISD::CondCode NewCond = UOF == 0 ? ISD::SETUO : ISD::SETO;
    if (NewCond != Cond)
      return getSetCC(VT, N1, N2, NewCond);
  }

  if (Cond == ISD::SETEQ || Cond == ISD::SETNE) {
    if (N1.getOpcode() == ISD::ADD || N1.getOpcode() == ISD::SUB ||
        N1.getOpcode() == ISD::XOR) {
      // Simplify (X+Y) == (X+Z) -->  Y == Z
      if (N1.getOpcode() == N2.getOpcode()) {
        if (N1.getOperand(0) == N2.getOperand(0))
          return getSetCC(VT, N1.getOperand(1), N2.getOperand(1), Cond);
        if (N1.getOperand(1) == N2.getOperand(1))
          return getSetCC(VT, N1.getOperand(0), N2.getOperand(0), Cond);
        if (isCommutativeBinOp(N1.getOpcode())) {
          // If X op Y == Y op X, try other combinations.
          if (N1.getOperand(0) == N2.getOperand(1))
            return getSetCC(VT, N1.getOperand(1), N2.getOperand(0), Cond);
          if (N1.getOperand(1) == N2.getOperand(0))
            return getSetCC(VT, N1.getOperand(1), N2.getOperand(1), Cond);
        }
      }

      // FIXME: move this stuff to the DAG Combiner when it exists!

      // Turn (X^C1) == C2 into X == C1^C2 iff X&~C1 = 0.  Common for condcodes.
      if (N1.getOpcode() == ISD::XOR)
        if (ConstantSDNode *XORC = dyn_cast<ConstantSDNode>(N1.getOperand(1)))
          if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(N2)) {
            // If we know that all of the inverted bits are zero, don't bother
            // performing the inversion.
            if (MaskedValueIsZero(N1.getOperand(0), ~XORC->getValue(), TLI))
              return getSetCC(VT, N1.getOperand(0),
                              getConstant(XORC->getValue()^RHSC->getValue(),
                                          N1.getValueType()), Cond);
          }
      
      // Simplify (X+Z) == X -->  Z == 0
      if (N1.getOperand(0) == N2)
        return getSetCC(VT, N1.getOperand(1),
                        getConstant(0, N1.getValueType()), Cond);
      if (N1.getOperand(1) == N2) {
        if (isCommutativeBinOp(N1.getOpcode()))
          return getSetCC(VT, N1.getOperand(0),
                          getConstant(0, N1.getValueType()), Cond);
        else {
          assert(N1.getOpcode() == ISD::SUB && "Unexpected operation!");
          // (Z-X) == X  --> Z == X<<1
          return getSetCC(VT, N1.getOperand(0),
                          getNode(ISD::SHL, N2.getValueType(),
                                  N2, getConstant(1, TLI.getShiftAmountTy())),
                          Cond);
        }
      }
    }

    if (N2.getOpcode() == ISD::ADD || N2.getOpcode() == ISD::SUB ||
        N2.getOpcode() == ISD::XOR) {
      // Simplify  X == (X+Z) -->  Z == 0
      if (N2.getOperand(0) == N1) {
        return getSetCC(VT, N2.getOperand(1),
                        getConstant(0, N2.getValueType()), Cond);
      } else if (N2.getOperand(1) == N1) {
        if (isCommutativeBinOp(N2.getOpcode())) {
          return getSetCC(VT, N2.getOperand(0),
                          getConstant(0, N2.getValueType()), Cond);
        } else {
          assert(N2.getOpcode() == ISD::SUB && "Unexpected operation!");
          // X == (Z-X)  --> X<<1 == Z
          return getSetCC(VT, getNode(ISD::SHL, N2.getValueType(), N1, 
                                      getConstant(1, TLI.getShiftAmountTy())),
                          N2.getOperand(0), Cond);
        }
      }
    }
  }

  // Fold away ALL boolean setcc's.
  if (N1.getValueType() == MVT::i1) {
    switch (Cond) {
    default: assert(0 && "Unknown integer setcc!");
    case ISD::SETEQ:  // X == Y  -> (X^Y)^1
      N1 = getNode(ISD::XOR, MVT::i1,
                   getNode(ISD::XOR, MVT::i1, N1, N2),
                   getConstant(1, MVT::i1));
      break;
    case ISD::SETNE:  // X != Y   -->  (X^Y)
      N1 = getNode(ISD::XOR, MVT::i1, N1, N2);
      break;
    case ISD::SETGT:  // X >s Y   -->  X == 0 & Y == 1  -->  X^1 & Y
    case ISD::SETULT: // X <u Y   -->  X == 0 & Y == 1  -->  X^1 & Y
      N1 = getNode(ISD::AND, MVT::i1, N2,
                   getNode(ISD::XOR, MVT::i1, N1, getConstant(1, MVT::i1)));
      break;
    case ISD::SETLT:  // X <s Y   --> X == 1 & Y == 0  -->  Y^1 & X
    case ISD::SETUGT: // X >u Y   --> X == 1 & Y == 0  -->  Y^1 & X
      N1 = getNode(ISD::AND, MVT::i1, N1,
                   getNode(ISD::XOR, MVT::i1, N2, getConstant(1, MVT::i1)));
      break;
    case ISD::SETULE: // X <=u Y  --> X == 0 | Y == 1  -->  X^1 | Y
    case ISD::SETGE:  // X >=s Y  --> X == 0 | Y == 1  -->  X^1 | Y
      N1 = getNode(ISD::OR, MVT::i1, N2,
                   getNode(ISD::XOR, MVT::i1, N1, getConstant(1, MVT::i1)));
      break;
    case ISD::SETUGE: // X >=u Y  --> X == 1 | Y == 0  -->  Y^1 | X
    case ISD::SETLE:  // X <=s Y  --> X == 1 | Y == 0  -->  Y^1 | X
      N1 = getNode(ISD::OR, MVT::i1, N1,
                   getNode(ISD::XOR, MVT::i1, N2, getConstant(1, MVT::i1)));
      break;
    }
    if (VT != MVT::i1)
      N1 = getNode(ISD::ZERO_EXTEND, VT, N1);
    return N1;
  }
  }
  // Could not fold it.
  return SDOperand();
}

SDOperand SelectionDAG::SimplifySelectCC(SDOperand N1, SDOperand N2, 
                                         SDOperand N3, SDOperand N4, 
                                         ISD::CondCode CC) {
  MVT::ValueType VT = N3.getValueType();
  ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.Val);
  ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2.Val);
  ConstantSDNode *N3C = dyn_cast<ConstantSDNode>(N3.Val);
  ConstantSDNode *N4C = dyn_cast<ConstantSDNode>(N4.Val);
  
  // Check to see if we can simplify the select into an fabs node
  if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(N2)) {
    // Allow either -0.0 or 0.0
    if (CFP->getValue() == 0.0) {
      // select (setg[te] X, +/-0.0), X, fneg(X) -> fabs
      if ((CC == ISD::SETGE || CC == ISD::SETGT) &&
          N1 == N3 && N4.getOpcode() == ISD::FNEG &&
          N1 == N4.getOperand(0))
        return getNode(ISD::FABS, VT, N1);
      
      // select (setl[te] X, +/-0.0), fneg(X), X -> fabs
      if ((CC == ISD::SETLT || CC == ISD::SETLE) &&
          N1 == N4 && N3.getOpcode() == ISD::FNEG &&
          N3.getOperand(0) == N4)
        return getNode(ISD::FABS, VT, N4);
    }
  }
  
  // check to see if we're select_cc'ing a select_cc.
  // this allows us to turn:
  // select_cc set[eq,ne] (select_cc cc, lhs, rhs, 1, 0), 0, true, false ->
  // select_cc cc, lhs, rhs, true, false
  if ((N1C && N1C->isNullValue() && N2.getOpcode() == ISD::SELECT_CC) ||
      (N2C && N2C->isNullValue() && N1.getOpcode() == ISD::SELECT_CC) &&
      (CC == ISD::SETEQ || CC == ISD::SETNE)) {
    SDOperand SCC = N1C ? N2 : N1;
    ConstantSDNode *SCCT = dyn_cast<ConstantSDNode>(SCC.getOperand(2));
    ConstantSDNode *SCCF = dyn_cast<ConstantSDNode>(SCC.getOperand(3));
    if (SCCT && SCCF && SCCF->isNullValue() && SCCT->getValue() == 1ULL) {
      if (CC == ISD::SETEQ) std::swap(N3, N4);
      return getNode(ISD::SELECT_CC, N3.getValueType(), SCC.getOperand(0), 
                     SCC.getOperand(1), N3, N4, SCC.getOperand(4));
    }
  }
      
  // Check to see if we can perform the "gzip trick", transforming
  // select_cc setlt X, 0, A, 0 -> and (sra X, size(X)-1), A
  if (N2C && N2C->isNullValue() && N4C && N4C->isNullValue() &&
      MVT::isInteger(N1.getValueType()) && 
      MVT::isInteger(N3.getValueType()) && CC == ISD::SETLT) {
    MVT::ValueType XType = N1.getValueType();
    MVT::ValueType AType = N3.getValueType();
    if (XType >= AType) {
      // and (sra X, size(X)-1, A) -> "and (srl X, C2), A" iff A is a
      // single-bit constant.  FIXME: remove once the dag combiner
      // exists.
      if (N3C && ((N3C->getValue() & (N3C->getValue()-1)) == 0)) {
        unsigned ShCtV = Log2_64(N3C->getValue());
        ShCtV = MVT::getSizeInBits(XType)-ShCtV-1;
        SDOperand ShCt = getConstant(ShCtV, TLI.getShiftAmountTy());
        SDOperand Shift = getNode(ISD::SRL, XType, N1, ShCt);
        if (XType > AType)
          Shift = getNode(ISD::TRUNCATE, AType, Shift);
        return getNode(ISD::AND, AType, Shift, N3);
      }
      SDOperand Shift = getNode(ISD::SRA, XType, N1,
                                getConstant(MVT::getSizeInBits(XType)-1,
                                            TLI.getShiftAmountTy()));
      if (XType > AType)
        Shift = getNode(ISD::TRUNCATE, AType, Shift);
      return getNode(ISD::AND, AType, Shift, N3);
    }
  }
  
  // Check to see if this is the equivalent of setcc
  if (N4C && N4C->isNullValue() && N3C && (N3C->getValue() == 1ULL)) {
    MVT::ValueType XType = N1.getValueType();
    if (TLI.isOperationLegal(ISD::SETCC, TLI.getSetCCResultTy())) {
      SDOperand Res = getSetCC(TLI.getSetCCResultTy(), N1, N2, CC);
      if (Res.getValueType() != VT)
        Res = getNode(ISD::ZERO_EXTEND, VT, Res);
      return Res;
    }

    // seteq X, 0 -> srl (ctlz X, log2(size(X)))
    if (N2C && N2C->isNullValue() && CC == ISD::SETEQ && 
        TLI.isOperationLegal(ISD::CTLZ, XType)) {
      SDOperand Ctlz = getNode(ISD::CTLZ, XType, N1);
      return getNode(ISD::SRL, XType, Ctlz, 
                     getConstant(Log2_32(MVT::getSizeInBits(XType)),
                                 TLI.getShiftAmountTy()));
    }
    // setgt X, 0 -> srl (and (-X, ~X), size(X)-1)
    if (N2C && N2C->isNullValue() && CC == ISD::SETGT) { 
      SDOperand NegN1 = getNode(ISD::SUB, XType, getConstant(0, XType), N1);
      SDOperand NotN1 = getNode(ISD::XOR, XType, N1, getConstant(~0ULL, XType));
      return getNode(ISD::SRL, XType, getNode(ISD::AND, XType, NegN1, NotN1),
                     getConstant(MVT::getSizeInBits(XType)-1,
                                 TLI.getShiftAmountTy()));
    }
    // setgt X, -1 -> xor (srl (X, size(X)-1), 1)
    if (N2C && N2C->isAllOnesValue() && CC == ISD::SETGT) {
      SDOperand Sign = getNode(ISD::SRL, XType, N1,
                               getConstant(MVT::getSizeInBits(XType)-1,
                                           TLI.getShiftAmountTy()));
      return getNode(ISD::XOR, XType, Sign, getConstant(1, XType));
    }
  }

  // Check to see if this is an integer abs. select_cc setl[te] X, 0, -X, X ->
  // Y = sra (X, size(X)-1); xor (add (X, Y), Y)
  if (N2C && N2C->isNullValue() && (CC == ISD::SETLT || CC == ISD::SETLE) &&
      N1 == N4 && N3.getOpcode() == ISD::SUB && N1 == N3.getOperand(1)) {
    if (ConstantSDNode *SubC = dyn_cast<ConstantSDNode>(N3.getOperand(0))) {
      MVT::ValueType XType = N1.getValueType();
      if (SubC->isNullValue() && MVT::isInteger(XType)) {
        SDOperand Shift = getNode(ISD::SRA, XType, N1,
                                  getConstant(MVT::getSizeInBits(XType)-1,
                                              TLI.getShiftAmountTy()));
        return getNode(ISD::XOR, XType, getNode(ISD::ADD, XType, N1, Shift), 
                       Shift);
      }
    }
  }
  
  // Could not fold it.
  return SDOperand();
}

/// getNode - Gets or creates the specified node.
///
SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT) {
  SDNode *&N = NullaryOps[std::make_pair(Opcode, VT)];
  if (!N) {
    N = new SDNode(Opcode, VT);
    AllNodes.push_back(N);
  }
  return SDOperand(N, 0);
}

SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
                                SDOperand Operand) {
  if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Operand.Val)) {
    uint64_t Val = C->getValue();
    switch (Opcode) {
    default: break;
    case ISD::SIGN_EXTEND: return getConstant(C->getSignExtended(), VT);
    case ISD::ANY_EXTEND:
    case ISD::ZERO_EXTEND: return getConstant(Val, VT);
    case ISD::TRUNCATE:    return getConstant(Val, VT);
    case ISD::SINT_TO_FP:  return getConstantFP(C->getSignExtended(), VT);
    case ISD::UINT_TO_FP:  return getConstantFP(C->getValue(), VT);
    }
  }

  if (ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(Operand.Val))
    switch (Opcode) {
    case ISD::FNEG:
      return getConstantFP(-C->getValue(), VT);
    case ISD::FP_ROUND:
    case ISD::FP_EXTEND:
      return getConstantFP(C->getValue(), VT);
    case ISD::FP_TO_SINT:
      return getConstant((int64_t)C->getValue(), VT);
    case ISD::FP_TO_UINT:
      return getConstant((uint64_t)C->getValue(), VT);
    }

  unsigned OpOpcode = Operand.Val->getOpcode();
  switch (Opcode) {
  case ISD::TokenFactor:
    return Operand;         // Factor of one node?  No factor.
  case ISD::SIGN_EXTEND:
    if (Operand.getValueType() == VT) return Operand;   // noop extension
    if (OpOpcode == ISD::SIGN_EXTEND || OpOpcode == ISD::ZERO_EXTEND)
      return getNode(OpOpcode, VT, Operand.Val->getOperand(0));
    break;
  case ISD::ZERO_EXTEND:
    if (Operand.getValueType() == VT) return Operand;   // noop extension
    if (OpOpcode == ISD::ZERO_EXTEND)   // (zext (zext x)) -> (zext x)
      return getNode(ISD::ZERO_EXTEND, VT, Operand.Val->getOperand(0));
    break;
  case ISD::ANY_EXTEND:
    if (Operand.getValueType() == VT) return Operand;   // noop extension
    if (OpOpcode == ISD::ZERO_EXTEND || OpOpcode == ISD::SIGN_EXTEND)
      // (ext (zext x)) -> (zext x)  and  (ext (sext x)) -> (sext x)
      return getNode(OpOpcode, VT, Operand.Val->getOperand(0));
    break;
  case ISD::TRUNCATE:
    if (Operand.getValueType() == VT) return Operand;   // noop truncate
    if (OpOpcode == ISD::TRUNCATE)
      return getNode(ISD::TRUNCATE, VT, Operand.Val->getOperand(0));
    else if (OpOpcode == ISD::ZERO_EXTEND || OpOpcode == ISD::SIGN_EXTEND ||
             OpOpcode == ISD::ANY_EXTEND) {
      // If the source is smaller than the dest, we still need an extend.
      if (Operand.Val->getOperand(0).getValueType() < VT)
        return getNode(OpOpcode, VT, Operand.Val->getOperand(0));
      else if (Operand.Val->getOperand(0).getValueType() > VT)
        return getNode(ISD::TRUNCATE, VT, Operand.Val->getOperand(0));
      else
        return Operand.Val->getOperand(0);
    }
    break;
  case ISD::FNEG:
    if (OpOpcode == ISD::FSUB)   // -(X-Y) -> (Y-X)
      return getNode(ISD::FSUB, VT, Operand.Val->getOperand(1),
                     Operand.Val->getOperand(0));
    if (OpOpcode == ISD::FNEG)  // --X -> X
      return Operand.Val->getOperand(0);
    break;
  case ISD::FABS:
    if (OpOpcode == ISD::FNEG)  // abs(-X) -> abs(X)
      return getNode(ISD::FABS, VT, Operand.Val->getOperand(0));
    break;
  }

  SDNode *N;
  if (VT != MVT::Flag) { // Don't CSE flag producing nodes
    SDNode *&E = UnaryOps[std::make_pair(Opcode, std::make_pair(Operand, VT))];
    if (E) return SDOperand(E, 0);
    E = N = new SDNode(Opcode, Operand);
  } else {
    N = new SDNode(Opcode, Operand);
  }
  N->setValueTypes(VT);
  AllNodes.push_back(N);
  return SDOperand(N, 0);
}



SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
                                SDOperand N1, SDOperand N2) {
#ifndef NDEBUG
  switch (Opcode) {
  case ISD::TokenFactor:
    assert(VT == MVT::Other && N1.getValueType() == MVT::Other &&
           N2.getValueType() == MVT::Other && "Invalid token factor!");
    break;
  case ISD::AND:
  case ISD::OR:
  case ISD::XOR:
  case ISD::UDIV:
  case ISD::UREM:
  case ISD::MULHU:
  case ISD::MULHS:
    assert(MVT::isInteger(VT) && "This operator does not apply to FP types!");
    // fall through
  case ISD::ADD:
  case ISD::SUB:
  case ISD::MUL:
  case ISD::SDIV:
  case ISD::SREM:
    assert(MVT::isInteger(N1.getValueType()) && "Should use F* for FP ops");
    // fall through.
  case ISD::FADD:
  case ISD::FSUB:
  case ISD::FMUL:
  case ISD::FDIV:
  case ISD::FREM:
    assert(N1.getValueType() == N2.getValueType() &&
           N1.getValueType() == VT && "Binary operator types must match!");
    break;

  case ISD::SHL:
  case ISD::SRA:
  case ISD::SRL:
    assert(VT == N1.getValueType() &&
           "Shift operators return type must be the same as their first arg");
    assert(MVT::isInteger(VT) && MVT::isInteger(N2.getValueType()) &&
           VT != MVT::i1 && "Shifts only work on integers");
    break;
  case ISD::FP_ROUND_INREG: {
    MVT::ValueType EVT = cast<VTSDNode>(N2)->getVT();
    assert(VT == N1.getValueType() && "Not an inreg round!");
    assert(MVT::isFloatingPoint(VT) && MVT::isFloatingPoint(EVT) &&
           "Cannot FP_ROUND_INREG integer types");
    assert(EVT <= VT && "Not rounding down!");
    break;
  }
  case ISD::AssertSext:
  case ISD::AssertZext:
  case ISD::SIGN_EXTEND_INREG: {
    MVT::ValueType EVT = cast<VTSDNode>(N2)->getVT();
    assert(VT == N1.getValueType() && "Not an inreg extend!");
    assert(MVT::isInteger(VT) && MVT::isInteger(EVT) &&
           "Cannot *_EXTEND_INREG FP types");
    assert(EVT <= VT && "Not extending!");
  }

  default: break;
  }
#endif

  ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.Val);
  ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2.Val);
  if (N1C) {
    if (N2C) {
      uint64_t C1 = N1C->getValue(), C2 = N2C->getValue();
      switch (Opcode) {
      case ISD::ADD: return getConstant(C1 + C2, VT);
      case ISD::SUB: return getConstant(C1 - C2, VT);
      case ISD::MUL: return getConstant(C1 * C2, VT);
      case ISD::UDIV:
        if (C2) return getConstant(C1 / C2, VT);
        break;
      case ISD::UREM :
        if (C2) return getConstant(C1 % C2, VT);
        break;
      case ISD::SDIV :
        if (C2) return getConstant(N1C->getSignExtended() /
                                   N2C->getSignExtended(), VT);
        break;
      case ISD::SREM :
        if (C2) return getConstant(N1C->getSignExtended() %
                                   N2C->getSignExtended(), VT);
        break;
      case ISD::AND  : return getConstant(C1 & C2, VT);
      case ISD::OR   : return getConstant(C1 | C2, VT);
      case ISD::XOR  : return getConstant(C1 ^ C2, VT);
      case ISD::SHL  : return getConstant(C1 << C2, VT);
      case ISD::SRL  : return getConstant(C1 >> C2, VT);
      case ISD::SRA  : return getConstant(N1C->getSignExtended() >>(int)C2, VT);
      default: break;
      }
    } else {      // Cannonicalize constant to RHS if commutative
      if (isCommutativeBinOp(Opcode)) {
        std::swap(N1C, N2C);
        std::swap(N1, N2);
      }
    }

    if (!CombinerEnabled) {
    switch (Opcode) {
    default: break;
    case ISD::SHL:    // shl  0, X -> 0
      if (N1C->isNullValue()) return N1;
      break;
    case ISD::SRL:    // srl  0, X -> 0
      if (N1C->isNullValue()) return N1;
      break;
    case ISD::SRA:    // sra -1, X -> -1
      if (N1C->isAllOnesValue()) return N1;
      break;
    case ISD::SIGN_EXTEND_INREG:  // SIGN_EXTEND_INREG N1C, EVT
      // Extending a constant?  Just return the extended constant.
      SDOperand Tmp = getNode(ISD::TRUNCATE, cast<VTSDNode>(N2)->getVT(), N1);
      return getNode(ISD::SIGN_EXTEND, VT, Tmp);
    }
    }
  }

  if (!CombinerEnabled) {
  if (N2C) {
    uint64_t C2 = N2C->getValue();

    switch (Opcode) {
    case ISD::ADD:
      if (!C2) return N1;         // add X, 0 -> X
      break;
    case ISD::SUB:
      if (!C2) return N1;         // sub X, 0 -> X
      return getNode(ISD::ADD, VT, N1, getConstant(-C2, VT));
    case ISD::MUL:
      if (!C2) return N2;         // mul X, 0 -> 0
      if (N2C->isAllOnesValue()) // mul X, -1 -> 0-X
        return getNode(ISD::SUB, VT, getConstant(0, VT), N1);

      // FIXME: Move this to the DAG combiner when it exists.
      if ((C2 & C2-1) == 0) {
        SDOperand ShAmt = getConstant(Log2_64(C2), TLI.getShiftAmountTy());
        return getNode(ISD::SHL, VT, N1, ShAmt);
      }
      break;

    case ISD::MULHU:
    case ISD::MULHS:
      if (!C2) return N2;         // mul X, 0 -> 0

      if (C2 == 1)                // 0X*01 -> 0X  hi(0X) == 0
        return getConstant(0, VT);

      // Many others could be handled here, including -1, powers of 2, etc.
      break;

    case ISD::UDIV:
      // FIXME: Move this to the DAG combiner when it exists.
      if ((C2 & C2-1) == 0 && C2) {
        SDOperand ShAmt = getConstant(Log2_64(C2), TLI.getShiftAmountTy());
        return getNode(ISD::SRL, VT, N1, ShAmt);
      }
      break;

    case ISD::SHL:
    case ISD::SRL:
    case ISD::SRA:
      // If the shift amount is bigger than the size of the data, then all the
      // bits are shifted out.  Simplify to undef.
      if (C2 >= MVT::getSizeInBits(N1.getValueType())) {
        return getNode(ISD::UNDEF, N1.getValueType());
      }
      if (C2 == 0) return N1;
      
      if (Opcode == ISD::SRA) {
        // If the sign bit is known to be zero, switch this to a SRL.
        if (MaskedValueIsZero(N1,
                              1ULL << (MVT::getSizeInBits(N1.getValueType())-1),
                              TLI))
          return getNode(ISD::SRL, N1.getValueType(), N1, N2);
      } else {
        // If the part left over is known to be zero, the whole thing is zero.
        uint64_t TypeMask = ~0ULL >> (64-MVT::getSizeInBits(N1.getValueType()));
        if (Opcode == ISD::SRL) {
          if (MaskedValueIsZero(N1, TypeMask << C2, TLI))
            return getConstant(0, N1.getValueType());
        } else if (Opcode == ISD::SHL) {
          if (MaskedValueIsZero(N1, TypeMask >> C2, TLI))
            return getConstant(0, N1.getValueType());
        }
      }

      if (Opcode == ISD::SHL && N1.getNumOperands() == 2)
        if (ConstantSDNode *OpSA = dyn_cast<ConstantSDNode>(N1.getOperand(1))) {
          unsigned OpSAC = OpSA->getValue();
          if (N1.getOpcode() == ISD::SHL) {
            if (C2+OpSAC >= MVT::getSizeInBits(N1.getValueType()))
              return getConstant(0, N1.getValueType());
            return getNode(ISD::SHL, N1.getValueType(), N1.getOperand(0),
                           getConstant(C2+OpSAC, N2.getValueType()));
          } else if (N1.getOpcode() == ISD::SRL) {
            // (X >> C1) << C2:  if C2 > C1, ((X & ~0<<C1) << C2-C1)
            SDOperand Mask = getNode(ISD::AND, VT, N1.getOperand(0),
                                     getConstant(~0ULL << OpSAC, VT));
            if (C2 > OpSAC) {
              return getNode(ISD::SHL, VT, Mask,
                             getConstant(C2-OpSAC, N2.getValueType()));
            } else {
              // (X >> C1) << C2:  if C2 <= C1, ((X & ~0<<C1) >> C1-C2)
              return getNode(ISD::SRL, VT, Mask,
                             getConstant(OpSAC-C2, N2.getValueType()));
            }
          } else if (N1.getOpcode() == ISD::SRA) {
            // if C1 == C2, just mask out low bits.
            if (C2 == OpSAC)
              return getNode(ISD::AND, VT, N1.getOperand(0),
                             getConstant(~0ULL << C2, VT));
          }
        }
      break;

    case ISD::AND:
      if (!C2) return N2;         // X and 0 -> 0
      if (N2C->isAllOnesValue())
        return N1;                // X and -1 -> X

      if (MaskedValueIsZero(N1, C2, TLI))  // X and 0 -> 0
        return getConstant(0, VT);

      {
        uint64_t NotC2 = ~C2;
        if (VT != MVT::i64)
          NotC2 &= (1ULL << MVT::getSizeInBits(VT))-1;

        if (MaskedValueIsZero(N1, NotC2, TLI))
          return N1;                // if (X & ~C2) -> 0, the and is redundant
      }

      // FIXME: Should add a corresponding version of this for
      // ZERO_EXTEND/SIGN_EXTEND by converting them to an ANY_EXTEND node which
      // we don't have yet.
      // FIXME: NOW WE DO, add this.

      // and (sign_extend_inreg x:16:32), 1 -> and x, 1
      if (N1.getOpcode() == ISD::SIGN_EXTEND_INREG) {
        // If we are masking out the part of our input that was extended, just
        // mask the input to the extension directly.
        unsigned ExtendBits =
          MVT::getSizeInBits(cast<VTSDNode>(N1.getOperand(1))->getVT());
        if ((C2 & (~0ULL << ExtendBits)) == 0)
          return getNode(ISD::AND, VT, N1.getOperand(0), N2);
      } else if (N1.getOpcode() == ISD::OR) {
        if (ConstantSDNode *ORI = dyn_cast<ConstantSDNode>(N1.getOperand(1)))
          if ((ORI->getValue() & C2) == C2) {
            // If the 'or' is setting all of the bits that we are masking for,
            // we know the result of the AND will be the AND mask itself.
            return N2;
          }
      }
      break;
    case ISD::OR:
      if (!C2)return N1;          // X or 0 -> X
      if (N2C->isAllOnesValue())
        return N2;                // X or -1 -> -1
      break;
    case ISD::XOR:
      if (!C2) return N1;        // X xor 0 -> X
      if (N2C->getValue() == 1 && N1.Val->getOpcode() == ISD::SETCC) {
          SDNode *SetCC = N1.Val;
          // !(X op Y) -> (X !op Y)
          bool isInteger = MVT::isInteger(SetCC->getOperand(0).getValueType());
          ISD::CondCode CC = cast<CondCodeSDNode>(SetCC->getOperand(2))->get();
          return getSetCC(SetCC->getValueType(0),
                          SetCC->getOperand(0), SetCC->getOperand(1),
                          ISD::getSetCCInverse(CC, isInteger));
      } else if (N2C->isAllOnesValue()) {
        if (N1.getOpcode() == ISD::AND || N1.getOpcode() == ISD::OR) {
          SDNode *Op = N1.Val;
          // !(X or Y) -> (!X and !Y) iff X or Y are freely invertible
          // !(X and Y) -> (!X or !Y) iff X or Y are freely invertible
          SDOperand LHS = Op->getOperand(0), RHS = Op->getOperand(1);
          if (isInvertibleForFree(RHS) || isInvertibleForFree(LHS)) {
            LHS = getNode(ISD::XOR, VT, LHS, N2);  // RHS = ~LHS
            RHS = getNode(ISD::XOR, VT, RHS, N2);  // RHS = ~RHS
            if (Op->getOpcode() == ISD::AND)
              return getNode(ISD::OR, VT, LHS, RHS);
            return getNode(ISD::AND, VT, LHS, RHS);
          }
        }
        // X xor -1 -> not(x)  ?
      }
      break;
    }

    // Reassociate ((X op C1) op C2) if possible.
    if (N1.getOpcode() == Opcode && isAssociativeBinOp(Opcode))
      if (ConstantSDNode *N3C = dyn_cast<ConstantSDNode>(N1.Val->getOperand(1)))
        return getNode(Opcode, VT, N1.Val->getOperand(0),
                       getNode(Opcode, VT, N2, N1.Val->getOperand(1)));
  }
  }

  ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N1.Val);
  ConstantFPSDNode *N2CFP = dyn_cast<ConstantFPSDNode>(N2.Val);
  if (N1CFP) {
    if (N2CFP) {
      double C1 = N1CFP->getValue(), C2 = N2CFP->getValue();
      switch (Opcode) {
      case ISD::FADD: return getConstantFP(C1 + C2, VT);
      case ISD::FSUB: return getConstantFP(C1 - C2, VT);
      case ISD::FMUL: return getConstantFP(C1 * C2, VT);
      case ISD::FDIV:
        if (C2) return getConstantFP(C1 / C2, VT);
        break;
      case ISD::FREM :
        if (C2) return getConstantFP(fmod(C1, C2), VT);
        break;
      default: break;
      }
    } else {      // Cannonicalize constant to RHS if commutative
      if (isCommutativeBinOp(Opcode)) {
        std::swap(N1CFP, N2CFP);
        std::swap(N1, N2);
      }
    }

    if (!CombinerEnabled) {
    if (Opcode == ISD::FP_ROUND_INREG)
      return getNode(ISD::FP_EXTEND, VT,
                     getNode(ISD::FP_ROUND, cast<VTSDNode>(N2)->getVT(), N1));
    }
  }

  // Finally, fold operations that do not require constants.
  switch (Opcode) {
  case ISD::TokenFactor:
    if (!CombinerEnabled) {
    if (N1.getOpcode() == ISD::EntryToken)
      return N2;
    if (N2.getOpcode() == ISD::EntryToken)
      return N1;
    }
    break;

  case ISD::AND:
  case ISD::OR:
    if (!CombinerEnabled) {
    if (N1.Val->getOpcode() == ISD::SETCC && N2.Val->getOpcode() == ISD::SETCC){
      SDNode *LHS = N1.Val, *RHS = N2.Val;
      SDOperand LL = LHS->getOperand(0), RL = RHS->getOperand(0);
      SDOperand LR = LHS->getOperand(1), RR = RHS->getOperand(1);
      ISD::CondCode Op1 = cast<CondCodeSDNode>(LHS->getOperand(2))->get();
      ISD::CondCode Op2 = cast<CondCodeSDNode>(RHS->getOperand(2))->get();

      if (LR == RR && isa<ConstantSDNode>(LR) &&
          Op2 == Op1 && MVT::isInteger(LL.getValueType())) {
        // (X != 0) | (Y != 0) -> (X|Y != 0)
        // (X == 0) & (Y == 0) -> (X|Y == 0)
        // (X <  0) | (Y <  0) -> (X|Y < 0)
        if (cast<ConstantSDNode>(LR)->getValue() == 0 &&
            ((Op2 == ISD::SETEQ && Opcode == ISD::AND) ||
             (Op2 == ISD::SETNE && Opcode == ISD::OR) ||
             (Op2 == ISD::SETLT && Opcode == ISD::OR)))
          return getSetCC(VT, getNode(ISD::OR, LR.getValueType(), LL, RL), LR,
                          Op2);

        if (cast<ConstantSDNode>(LR)->isAllOnesValue()) {
          // (X == -1) & (Y == -1) -> (X&Y == -1)
          // (X != -1) | (Y != -1) -> (X&Y != -1)
          // (X >  -1) | (Y >  -1) -> (X&Y >  -1)
          if ((Opcode == ISD::AND && Op2 == ISD::SETEQ) ||
              (Opcode == ISD::OR  && Op2 == ISD::SETNE) ||
              (Opcode == ISD::OR  && Op2 == ISD::SETGT))
            return getSetCC(VT, getNode(ISD::AND, LR.getValueType(), LL, RL),
                            LR, Op2);
          // (X >  -1) & (Y >  -1) -> (X|Y > -1)
          if (Opcode == ISD::AND && Op2 == ISD::SETGT)
            return getSetCC(VT, getNode(ISD::OR, LR.getValueType(), LL, RL),
                            LR, Op2);
        }
      }

      // (X op1 Y) | (Y op2 X) -> (X op1 Y) | (X swapop2 Y)
      if (LL == RR && LR == RL) {
        Op2 = ISD::getSetCCSwappedOperands(Op2);
        goto MatchedBackwards;
      }

      if (LL == RL && LR == RR) {
      MatchedBackwards:
        ISD::CondCode Result;
        bool isInteger = MVT::isInteger(LL.getValueType());
        if (Opcode == ISD::OR)
          Result = ISD::getSetCCOrOperation(Op1, Op2, isInteger);
        else
          Result = ISD::getSetCCAndOperation(Op1, Op2, isInteger);

        if (Result != ISD::SETCC_INVALID)
          return getSetCC(LHS->getValueType(0), LL, LR, Result);
      }
    }

    // and/or zext(a), zext(b) -> zext(and/or a, b)
    if (N1.getOpcode() == ISD::ZERO_EXTEND &&
        N2.getOpcode() == ISD::ZERO_EXTEND &&
        N1.getOperand(0).getValueType() == N2.getOperand(0).getValueType())
      return getNode(ISD::ZERO_EXTEND, VT,
                     getNode(Opcode, N1.getOperand(0).getValueType(),
                             N1.getOperand(0), N2.getOperand(0)));
    }
    break;
  case ISD::XOR:
    if (!CombinerEnabled) {
    if (N1 == N2) return getConstant(0, VT);  // xor X, Y -> 0
    }
    break;
  case ISD::ADD:
    if (!CombinerEnabled) {
    if (N1.getOpcode() == ISD::SUB && isa<ConstantSDNode>(N1.getOperand(0)) &&
        cast<ConstantSDNode>(N1.getOperand(0))->getValue() == 0)
      return getNode(ISD::SUB, VT, N2, N1.getOperand(1)); // (0-A)+B -> B-A
    if (N2.getOpcode() == ISD::SUB && isa<ConstantSDNode>(N2.getOperand(0)) &&
        cast<ConstantSDNode>(N2.getOperand(0))->getValue() == 0)
      return getNode(ISD::SUB, VT, N1, N2.getOperand(1)); // A+(0-B) -> A-B
    if (N2.getOpcode() == ISD::SUB && N1 == N2.Val->getOperand(1))
      return N2.Val->getOperand(0); // A+(B-A) -> B
    }
    break;
  case ISD::FADD:
    if (!CombinerEnabled) {
    if (N2.getOpcode() == ISD::FNEG)          // (A+ (-B) -> A-B
      return getNode(ISD::FSUB, VT, N1, N2.getOperand(0));
    if (N1.getOpcode() == ISD::FNEG)          // ((-A)+B) -> B-A
      return getNode(ISD::FSUB, VT, N2, N1.getOperand(0));
    }
    break;
    
  case ISD::SUB:
    if (!CombinerEnabled) {
    if (N1.getOpcode() == ISD::ADD) {
      if (N1.Val->getOperand(0) == N2)
        return N1.Val->getOperand(1);         // (A+B)-A == B
      if (N1.Val->getOperand(1) == N2)
        return N1.Val->getOperand(0);         // (A+B)-B == A
    }
    }
    break;
  case ISD::FSUB:
    if (!CombinerEnabled) {
    if (N2.getOpcode() == ISD::FNEG)          // (A- (-B) -> A+B
      return getNode(ISD::FADD, VT, N1, N2.getOperand(0));
    }
    break;
  case ISD::FP_ROUND_INREG:
    if (cast<VTSDNode>(N2)->getVT() == VT) return N1;  // Not actually rounding.
    break;
  case ISD::SIGN_EXTEND_INREG: {
    MVT::ValueType EVT = cast<VTSDNode>(N2)->getVT();
    if (EVT == VT) return N1;  // Not actually extending
    if (!CombinerEnabled) {
    // If we are sign extending an extension, use the original source.
    if (N1.getOpcode() == ISD::SIGN_EXTEND_INREG ||
        N1.getOpcode() == ISD::AssertSext)
      if (cast<VTSDNode>(N1.getOperand(1))->getVT() <= EVT)
        return N1;

    // If we are sign extending a sextload, return just the load.
    if (N1.getOpcode() == ISD::SEXTLOAD)
      if (cast<VTSDNode>(N1.getOperand(3))->getVT() <= EVT)
        return N1;    

    // If we are extending the result of a setcc, and we already know the
    // contents of the top bits, eliminate the extension.
    if (N1.getOpcode() == ISD::SETCC &&
        TLI.getSetCCResultContents() ==
                        TargetLowering::ZeroOrNegativeOneSetCCResult)
      return N1;
    
    // If we are sign extending the result of an (and X, C) operation, and we
    // know the extended bits are zeros already, don't do the extend.
    if (N1.getOpcode() == ISD::AND)
      if (ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.getOperand(1))) {
        uint64_t Mask = N1C->getValue();
        unsigned NumBits = MVT::getSizeInBits(EVT);
        if ((Mask & (~0ULL << (NumBits-1))) == 0)
          return N1;
      }
    }
    break;
  }

  // FIXME: figure out how to safely handle things like
  // int foo(int x) { return 1 << (x & 255); }
  // int bar() { return foo(256); }
#if 0
  case ISD::SHL:
  case ISD::SRL:
  case ISD::SRA:
    if (N2.getOpcode() == ISD::SIGN_EXTEND_INREG &&
        cast<VTSDNode>(N2.getOperand(1))->getVT() != MVT::i1)
      return getNode(Opcode, VT, N1, N2.getOperand(0));
    else if (N2.getOpcode() == ISD::AND)
      if (ConstantSDNode *AndRHS = dyn_cast<ConstantSDNode>(N2.getOperand(1))) {
        // If the and is only masking out bits that cannot effect the shift,
        // eliminate the and.
        unsigned NumBits = MVT::getSizeInBits(VT);
        if ((AndRHS->getValue() & (NumBits-1)) == NumBits-1)
          return getNode(Opcode, VT, N1, N2.getOperand(0));
      }
    break;
#endif
  }

  // Memoize this node if possible.
  SDNode *N;
  if (Opcode != ISD::CALLSEQ_START && Opcode != ISD::CALLSEQ_END &&
      VT != MVT::Flag) {
    SDNode *&BON = BinaryOps[std::make_pair(Opcode, std::make_pair(N1, N2))];
    if (BON) return SDOperand(BON, 0);

    BON = N = new SDNode(Opcode, N1, N2);
  } else {
    N = new SDNode(Opcode, N1, N2);
  }

  N->setValueTypes(VT);
  AllNodes.push_back(N);
  return SDOperand(N, 0);
}

// setAdjCallChain - This method changes the token chain of an
// CALLSEQ_START/END node to be the specified operand.
void SDNode::setAdjCallChain(SDOperand N) {
  assert(N.getValueType() == MVT::Other);
  assert((getOpcode() == ISD::CALLSEQ_START ||
          getOpcode() == ISD::CALLSEQ_END) && "Cannot adjust this node!");

  Operands[0].Val->removeUser(this);
  Operands[0] = N;
  N.Val->Uses.push_back(this);
}



SDOperand SelectionDAG::getLoad(MVT::ValueType VT,
                                SDOperand Chain, SDOperand Ptr,
                                SDOperand SV) {
  SDNode *&N = Loads[std::make_pair(Ptr, std::make_pair(Chain, VT))];
  if (N) return SDOperand(N, 0);
  N = new SDNode(ISD::LOAD, Chain, Ptr, SV);

  // Loads have a token chain.
  N->setValueTypes(VT, MVT::Other);
  AllNodes.push_back(N);
  return SDOperand(N, 0);
}


SDOperand SelectionDAG::getExtLoad(unsigned Opcode, MVT::ValueType VT,
                                   SDOperand Chain, SDOperand Ptr, SDOperand SV,
                                   MVT::ValueType EVT) {
  std::vector<SDOperand> Ops;
  Ops.reserve(4);
  Ops.push_back(Chain);
  Ops.push_back(Ptr);
  Ops.push_back(SV);
  Ops.push_back(getValueType(EVT));
  std::vector<MVT::ValueType> VTs;
  VTs.reserve(2);
  VTs.push_back(VT); VTs.push_back(MVT::Other);  // Add token chain.
  return getNode(Opcode, VTs, Ops);
}

SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
                                SDOperand N1, SDOperand N2, SDOperand N3) {
  // Perform various simplifications.
  ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.Val);
  ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2.Val);
  ConstantSDNode *N3C = dyn_cast<ConstantSDNode>(N3.Val);
  switch (Opcode) {
  case ISD::SETCC: {
    // Use SimplifySetCC  to simplify SETCC's.
    SDOperand Simp = SimplifySetCC(VT, N1, N2, cast<CondCodeSDNode>(N3)->get());
    if (Simp.Val) return Simp;
    break;
  }
  case ISD::SELECT:
    if (N1C)
      if (N1C->getValue())
        return N2;             // select true, X, Y -> X
      else
        return N3;             // select false, X, Y -> Y

    if (N2 == N3) return N2;   // select C, X, X -> X

    if (!CombinerEnabled) {
    if (VT == MVT::i1) {  // Boolean SELECT
      if (N2C) {
        if (N2C->getValue())   // select C, 1, X -> C | X
          return getNode(ISD::OR, VT, N1, N3);
        else                   // select C, 0, X -> ~C & X
          return getNode(ISD::AND, VT,
                         getNode(ISD::XOR, N1.getValueType(), N1,
                                 getConstant(1, N1.getValueType())), N3);
      } else if (N3C) {
        if (N3C->getValue())   // select C, X, 1 -> ~C | X
          return getNode(ISD::OR, VT,
                         getNode(ISD::XOR, N1.getValueType(), N1,
                                 getConstant(1, N1.getValueType())), N2);
        else                   // select C, X, 0 -> C & X
          return getNode(ISD::AND, VT, N1, N2);
      }

      if (N1 == N2)   // X ? X : Y --> X ? 1 : Y --> X | Y
        return getNode(ISD::OR, VT, N1, N3);
      if (N1 == N3)   // X ? Y : X --> X ? Y : 0 --> X & Y
        return getNode(ISD::AND, VT, N1, N2);
    }
    if (N1.getOpcode() == ISD::SETCC) {
      SDOperand Simp = SimplifySelectCC(N1.getOperand(0), N1.getOperand(1), N2, 
                             N3, cast<CondCodeSDNode>(N1.getOperand(2))->get());
      if (Simp.Val) return Simp;
    }
    }
    break;
  case ISD::BRCOND:
    if (N2C)
      if (N2C->getValue()) // Unconditional branch
        return getNode(ISD::BR, MVT::Other, N1, N3);
      else
        return N1;         // Never-taken branch
    break;
  }

  std::vector<SDOperand> Ops;
  Ops.reserve(3);
  Ops.push_back(N1);
  Ops.push_back(N2);
  Ops.push_back(N3);

  // Memoize node if it doesn't produce a flag.
  SDNode *N;
  if (VT != MVT::Flag) {
    SDNode *&E = OneResultNodes[std::make_pair(Opcode,std::make_pair(VT, Ops))];
    if (E) return SDOperand(E, 0);
    E = N = new SDNode(Opcode, N1, N2, N3);
  } else {
    N = new SDNode(Opcode, N1, N2, N3);
  }
  N->setValueTypes(VT);
  AllNodes.push_back(N);
  return SDOperand(N, 0);
}

SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
                                SDOperand N1, SDOperand N2, SDOperand N3,
                                SDOperand N4) {
  std::vector<SDOperand> Ops;
  Ops.reserve(4);
  Ops.push_back(N1);
  Ops.push_back(N2);
  Ops.push_back(N3);
  Ops.push_back(N4);
  return getNode(Opcode, VT, Ops);
}

SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
                                SDOperand N1, SDOperand N2, SDOperand N3,
                                SDOperand N4, SDOperand N5) {
  std::vector<SDOperand> Ops;
  Ops.reserve(5);
  Ops.push_back(N1);
  Ops.push_back(N2);
  Ops.push_back(N3);
  Ops.push_back(N4);
  Ops.push_back(N5);
  return getNode(Opcode, VT, Ops);
}


SDOperand SelectionDAG::getSrcValue(const Value *V, int Offset) {
  assert((!V || isa<PointerType>(V->getType())) &&
         "SrcValue is not a pointer?");
  SDNode *&N = ValueNodes[std::make_pair(V, Offset)];
  if (N) return SDOperand(N, 0);

  N = new SrcValueSDNode(V, Offset);
  AllNodes.push_back(N);
  return SDOperand(N, 0);
}

SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
                                std::vector<SDOperand> &Ops) {
  switch (Ops.size()) {
  case 0: return getNode(Opcode, VT);
  case 1: return getNode(Opcode, VT, Ops[0]);
  case 2: return getNode(Opcode, VT, Ops[0], Ops[1]);
  case 3: return getNode(Opcode, VT, Ops[0], Ops[1], Ops[2]);
  default: break;
  }

  ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(Ops[1].Val);
  switch (Opcode) {
  default: break;
  case ISD::BRCONDTWOWAY:
    if (N1C)
      if (N1C->getValue()) // Unconditional branch to true dest.
        return getNode(ISD::BR, MVT::Other, Ops[0], Ops[2]);
      else                 // Unconditional branch to false dest.
        return getNode(ISD::BR, MVT::Other, Ops[0], Ops[3]);
    break;
  case ISD::BRTWOWAY_CC:
    assert(Ops.size() == 6 && "BRTWOWAY_CC takes 6 operands!");
    assert(Ops[2].getValueType() == Ops[3].getValueType() &&
           "LHS and RHS of comparison must have same type!");
    break;
  case ISD::TRUNCSTORE: {
    assert(Ops.size() == 5 && "TRUNCSTORE takes 5 operands!");
    MVT::ValueType EVT = cast<VTSDNode>(Ops[4])->getVT();
#if 0 // FIXME: If the target supports EVT natively, convert to a truncate/store
    // If this is a truncating store of a constant, convert to the desired type
    // and store it instead.
    if (isa<Constant>(Ops[0])) {
      SDOperand Op = getNode(ISD::TRUNCATE, EVT, N1);
      if (isa<Constant>(Op))
        N1 = Op;
    }
    // Also for ConstantFP?
#endif
    if (Ops[0].getValueType() == EVT)       // Normal store?
      return getNode(ISD::STORE, VT, Ops[0], Ops[1], Ops[2], Ops[3]);
    assert(Ops[1].getValueType() > EVT && "Not a truncation?");
    assert(MVT::isInteger(Ops[1].getValueType()) == MVT::isInteger(EVT) &&
           "Can't do FP-INT conversion!");
    break;
  }
  case ISD::SELECT_CC: {
    assert(Ops.size() == 5 && "SELECT_CC takes 5 operands!");
    assert(Ops[0].getValueType() == Ops[1].getValueType() &&
           "LHS and RHS of condition must have same type!");
    assert(Ops[2].getValueType() == Ops[3].getValueType() &&
           "True and False arms of SelectCC must have same type!");
    assert(Ops[2].getValueType() == VT &&
           "select_cc node must be of same type as true and false value!");
    SDOperand Simp = SimplifySelectCC(Ops[0], Ops[1], Ops[2], Ops[3], 
                                      cast<CondCodeSDNode>(Ops[4])->get());
    if (Simp.Val) return Simp;
    break;
  }
  case ISD::BR_CC: {
    assert(Ops.size() == 5 && "BR_CC takes 5 operands!");
    assert(Ops[2].getValueType() == Ops[3].getValueType() &&
           "LHS/RHS of comparison should match types!");
    
    if (CombinerEnabled) break;  // xforms moved to dag combine.
    
    // Use SimplifySetCC  to simplify SETCC's.
    SDOperand Simp = SimplifySetCC(MVT::i1, Ops[2], Ops[3],
                                   cast<CondCodeSDNode>(Ops[1])->get());
    if (Simp.Val) {
      if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Simp)) {
        if (C->getValue() & 1) // Unconditional branch
          return getNode(ISD::BR, MVT::Other, Ops[0], Ops[4]);
        else
          return Ops[0];          // Unconditional Fall through
      } else if (Simp.Val->getOpcode() == ISD::SETCC) {
        Ops[2] = Simp.getOperand(0);
        Ops[3] = Simp.getOperand(1);
        Ops[1] = Simp.getOperand(2);
      }
    }
    break;
  }
  }

  // Memoize nodes.
  SDNode *N;
  if (VT != MVT::Flag) {
    SDNode *&E =
      OneResultNodes[std::make_pair(Opcode, std::make_pair(VT, Ops))];
    if (E) return SDOperand(E, 0);
    E = N = new SDNode(Opcode, Ops);
  } else {
    N = new SDNode(Opcode, Ops);
  }
  N->setValueTypes(VT);
  AllNodes.push_back(N);
  return SDOperand(N, 0);
}

SDOperand SelectionDAG::getNode(unsigned Opcode,
                                std::vector<MVT::ValueType> &ResultTys,
                                std::vector<SDOperand> &Ops) {
  if (ResultTys.size() == 1)
    return getNode(Opcode, ResultTys[0], Ops);

  switch (Opcode) {
  case ISD::EXTLOAD:
  case ISD::SEXTLOAD:
  case ISD::ZEXTLOAD: {
    MVT::ValueType EVT = cast<VTSDNode>(Ops[3])->getVT();
    assert(Ops.size() == 4 && ResultTys.size() == 2 && "Bad *EXTLOAD!");
    // If they are asking for an extending load from/to the same thing, return a
    // normal load.
    if (ResultTys[0] == EVT)
      return getLoad(ResultTys[0], Ops[0], Ops[1], Ops[2]);
    assert(EVT < ResultTys[0] &&
           "Should only be an extending load, not truncating!");
    assert((Opcode == ISD::EXTLOAD || MVT::isInteger(ResultTys[0])) &&
           "Cannot sign/zero extend a FP load!");
    assert(MVT::isInteger(ResultTys[0]) == MVT::isInteger(EVT) &&
           "Cannot convert from FP to Int or Int -> FP!");
    break;
  }

  // FIXME: figure out how to safely handle things like
  // int foo(int x) { return 1 << (x & 255); }
  // int bar() { return foo(256); }
#if 0
  case ISD::SRA_PARTS:
  case ISD::SRL_PARTS:
  case ISD::SHL_PARTS:
    if (N3.getOpcode() == ISD::SIGN_EXTEND_INREG &&
        cast<VTSDNode>(N3.getOperand(1))->getVT() != MVT::i1)
      return getNode(Opcode, VT, N1, N2, N3.getOperand(0));
    else if (N3.getOpcode() == ISD::AND)
      if (ConstantSDNode *AndRHS = dyn_cast<ConstantSDNode>(N3.getOperand(1))) {
        // If the and is only masking out bits that cannot effect the shift,
        // eliminate the and.
        unsigned NumBits = MVT::getSizeInBits(VT)*2;
        if ((AndRHS->getValue() & (NumBits-1)) == NumBits-1)
          return getNode(Opcode, VT, N1, N2, N3.getOperand(0));
      }
    break;
#endif
  }

  // Memoize the node unless it returns a flag.
  SDNode *N;
  if (ResultTys.back() != MVT::Flag) {
    SDNode *&E =
      ArbitraryNodes[std::make_pair(Opcode, std::make_pair(ResultTys, Ops))];
    if (E) return SDOperand(E, 0);
    E = N = new SDNode(Opcode, Ops);
  } else {
    N = new SDNode(Opcode, Ops);
  }
  N->setValueTypes(ResultTys);
  AllNodes.push_back(N);
  return SDOperand(N, 0);
}


/// SelectNodeTo - These are used for target selectors to *mutate* the
/// specified node to have the specified return type, Target opcode, and
/// operands.  Note that target opcodes are stored as
/// ISD::BUILTIN_OP_END+TargetOpcode in the node opcode field.
void SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc,
                                MVT::ValueType VT) {
  RemoveNodeFromCSEMaps(N);
  N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc);
  N->setValueTypes(VT);
}
void SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc,
                                MVT::ValueType VT, SDOperand Op1) {
  RemoveNodeFromCSEMaps(N);
  N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc);
  N->setValueTypes(VT);
  N->setOperands(Op1);
}
void SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc,
                                MVT::ValueType VT, SDOperand Op1,
                                SDOperand Op2) {
  RemoveNodeFromCSEMaps(N);
  N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc);
  N->setValueTypes(VT);
  N->setOperands(Op1, Op2);
}
void SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc, 
                                MVT::ValueType VT1, MVT::ValueType VT2,
                                SDOperand Op1, SDOperand Op2) {
  RemoveNodeFromCSEMaps(N);
  N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc);
  N->setValueTypes(VT1, VT2);
  N->setOperands(Op1, Op2);
}
void SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc,
                                MVT::ValueType VT, SDOperand Op1,
                                SDOperand Op2, SDOperand Op3) {
  RemoveNodeFromCSEMaps(N);
  N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc);
  N->setValueTypes(VT);
  N->setOperands(Op1, Op2, Op3);
}
void SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc,
                                MVT::ValueType VT1, MVT::ValueType VT2,
                                SDOperand Op1, SDOperand Op2, SDOperand Op3) {
  RemoveNodeFromCSEMaps(N);
  N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc);
  N->setValueTypes(VT1, VT2);
  N->setOperands(Op1, Op2, Op3);
}

void SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc,
                                MVT::ValueType VT, SDOperand Op1,
                                SDOperand Op2, SDOperand Op3, SDOperand Op4) {
  RemoveNodeFromCSEMaps(N);
  N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc);
  N->setValueTypes(VT);
  N->setOperands(Op1, Op2, Op3, Op4);
}
void SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc,
                                MVT::ValueType VT, SDOperand Op1,
                                SDOperand Op2, SDOperand Op3, SDOperand Op4,
                                SDOperand Op5) {
  RemoveNodeFromCSEMaps(N);
  N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc);
  N->setValueTypes(VT);
  N->setOperands(Op1, Op2, Op3, Op4, Op5);
}

/// ReplaceAllUsesWith - Modify anything using 'From' to use 'To' instead.
/// This can cause recursive merging of nodes in the DAG.
///
/// This version assumes From/To have a single result value.
///
void SelectionDAG::ReplaceAllUsesWith(SDOperand FromN, SDOperand ToN,
                                      std::vector<SDNode*> *Deleted) {
  SDNode *From = FromN.Val, *To = ToN.Val;
  assert(From->getNumValues() == 1 && To->getNumValues() == 1 &&
         "Cannot replace with this method!");
  assert(From != To && "Cannot replace uses of with self");
  
  while (!From->use_empty()) {
    // Process users until they are all gone.
    SDNode *U = *From->use_begin();
    
    // This node is about to morph, remove its old self from the CSE maps.
    RemoveNodeFromCSEMaps(U);
    
    for (unsigned i = 0, e = U->getNumOperands(); i != e; ++i)
      if (U->getOperand(i).Val == From) {
        From->removeUser(U);
        U->Operands[i].Val = To;
        To->addUser(U);
      }

    // Now that we have modified U, add it back to the CSE maps.  If it already
    // exists there, recursively merge the results together.
    if (SDNode *Existing = AddNonLeafNodeToCSEMaps(U)) {
      ReplaceAllUsesWith(U, Existing, Deleted);
      // U is now dead.
      if (Deleted) Deleted->push_back(U);
      DeleteNodeNotInCSEMaps(U);
    }
  }
}

/// ReplaceAllUsesWith - Modify anything using 'From' to use 'To' instead.
/// This can cause recursive merging of nodes in the DAG.
///
/// This version assumes From/To have matching types and numbers of result
/// values.
///
void SelectionDAG::ReplaceAllUsesWith(SDNode *From, SDNode *To,
                                      std::vector<SDNode*> *Deleted) {
  assert(From != To && "Cannot replace uses of with self");
  assert(From->getNumValues() == To->getNumValues() &&
         "Cannot use this version of ReplaceAllUsesWith!");
  if (From->getNumValues() == 1) {  // If possible, use the faster version.
    ReplaceAllUsesWith(SDOperand(From, 0), SDOperand(To, 0), Deleted);
    return;
  }
  
  while (!From->use_empty()) {
    // Process users until they are all gone.
    SDNode *U = *From->use_begin();
    
    // This node is about to morph, remove its old self from the CSE maps.
    RemoveNodeFromCSEMaps(U);
    
    for (unsigned i = 0, e = U->getNumOperands(); i != e; ++i)
      if (U->getOperand(i).Val == From) {
        From->removeUser(U);
        U->Operands[i].Val = To;
        To->addUser(U);
      }
        
    // Now that we have modified U, add it back to the CSE maps.  If it already
    // exists there, recursively merge the results together.
    if (SDNode *Existing = AddNonLeafNodeToCSEMaps(U)) {
      ReplaceAllUsesWith(U, Existing, Deleted);
      // U is now dead.
      if (Deleted) Deleted->push_back(U);
      DeleteNodeNotInCSEMaps(U);
    }
  }
}

/// ReplaceAllUsesWith - Modify anything using 'From' to use 'To' instead.
/// This can cause recursive merging of nodes in the DAG.
///
/// This version can replace From with any result values.  To must match the
/// number and types of values returned by From.
void SelectionDAG::ReplaceAllUsesWith(SDNode *From,
                                      const std::vector<SDOperand> &To,
                                      std::vector<SDNode*> *Deleted) {
  assert(From->getNumValues() == To.size() &&
         "Incorrect number of values to replace with!");
  if (To.size() == 1 && To[0].Val->getNumValues() == 1) {
    // Degenerate case handled above.
    ReplaceAllUsesWith(SDOperand(From, 0), To[0], Deleted);
    return;
  }

  while (!From->use_empty()) {
    // Process users until they are all gone.
    SDNode *U = *From->use_begin();
    
    // This node is about to morph, remove its old self from the CSE maps.
    RemoveNodeFromCSEMaps(U);
    
    for (unsigned i = 0, e = U->getNumOperands(); i != e; ++i)
      if (U->getOperand(i).Val == From) {
        const SDOperand &ToOp = To[U->getOperand(i).ResNo];
        From->removeUser(U);
        U->Operands[i] = ToOp;
        ToOp.Val->addUser(U);
      }
        
    // Now that we have modified U, add it back to the CSE maps.  If it already
    // exists there, recursively merge the results together.
    if (SDNode *Existing = AddNonLeafNodeToCSEMaps(U)) {
      ReplaceAllUsesWith(U, Existing, Deleted);
      // U is now dead.
      if (Deleted) Deleted->push_back(U);
      DeleteNodeNotInCSEMaps(U);
    }
  }
}


//===----------------------------------------------------------------------===//
//                              SDNode Class
//===----------------------------------------------------------------------===//

/// hasNUsesOfValue - Return true if there are exactly NUSES uses of the
/// indicated value.  This method ignores uses of other values defined by this
/// operation.
bool SDNode::hasNUsesOfValue(unsigned NUses, unsigned Value) {
  assert(Value < getNumValues() && "Bad value!");

  // If there is only one value, this is easy.
  if (getNumValues() == 1)
    return use_size() == NUses;
  if (Uses.size() < NUses) return false;

  SDOperand TheValue(this, Value);

  std::set<SDNode*> UsersHandled;

  for (std::vector<SDNode*>::iterator UI = Uses.begin(), E = Uses.end();
       UI != E; ++UI) {
    SDNode *User = *UI;
    if (User->getNumOperands() == 1 ||
        UsersHandled.insert(User).second)     // First time we've seen this?
      for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i)
        if (User->getOperand(i) == TheValue) {
          if (NUses == 0)
            return false;   // too many uses
          --NUses;
        }
  }

  // Found exactly the right number of uses?
  return NUses == 0;
}


const char *SDNode::getOperationName(const SelectionDAG *G) const {
  switch (getOpcode()) {
  default:
    if (getOpcode() < ISD::BUILTIN_OP_END)
      return "<<Unknown DAG Node>>";
    else {
      if (G)
        if (const TargetInstrInfo *TII = G->getTarget().getInstrInfo())
          if (getOpcode()-ISD::BUILTIN_OP_END < TII->getNumOpcodes())
            return TII->getName(getOpcode()-ISD::BUILTIN_OP_END);
      return "<<Unknown Target Node>>";
    }
   
  case ISD::PCMARKER:      return "PCMarker";
  case ISD::SRCVALUE:      return "SrcValue";
  case ISD::VALUETYPE:     return "ValueType";
  case ISD::EntryToken:    return "EntryToken";
  case ISD::TokenFactor:   return "TokenFactor";
  case ISD::AssertSext:    return "AssertSext";
  case ISD::AssertZext:    return "AssertZext";
  case ISD::Constant:      return "Constant";
  case ISD::TargetConstant: return "TargetConstant";
  case ISD::ConstantFP:    return "ConstantFP";
  case ISD::GlobalAddress: return "GlobalAddress";
  case ISD::TargetGlobalAddress: return "TargetGlobalAddress";
  case ISD::FrameIndex:    return "FrameIndex";
  case ISD::TargetFrameIndex: return "TargetFrameIndex";
  case ISD::BasicBlock:    return "BasicBlock";
  case ISD::Register:      return "Register";
  case ISD::ExternalSymbol: return "ExternalSymbol";
  case ISD::ConstantPool:  return "ConstantPool";
  case ISD::TargetConstantPool:  return "TargetConstantPool";
  case ISD::CopyToReg:     return "CopyToReg";
  case ISD::CopyFromReg:   return "CopyFromReg";
  case ISD::ImplicitDef:   return "ImplicitDef";
  case ISD::UNDEF:         return "undef";

  // Unary operators
  case ISD::FABS:   return "fabs";
  case ISD::FNEG:   return "fneg";
  case ISD::FSQRT:  return "fsqrt";
  case ISD::FSIN:   return "fsin";
  case ISD::FCOS:   return "fcos";

  // Binary operators
  case ISD::ADD:    return "add";
  case ISD::SUB:    return "sub";
  case ISD::MUL:    return "mul";
  case ISD::MULHU:  return "mulhu";
  case ISD::MULHS:  return "mulhs";
  case ISD::SDIV:   return "sdiv";
  case ISD::UDIV:   return "udiv";
  case ISD::SREM:   return "srem";
  case ISD::UREM:   return "urem";
  case ISD::AND:    return "and";
  case ISD::OR:     return "or";
  case ISD::XOR:    return "xor";
  case ISD::SHL:    return "shl";
  case ISD::SRA:    return "sra";
  case ISD::SRL:    return "srl";
  case ISD::FADD:   return "fadd";
  case ISD::FSUB:   return "fsub";
  case ISD::FMUL:   return "fmul";
  case ISD::FDIV:   return "fdiv";
  case ISD::FREM:   return "frem";
    
  case ISD::SETCC:       return "setcc";
  case ISD::SELECT:      return "select";
  case ISD::SELECT_CC:   return "select_cc";
  case ISD::ADD_PARTS:   return "add_parts";
  case ISD::SUB_PARTS:   return "sub_parts";
  case ISD::SHL_PARTS:   return "shl_parts";
  case ISD::SRA_PARTS:   return "sra_parts";
  case ISD::SRL_PARTS:   return "srl_parts";

  // Conversion operators.
  case ISD::SIGN_EXTEND: return "sign_extend";
  case ISD::ZERO_EXTEND: return "zero_extend";
  case ISD::ANY_EXTEND:  return "any_extend";
  case ISD::SIGN_EXTEND_INREG: return "sign_extend_inreg";
  case ISD::TRUNCATE:    return "truncate";
  case ISD::FP_ROUND:    return "fp_round";
  case ISD::FP_ROUND_INREG: return "fp_round_inreg";
  case ISD::FP_EXTEND:   return "fp_extend";

  case ISD::SINT_TO_FP:  return "sint_to_fp";
  case ISD::UINT_TO_FP:  return "uint_to_fp";
  case ISD::FP_TO_SINT:  return "fp_to_sint";
  case ISD::FP_TO_UINT:  return "fp_to_uint";

    // Control flow instructions
  case ISD::BR:      return "br";
  case ISD::BRCOND:  return "brcond";
  case ISD::BRCONDTWOWAY:  return "brcondtwoway";
  case ISD::BR_CC:  return "br_cc";
  case ISD::BRTWOWAY_CC:  return "brtwoway_cc";
  case ISD::RET:     return "ret";
  case ISD::CALL:    return "call";
  case ISD::TAILCALL:return "tailcall";
  case ISD::CALLSEQ_START:  return "callseq_start";
  case ISD::CALLSEQ_END:    return "callseq_end";

    // Other operators
  case ISD::LOAD:    return "load";
  case ISD::STORE:   return "store";
  case ISD::EXTLOAD:    return "extload";
  case ISD::SEXTLOAD:   return "sextload";
  case ISD::ZEXTLOAD:   return "zextload";
  case ISD::TRUNCSTORE: return "truncstore";

  case ISD::DYNAMIC_STACKALLOC: return "dynamic_stackalloc";
  case ISD::EXTRACT_ELEMENT: return "extract_element";
  case ISD::BUILD_PAIR: return "build_pair";
  case ISD::MEMSET:  return "memset";
  case ISD::MEMCPY:  return "memcpy";
  case ISD::MEMMOVE: return "memmove";

  // Bit counting
  case ISD::CTPOP:   return "ctpop";
  case ISD::CTTZ:    return "cttz";
  case ISD::CTLZ:    return "ctlz";

  // IO Intrinsics
  case ISD::READPORT: return "readport";
  case ISD::WRITEPORT: return "writeport";
  case ISD::READIO: return "readio";
  case ISD::WRITEIO: return "writeio";

  case ISD::CONDCODE:
    switch (cast<CondCodeSDNode>(this)->get()) {
    default: assert(0 && "Unknown setcc condition!");
    case ISD::SETOEQ:  return "setoeq";
    case ISD::SETOGT:  return "setogt";
    case ISD::SETOGE:  return "setoge";
    case ISD::SETOLT:  return "setolt";
    case ISD::SETOLE:  return "setole";
    case ISD::SETONE:  return "setone";

    case ISD::SETO:    return "seto";
    case ISD::SETUO:   return "setuo";
    case ISD::SETUEQ:  return "setue";
    case ISD::SETUGT:  return "setugt";
    case ISD::SETUGE:  return "setuge";
    case ISD::SETULT:  return "setult";
    case ISD::SETULE:  return "setule";
    case ISD::SETUNE:  return "setune";

    case ISD::SETEQ:   return "seteq";
    case ISD::SETGT:   return "setgt";
    case ISD::SETGE:   return "setge";
    case ISD::SETLT:   return "setlt";
    case ISD::SETLE:   return "setle";
    case ISD::SETNE:   return "setne";
    }
  }
}

void SDNode::dump() const { dump(0); }
void SDNode::dump(const SelectionDAG *G) const {
  std::cerr << (void*)this << ": ";

  for (unsigned i = 0, e = getNumValues(); i != e; ++i) {
    if (i) std::cerr << ",";
    if (getValueType(i) == MVT::Other)
      std::cerr << "ch";
    else
      std::cerr << MVT::getValueTypeString(getValueType(i));
  }
  std::cerr << " = " << getOperationName(G);

  std::cerr << " ";
  for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
    if (i) std::cerr << ", ";
    std::cerr << (void*)getOperand(i).Val;
    if (unsigned RN = getOperand(i).ResNo)
      std::cerr << ":" << RN;
  }

  if (const ConstantSDNode *CSDN = dyn_cast<ConstantSDNode>(this)) {
    std::cerr << "<" << CSDN->getValue() << ">";
  } else if (const ConstantFPSDNode *CSDN = dyn_cast<ConstantFPSDNode>(this)) {
    std::cerr << "<" << CSDN->getValue() << ">";
  } else if (const GlobalAddressSDNode *GADN =
             dyn_cast<GlobalAddressSDNode>(this)) {
    std::cerr << "<";
    WriteAsOperand(std::cerr, GADN->getGlobal()) << ">";
  } else if (const FrameIndexSDNode *FIDN = dyn_cast<FrameIndexSDNode>(this)) {
    std::cerr << "<" << FIDN->getIndex() << ">";
  } else if (const ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(this)){
    std::cerr << "<" << *CP->get() << ">";
  } else if (const BasicBlockSDNode *BBDN = dyn_cast<BasicBlockSDNode>(this)) {
    std::cerr << "<";
    const Value *LBB = (const Value*)BBDN->getBasicBlock()->getBasicBlock();
    if (LBB)
      std::cerr << LBB->getName() << " ";
    std::cerr << (const void*)BBDN->getBasicBlock() << ">";
  } else if (const RegisterSDNode *R = dyn_cast<RegisterSDNode>(this)) {
    if (G && MRegisterInfo::isPhysicalRegister(R->getReg())) {
      std::cerr << " " <<G->getTarget().getRegisterInfo()->getName(R->getReg());
    } else {
      std::cerr << " #" << R->getReg();
    }
  } else if (const ExternalSymbolSDNode *ES =
             dyn_cast<ExternalSymbolSDNode>(this)) {
    std::cerr << "'" << ES->getSymbol() << "'";
  } else if (const SrcValueSDNode *M = dyn_cast<SrcValueSDNode>(this)) {
    if (M->getValue())
      std::cerr << "<" << M->getValue() << ":" << M->getOffset() << ">";
    else
      std::cerr << "<null:" << M->getOffset() << ">";
  } else if (const VTSDNode *N = dyn_cast<VTSDNode>(this)) {
    std::cerr << ":" << getValueTypeString(N->getVT());
  }
}

static void DumpNodes(SDNode *N, unsigned indent, const SelectionDAG *G) {
  for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
    if (N->getOperand(i).Val->hasOneUse())
      DumpNodes(N->getOperand(i).Val, indent+2, G);
    else
      std::cerr << "\n" << std::string(indent+2, ' ')
                << (void*)N->getOperand(i).Val << ": <multiple use>";


  std::cerr << "\n" << std::string(indent, ' ');
  N->dump(G);
}

void SelectionDAG::dump() const {
  std::cerr << "SelectionDAG has " << AllNodes.size() << " nodes:";
  std::vector<SDNode*> Nodes(AllNodes);
  std::sort(Nodes.begin(), Nodes.end());

  for (unsigned i = 0, e = Nodes.size(); i != e; ++i) {
    if (!Nodes[i]->hasOneUse() && Nodes[i] != getRoot().Val)
      DumpNodes(Nodes[i], 2, this);
  }

  DumpNodes(getRoot().Val, 2, this);

  std::cerr << "\n\n";
}

