diff options
Diffstat (limited to 'lib/CodeGen/SelectionDAG/SelectionDAG.cpp')
| -rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 1342 | 
1 files changed, 805 insertions, 537 deletions
| diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 45d5a4fa69e8..a5555364c82a 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -18,17 +18,15 @@  #include "llvm/ADT/SmallSet.h"  #include "llvm/ADT/SmallVector.h"  #include "llvm/ADT/StringExtras.h" -#include "llvm/Analysis/TargetTransformInfo.h"  #include "llvm/Analysis/ValueTracking.h" -#include "llvm/Assembly/Writer.h"  #include "llvm/CodeGen/MachineBasicBlock.h"  #include "llvm/CodeGen/MachineConstantPool.h"  #include "llvm/CodeGen/MachineFrameInfo.h"  #include "llvm/CodeGen/MachineModuleInfo.h" -#include "llvm/DebugInfo.h"  #include "llvm/IR/CallingConv.h"  #include "llvm/IR/Constants.h"  #include "llvm/IR/DataLayout.h" +#include "llvm/IR/DebugInfo.h"  #include "llvm/IR/DerivedTypes.h"  #include "llvm/IR/Function.h"  #include "llvm/IR/GlobalAlias.h" @@ -50,6 +48,7 @@  #include "llvm/Target/TargetSelectionDAGInfo.h"  #include <algorithm>  #include <cmath> +  using namespace llvm;  /// makeVTList - Return an instance of the SDVTList struct initialized with the @@ -149,33 +148,50 @@ bool ISD::isBuildVectorAllZeros(const SDNode *N) {    if (N->getOpcode() != ISD::BUILD_VECTOR) return false; -  unsigned i = 0, e = N->getNumOperands(); - -  // Skip over all of the undef values. -  while (i != e && N->getOperand(i).getOpcode() == ISD::UNDEF) -    ++i; +  bool IsAllUndef = true; +  for (unsigned i = 0, e = N->getNumOperands(); i < e; ++i) { +    if (N->getOperand(i).getOpcode() == ISD::UNDEF) +      continue; +    IsAllUndef = false; +    // Do not accept build_vectors that aren't all constants or which have non-0 +    // elements. We have to be a bit careful here, as the type of the constant +    // may not be the same as the type of the vector elements due to type +    // legalization (the elements are promoted to a legal type for the target +    // and a vector of a type may be legal when the base element type is not). +    // We only want to check enough bits to cover the vector elements, because +    // we care if the resultant vector is all zeros, not whether the individual +    // constants are. +    SDValue Zero = N->getOperand(i); +    unsigned EltSize = N->getValueType(0).getVectorElementType().getSizeInBits(); +    if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Zero)) { +      if (CN->getAPIntValue().countTrailingZeros() < EltSize) +        return false; +    } else if (ConstantFPSDNode *CFPN = dyn_cast<ConstantFPSDNode>(Zero)) { +      if (CFPN->getValueAPF().bitcastToAPInt().countTrailingZeros() < EltSize) +        return false; +    } else +      return false; +  }    // Do not accept an all-undef vector. -  if (i == e) return false; +  if (IsAllUndef) +    return false; +  return true; +} -  // Do not accept build_vectors that aren't all constants or which have non-0 -  // elements. -  SDValue Zero = N->getOperand(i); -  if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Zero)) { -    if (!CN->isNullValue()) -      return false; -  } else if (ConstantFPSDNode *CFPN = dyn_cast<ConstantFPSDNode>(Zero)) { -    if (!CFPN->getValueAPF().isPosZero()) -      return false; -  } else +/// \brief Return true if the specified node is a BUILD_VECTOR node of +/// all ConstantSDNode or undef. +bool ISD::isBuildVectorOfConstantSDNodes(const SDNode *N) { +  if (N->getOpcode() != ISD::BUILD_VECTOR)      return false; -  // Okay, we have at least one 0 value, check to see if the rest match or are -  // undefs. -  for (++i; i != e; ++i) -    if (N->getOperand(i) != Zero && -        N->getOperand(i).getOpcode() != ISD::UNDEF) +  for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { +    SDValue Op = N->getOperand(i); +    if (Op.getOpcode() == ISD::UNDEF) +      continue; +    if (!isa<ConstantSDNode>(Op))        return false; +  }    return true;  } @@ -217,6 +233,21 @@ bool ISD::allOperandsUndef(const SDNode *N) {    return true;  } +ISD::NodeType ISD::getExtForLoadExtType(ISD::LoadExtType ExtType) { +  switch (ExtType) { +  case ISD::EXTLOAD: +    return ISD::ANY_EXTEND; +  case ISD::SEXTLOAD: +    return ISD::SIGN_EXTEND; +  case ISD::ZEXTLOAD: +    return ISD::ZERO_EXTEND; +  default: +    break; +  } + +  llvm_unreachable("Invalid LoadExtType"); +} +  /// getSetCCSwappedOperands - Return the operation corresponding to (Y op X)  /// when given the operation for (X op Y).  ISD::CondCode ISD::getSetCCSwappedOperands(ISD::CondCode Operation) { @@ -335,29 +366,42 @@ static void AddNodeIDValueTypes(FoldingSetNodeID &ID, SDVTList VTList) {  /// AddNodeIDOperands - Various routines for adding operands to the NodeID data.  ///  static void AddNodeIDOperands(FoldingSetNodeID &ID, -                              const SDValue *Ops, unsigned NumOps) { -  for (; NumOps; --NumOps, ++Ops) { -    ID.AddPointer(Ops->getNode()); -    ID.AddInteger(Ops->getResNo()); +                              ArrayRef<SDValue> Ops) { +  for (auto& Op : Ops) { +    ID.AddPointer(Op.getNode()); +    ID.AddInteger(Op.getResNo());    }  }  /// AddNodeIDOperands - Various routines for adding operands to the NodeID data.  ///  static void AddNodeIDOperands(FoldingSetNodeID &ID, -                              const SDUse *Ops, unsigned NumOps) { -  for (; NumOps; --NumOps, ++Ops) { -    ID.AddPointer(Ops->getNode()); -    ID.AddInteger(Ops->getResNo()); +                              ArrayRef<SDUse> Ops) { +  for (auto& Op : Ops) { +    ID.AddPointer(Op.getNode()); +    ID.AddInteger(Op.getResNo());    }  } -static void AddNodeIDNode(FoldingSetNodeID &ID, -                          unsigned short OpC, SDVTList VTList, -                          const SDValue *OpList, unsigned N) { +static void AddBinaryNodeIDCustom(FoldingSetNodeID &ID, bool nuw, bool nsw, +                                  bool exact) { +  ID.AddBoolean(nuw); +  ID.AddBoolean(nsw); +  ID.AddBoolean(exact); +} + +/// AddBinaryNodeIDCustom - Add BinarySDNodes special infos +static void AddBinaryNodeIDCustom(FoldingSetNodeID &ID, unsigned Opcode, +                                  bool nuw, bool nsw, bool exact) { +  if (isBinOpWithFlags(Opcode)) +    AddBinaryNodeIDCustom(ID, nuw, nsw, exact); +} + +static void AddNodeIDNode(FoldingSetNodeID &ID, unsigned short OpC, +                          SDVTList VTList, ArrayRef<SDValue> OpList) {    AddNodeIDOpcode(ID, OpC);    AddNodeIDValueTypes(ID, VTList); -  AddNodeIDOperands(ID, OpList, N); +  AddNodeIDOperands(ID, OpList);  }  /// AddNodeIDCustom - If this is an SDNode with special info, add this info to @@ -369,9 +413,12 @@ static void AddNodeIDCustom(FoldingSetNodeID &ID, const SDNode *N) {      llvm_unreachable("Should only be used on nodes with operands");    default: break;  // Normal nodes don't need extra info.    case ISD::TargetConstant: -  case ISD::Constant: -    ID.AddPointer(cast<ConstantSDNode>(N)->getConstantIntValue()); +  case ISD::Constant: { +    const ConstantSDNode *C = cast<ConstantSDNode>(N); +    ID.AddPointer(C->getConstantIntValue()); +    ID.AddBoolean(C->isOpaque());      break; +  }    case ISD::TargetConstantFP:    case ISD::ConstantFP: {      ID.AddPointer(cast<ConstantFPSDNode>(N)->getConstantFPValue()); @@ -442,7 +489,21 @@ static void AddNodeIDCustom(FoldingSetNodeID &ID, const SDNode *N) {      ID.AddInteger(ST->getPointerInfo().getAddrSpace());      break;    } +  case ISD::SDIV: +  case ISD::UDIV: +  case ISD::SRA: +  case ISD::SRL: +  case ISD::MUL: +  case ISD::ADD: +  case ISD::SUB: +  case ISD::SHL: { +    const BinaryWithFlagsSDNode *BinNode = cast<BinaryWithFlagsSDNode>(N); +    AddBinaryNodeIDCustom(ID, N->getOpcode(), BinNode->hasNoUnsignedWrap(), +                          BinNode->hasNoSignedWrap(), BinNode->isExact()); +    break; +  }    case ISD::ATOMIC_CMP_SWAP: +  case ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS:    case ISD::ATOMIC_SWAP:    case ISD::ATOMIC_LOAD_ADD:    case ISD::ATOMIC_LOAD_SUB: @@ -496,7 +557,7 @@ static void AddNodeIDNode(FoldingSetNodeID &ID, const SDNode *N) {    // Add the return value info.    AddNodeIDValueTypes(ID, N->getVTList());    // Add the operand info. -  AddNodeIDOperands(ID, N->op_begin(), N->getNumOperands()); +  AddNodeIDOperands(ID, N->ops());    // Handle SDNode leafs with special info.    AddNodeIDCustom(ID, N); @@ -574,7 +635,7 @@ void SelectionDAG::RemoveDeadNodes(SmallVectorImpl<SDNode *> &DeadNodes) {      SDNode *N = DeadNodes.pop_back_val();      for (DAGUpdateListener *DUL = UpdateListeners; DUL; DUL = DUL->Next) -      DUL->NodeDeleted(N, 0); +      DUL->NodeDeleted(N, nullptr);      // Take the node out of the appropriate CSE map.      RemoveNodeFromCSEMaps(N); @@ -652,8 +713,8 @@ bool SelectionDAG::RemoveNodeFromCSEMaps(SDNode *N) {    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; +    Erased = CondCodeNodes[cast<CondCodeSDNode>(N)->get()] != nullptr; +    CondCodeNodes[cast<CondCodeSDNode>(N)->get()] = nullptr;      break;    case ISD::ExternalSymbol:      Erased = ExternalSymbols.erase(cast<ExternalSymbolSDNode>(N)->getSymbol()); @@ -670,8 +731,8 @@ bool SelectionDAG::RemoveNodeFromCSEMaps(SDNode *N) {      if (VT.isExtended()) {        Erased = ExtendedValueTypeNodes.erase(VT);      } else { -      Erased = ValueTypeNodes[VT.getSimpleVT().SimpleTy] != 0; -      ValueTypeNodes[VT.getSimpleVT().SimpleTy] = 0; +      Erased = ValueTypeNodes[VT.getSimpleVT().SimpleTy] != nullptr; +      ValueTypeNodes[VT.getSimpleVT().SimpleTy] = nullptr;      }      break;    } @@ -733,11 +794,11 @@ SelectionDAG::AddModifiedNodeToCSEMaps(SDNode *N) {  SDNode *SelectionDAG::FindModifiedNodeSlot(SDNode *N, SDValue Op,                                             void *&InsertPos) {    if (doNotCSE(N)) -    return 0; +    return nullptr;    SDValue Ops[] = { Op };    FoldingSetNodeID ID; -  AddNodeIDNode(ID, N->getOpcode(), N->getVTList(), Ops, 1); +  AddNodeIDNode(ID, N->getOpcode(), N->getVTList(), Ops);    AddNodeIDCustom(ID, N);    SDNode *Node = CSEMap.FindNodeOrInsertPos(ID, InsertPos);    return Node; @@ -751,11 +812,11 @@ SDNode *SelectionDAG::FindModifiedNodeSlot(SDNode *N,                                             SDValue Op1, SDValue Op2,                                             void *&InsertPos) {    if (doNotCSE(N)) -    return 0; +    return nullptr;    SDValue Ops[] = { Op1, Op2 };    FoldingSetNodeID ID; -  AddNodeIDNode(ID, N->getOpcode(), N->getVTList(), Ops, 2); +  AddNodeIDNode(ID, N->getOpcode(), N->getVTList(), Ops);    AddNodeIDCustom(ID, N);    SDNode *Node = CSEMap.FindNodeOrInsertPos(ID, InsertPos);    return Node; @@ -766,14 +827,13 @@ SDNode *SelectionDAG::FindModifiedNodeSlot(SDNode *N,  /// were replaced with those specified.  If this node is never memoized,  /// return null, otherwise return a pointer to the slot it would take.  If a  /// node already exists with these operands, the slot will be non-null. -SDNode *SelectionDAG::FindModifiedNodeSlot(SDNode *N, -                                           const SDValue *Ops,unsigned NumOps, +SDNode *SelectionDAG::FindModifiedNodeSlot(SDNode *N, ArrayRef<SDValue> Ops,                                             void *&InsertPos) {    if (doNotCSE(N)) -    return 0; +    return nullptr;    FoldingSetNodeID ID; -  AddNodeIDNode(ID, N->getOpcode(), N->getVTList(), Ops, NumOps); +  AddNodeIDNode(ID, N->getOpcode(), N->getVTList(), Ops);    AddNodeIDCustom(ID, N);    SDNode *Node = CSEMap.FindNodeOrInsertPos(ID, InsertPos);    return Node; @@ -869,18 +929,16 @@ unsigned SelectionDAG::getEVTAlignment(EVT VT) const {  // EntryNode could meaningfully have debug info if we can find it...  SelectionDAG::SelectionDAG(const TargetMachine &tm, CodeGenOpt::Level OL) -  : TM(tm), TSI(*tm.getSelectionDAGInfo()), TTI(0), TLI(0), OptLevel(OL), +  : TM(tm), TSI(*tm.getSelectionDAGInfo()), TLI(nullptr), OptLevel(OL),      EntryNode(ISD::EntryToken, 0, DebugLoc(), getVTList(MVT::Other)),      Root(getEntryNode()), NewNodesMustHaveLegalTypes(false), -    UpdateListeners(0) { +    UpdateListeners(nullptr) {    AllNodes.push_back(&EntryNode);    DbgInfo = new SDDbgInfo();  } -void SelectionDAG::init(MachineFunction &mf, const TargetTransformInfo *tti, -                        const TargetLowering *tli) { +void SelectionDAG::init(MachineFunction &mf, const TargetLowering *tli) {    MF = &mf; -  TTI = tti;    TLI = tli;    Context = &mf.getFunction()->getContext();  } @@ -898,6 +956,25 @@ void SelectionDAG::allnodes_clear() {      DeallocateNode(AllNodes.begin());  } +BinarySDNode *SelectionDAG::GetBinarySDNode(unsigned Opcode, SDLoc DL, +                                            SDVTList VTs, SDValue N1, +                                            SDValue N2, bool nuw, bool nsw, +                                            bool exact) { +  if (isBinOpWithFlags(Opcode)) { +    BinaryWithFlagsSDNode *FN = new (NodeAllocator) BinaryWithFlagsSDNode( +        Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs, N1, N2); +    FN->setHasNoUnsignedWrap(nuw); +    FN->setHasNoSignedWrap(nsw); +    FN->setIsExact(exact); + +    return FN; +  } + +  BinarySDNode *N = new (NodeAllocator) +      BinarySDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), VTs, N1, N2); +  return N; +} +  void SelectionDAG::clear() {    allnodes_clear();    OperandAllocator.Reset(); @@ -907,11 +984,11 @@ void SelectionDAG::clear() {    ExternalSymbols.clear();    TargetExternalSymbols.clear();    std::fill(CondCodeNodes.begin(), CondCodeNodes.end(), -            static_cast<CondCodeSDNode*>(0)); +            static_cast<CondCodeSDNode*>(nullptr));    std::fill(ValueTypeNodes.begin(), ValueTypeNodes.end(), -            static_cast<SDNode*>(0)); +            static_cast<SDNode*>(nullptr)); -  EntryNode.UseList = 0; +  EntryNode.UseList = nullptr;    AllNodes.push_back(&EntryNode);    Root = getEntryNode();    DbgInfo->clear(); @@ -935,6 +1012,15 @@ SDValue SelectionDAG::getZExtOrTrunc(SDValue Op, SDLoc DL, EVT VT) {      getNode(ISD::TRUNCATE, DL, VT, Op);  } +SDValue SelectionDAG::getBoolExtOrTrunc(SDValue Op, SDLoc SL, EVT VT, +                                        EVT OpVT) { +  if (VT.bitsLE(Op.getValueType())) +    return getNode(ISD::TRUNCATE, SL, VT, Op); + +  TargetLowering::BooleanContent BType = TLI->getBooleanContents(OpVT); +  return getNode(TLI->getExtendForContent(BType), SL, VT, Op); +} +  SDValue SelectionDAG::getZeroExtendInReg(SDValue Op, SDLoc DL, EVT VT) {    assert(!VT.isVector() &&           "getZeroExtendInReg should use the vector element type instead of " @@ -947,6 +1033,36 @@ SDValue SelectionDAG::getZeroExtendInReg(SDValue Op, SDLoc DL, EVT VT) {                   getConstant(Imm, Op.getValueType()));  } +SDValue SelectionDAG::getAnyExtendVectorInReg(SDValue Op, SDLoc DL, EVT VT) { +  assert(VT.isVector() && "This DAG node is restricted to vector types."); +  assert(VT.getSizeInBits() == Op.getValueType().getSizeInBits() && +         "The sizes of the input and result must match in order to perform the " +         "extend in-register."); +  assert(VT.getVectorNumElements() < Op.getValueType().getVectorNumElements() && +         "The destination vector type must have fewer lanes than the input."); +  return getNode(ISD::ANY_EXTEND_VECTOR_INREG, DL, VT, Op); +} + +SDValue SelectionDAG::getSignExtendVectorInReg(SDValue Op, SDLoc DL, EVT VT) { +  assert(VT.isVector() && "This DAG node is restricted to vector types."); +  assert(VT.getSizeInBits() == Op.getValueType().getSizeInBits() && +         "The sizes of the input and result must match in order to perform the " +         "extend in-register."); +  assert(VT.getVectorNumElements() < Op.getValueType().getVectorNumElements() && +         "The destination vector type must have fewer lanes than the input."); +  return getNode(ISD::SIGN_EXTEND_VECTOR_INREG, DL, VT, Op); +} + +SDValue SelectionDAG::getZeroExtendVectorInReg(SDValue Op, SDLoc DL, EVT VT) { +  assert(VT.isVector() && "This DAG node is restricted to vector types."); +  assert(VT.getSizeInBits() == Op.getValueType().getSizeInBits() && +         "The sizes of the input and result must match in order to perform the " +         "extend in-register."); +  assert(VT.getVectorNumElements() < Op.getValueType().getVectorNumElements() && +         "The destination vector type must have fewer lanes than the input."); +  return getNode(ISD::ZERO_EXTEND_VECTOR_INREG, DL, VT, Op); +} +  /// getNOT - Create a bitwise NOT operation as (XOR Val, -1).  ///  SDValue SelectionDAG::getNOT(SDLoc DL, SDValue Val, EVT VT) { @@ -956,19 +1072,37 @@ SDValue SelectionDAG::getNOT(SDLoc DL, SDValue Val, EVT VT) {    return getNode(ISD::XOR, DL, VT, Val, NegOne);  } -SDValue SelectionDAG::getConstant(uint64_t Val, EVT VT, bool isT) { +SDValue SelectionDAG::getLogicalNOT(SDLoc DL, SDValue Val, EVT VT) { +  EVT EltVT = VT.getScalarType(); +  SDValue TrueValue; +  switch (TLI->getBooleanContents(VT)) { +    case TargetLowering::ZeroOrOneBooleanContent: +    case TargetLowering::UndefinedBooleanContent: +      TrueValue = getConstant(1, VT); +      break; +    case TargetLowering::ZeroOrNegativeOneBooleanContent: +      TrueValue = getConstant(APInt::getAllOnesValue(EltVT.getSizeInBits()), +                              VT); +      break; +  } +  return getNode(ISD::XOR, DL, VT, Val, TrueValue); +} + +SDValue SelectionDAG::getConstant(uint64_t Val, EVT VT, bool isT, bool isO) {    EVT EltVT = VT.getScalarType();    assert((EltVT.getSizeInBits() >= 64 ||           (uint64_t)((int64_t)Val >> EltVT.getSizeInBits()) + 1 < 2) &&           "getConstant with a uint64_t value that doesn't fit in the type!"); -  return getConstant(APInt(EltVT.getSizeInBits(), Val), VT, isT); +  return getConstant(APInt(EltVT.getSizeInBits(), Val), VT, isT, isO);  } -SDValue SelectionDAG::getConstant(const APInt &Val, EVT VT, bool isT) { -  return getConstant(*ConstantInt::get(*Context, Val), VT, isT); +SDValue SelectionDAG::getConstant(const APInt &Val, EVT VT, bool isT, bool isO) +{ +  return getConstant(*ConstantInt::get(*Context, Val), VT, isT, isO);  } -SDValue SelectionDAG::getConstant(const ConstantInt &Val, EVT VT, bool isT) { +SDValue SelectionDAG::getConstant(const ConstantInt &Val, EVT VT, bool isT, +                                  bool isO) {    assert(VT.isInteger() && "Cannot create FP integer constant!");    EVT EltVT = VT.getScalarType(); @@ -1010,7 +1144,7 @@ SDValue SelectionDAG::getConstant(const ConstantInt &Val, EVT VT, bool isT) {      for (unsigned i = 0; i < ViaVecNumElts / VT.getVectorNumElements(); ++i) {        EltParts.push_back(getConstant(NewVal.lshr(i * ViaEltSizeInBits)                                             .trunc(ViaEltSizeInBits), -                                     ViaEltVT, isT)); +                                     ViaEltVT, isT, isO));      }      // EltParts is currently in little endian order. If we actually want @@ -1031,7 +1165,7 @@ SDValue SelectionDAG::getConstant(const ConstantInt &Val, EVT VT, bool isT) {      SDValue Result = getNode(ISD::BITCAST, SDLoc(), VT,                               getNode(ISD::BUILD_VECTOR, SDLoc(), ViaVecVT, -                                     &Ops[0], Ops.size())); +                                     Ops));      return Result;    } @@ -1039,16 +1173,17 @@ SDValue SelectionDAG::getConstant(const ConstantInt &Val, EVT VT, bool isT) {           "APInt size does not match type size!");    unsigned Opc = isT ? ISD::TargetConstant : ISD::Constant;    FoldingSetNodeID ID; -  AddNodeIDNode(ID, Opc, getVTList(EltVT), 0, 0); +  AddNodeIDNode(ID, Opc, getVTList(EltVT), None);    ID.AddPointer(Elt); -  void *IP = 0; -  SDNode *N = NULL; +  ID.AddBoolean(isO); +  void *IP = nullptr; +  SDNode *N = nullptr;    if ((N = CSEMap.FindNodeOrInsertPos(ID, IP)))      if (!VT.isVector())        return SDValue(N, 0);    if (!N) { -    N = new (NodeAllocator) ConstantSDNode(isT, Elt, EltVT); +    N = new (NodeAllocator) ConstantSDNode(isT, isO, Elt, EltVT);      CSEMap.InsertNode(N, IP);      AllNodes.push_back(N);    } @@ -1057,7 +1192,7 @@ SDValue SelectionDAG::getConstant(const ConstantInt &Val, EVT VT, bool isT) {    if (VT.isVector()) {      SmallVector<SDValue, 8> Ops;      Ops.assign(VT.getVectorNumElements(), Result); -    Result = getNode(ISD::BUILD_VECTOR, SDLoc(), VT, &Ops[0], Ops.size()); +    Result = getNode(ISD::BUILD_VECTOR, SDLoc(), VT, Ops);    }    return Result;  } @@ -1081,10 +1216,10 @@ SDValue SelectionDAG::getConstantFP(const ConstantFP& V, EVT VT, bool isTarget){    // we don't have issues with SNANs.    unsigned Opc = isTarget ? ISD::TargetConstantFP : ISD::ConstantFP;    FoldingSetNodeID ID; -  AddNodeIDNode(ID, Opc, getVTList(EltVT), 0, 0); +  AddNodeIDNode(ID, Opc, getVTList(EltVT), None);    ID.AddPointer(&V); -  void *IP = 0; -  SDNode *N = NULL; +  void *IP = nullptr; +  SDNode *N = nullptr;    if ((N = CSEMap.FindNodeOrInsertPos(ID, IP)))      if (!VT.isVector())        return SDValue(N, 0); @@ -1100,7 +1235,7 @@ SDValue SelectionDAG::getConstantFP(const ConstantFP& V, EVT VT, bool isTarget){      SmallVector<SDValue, 8> Ops;      Ops.assign(VT.getVectorNumElements(), Result);      // FIXME SDLoc info might be appropriate here -    Result = getNode(ISD::BUILD_VECTOR, SDLoc(), VT, &Ops[0], Ops.size()); +    Result = getNode(ISD::BUILD_VECTOR, SDLoc(), VT, Ops);    }    return Result;  } @@ -1135,26 +1270,19 @@ SDValue SelectionDAG::getGlobalAddress(const GlobalValue *GV, SDLoc DL,    if (BitWidth < 64)      Offset = SignExtend64(Offset, BitWidth); -  const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV); -  if (!GVar) { -    // If GV is an alias then use the aliasee for determining thread-localness. -    if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV)) -      GVar = dyn_cast_or_null<GlobalVariable>(GA->resolveAliasedGlobal(false)); -  } -    unsigned Opc; -  if (GVar && GVar->isThreadLocal()) +  if (GV->isThreadLocal())      Opc = isTargetGA ? ISD::TargetGlobalTLSAddress : ISD::GlobalTLSAddress;    else      Opc = isTargetGA ? ISD::TargetGlobalAddress : ISD::GlobalAddress;    FoldingSetNodeID ID; -  AddNodeIDNode(ID, Opc, getVTList(VT), 0, 0); +  AddNodeIDNode(ID, Opc, getVTList(VT), None);    ID.AddPointer(GV);    ID.AddInteger(Offset);    ID.AddInteger(TargetFlags);    ID.AddInteger(GV->getType()->getAddressSpace()); -  void *IP = 0; +  void *IP = nullptr;    if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))      return SDValue(E, 0); @@ -1169,9 +1297,9 @@ SDValue SelectionDAG::getGlobalAddress(const GlobalValue *GV, SDLoc DL,  SDValue SelectionDAG::getFrameIndex(int FI, EVT VT, bool isTarget) {    unsigned Opc = isTarget ? ISD::TargetFrameIndex : ISD::FrameIndex;    FoldingSetNodeID ID; -  AddNodeIDNode(ID, Opc, getVTList(VT), 0, 0); +  AddNodeIDNode(ID, Opc, getVTList(VT), None);    ID.AddInteger(FI); -  void *IP = 0; +  void *IP = nullptr;    if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))      return SDValue(E, 0); @@ -1187,10 +1315,10 @@ SDValue SelectionDAG::getJumpTable(int JTI, EVT VT, bool isTarget,           "Cannot set target flags on target-independent jump tables");    unsigned Opc = isTarget ? ISD::TargetJumpTable : ISD::JumpTable;    FoldingSetNodeID ID; -  AddNodeIDNode(ID, Opc, getVTList(VT), 0, 0); +  AddNodeIDNode(ID, Opc, getVTList(VT), None);    ID.AddInteger(JTI);    ID.AddInteger(TargetFlags); -  void *IP = 0; +  void *IP = nullptr;    if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))      return SDValue(E, 0); @@ -1212,12 +1340,12 @@ SDValue SelectionDAG::getConstantPool(const Constant *C, EVT VT,      TM.getTargetLowering()->getDataLayout()->getPrefTypeAlignment(C->getType());    unsigned Opc = isTarget ? ISD::TargetConstantPool : ISD::ConstantPool;    FoldingSetNodeID ID; -  AddNodeIDNode(ID, Opc, getVTList(VT), 0, 0); +  AddNodeIDNode(ID, Opc, getVTList(VT), None);    ID.AddInteger(Alignment);    ID.AddInteger(Offset);    ID.AddPointer(C);    ID.AddInteger(TargetFlags); -  void *IP = 0; +  void *IP = nullptr;    if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))      return SDValue(E, 0); @@ -1240,12 +1368,12 @@ SDValue SelectionDAG::getConstantPool(MachineConstantPoolValue *C, EVT VT,      TM.getTargetLowering()->getDataLayout()->getPrefTypeAlignment(C->getType());    unsigned Opc = isTarget ? ISD::TargetConstantPool : ISD::ConstantPool;    FoldingSetNodeID ID; -  AddNodeIDNode(ID, Opc, getVTList(VT), 0, 0); +  AddNodeIDNode(ID, Opc, getVTList(VT), None);    ID.AddInteger(Alignment);    ID.AddInteger(Offset);    C->addSelectionDAGCSEId(ID);    ID.AddInteger(TargetFlags); -  void *IP = 0; +  void *IP = nullptr;    if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))      return SDValue(E, 0); @@ -1259,11 +1387,11 @@ SDValue SelectionDAG::getConstantPool(MachineConstantPoolValue *C, EVT VT,  SDValue SelectionDAG::getTargetIndex(int Index, EVT VT, int64_t Offset,                                       unsigned char TargetFlags) {    FoldingSetNodeID ID; -  AddNodeIDNode(ID, ISD::TargetIndex, getVTList(VT), 0, 0); +  AddNodeIDNode(ID, ISD::TargetIndex, getVTList(VT), None);    ID.AddInteger(Index);    ID.AddInteger(Offset);    ID.AddInteger(TargetFlags); -  void *IP = 0; +  void *IP = nullptr;    if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))      return SDValue(E, 0); @@ -1276,9 +1404,9 @@ SDValue SelectionDAG::getTargetIndex(int Index, EVT VT, int64_t Offset,  SDValue SelectionDAG::getBasicBlock(MachineBasicBlock *MBB) {    FoldingSetNodeID ID; -  AddNodeIDNode(ID, ISD::BasicBlock, getVTList(MVT::Other), 0, 0); +  AddNodeIDNode(ID, ISD::BasicBlock, getVTList(MVT::Other), None);    ID.AddPointer(MBB); -  void *IP = 0; +  void *IP = nullptr;    if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))      return SDValue(E, 0); @@ -1325,7 +1453,7 @@ SDValue SelectionDAG::getCondCode(ISD::CondCode Cond) {    if ((unsigned)Cond >= CondCodeNodes.size())      CondCodeNodes.resize(Cond+1); -  if (CondCodeNodes[Cond] == 0) { +  if (!CondCodeNodes[Cond]) {      CondCodeSDNode *N = new (NodeAllocator) CondCodeSDNode(Cond);      CondCodeNodes[Cond] = N;      AllNodes.push_back(N); @@ -1399,6 +1527,11 @@ SDValue SelectionDAG::getVectorShuffle(EVT VT, SDLoc dl, SDValue N1,      N1 = getUNDEF(VT);      commuteShuffle(N1, N2, MaskVec);    } +  // Reset our undef status after accounting for the mask. +  N2Undef = N2.getOpcode() == ISD::UNDEF; +  // Re-check whether both sides ended up undef. +  if (N1.getOpcode() == ISD::UNDEF && N2Undef) +    return getUNDEF(VT);    // If Identity shuffle return that node.    bool Identity = true; @@ -1408,13 +1541,45 @@ SDValue SelectionDAG::getVectorShuffle(EVT VT, SDLoc dl, SDValue N1,    if (Identity && NElts)      return N1; +  // Shuffling a constant splat doesn't change the result. +  if (N2Undef) { +    SDValue V = N1; + +    // Look through any bitcasts. We check that these don't change the number +    // (and size) of elements and just changes their types. +    while (V.getOpcode() == ISD::BITCAST) +      V = V->getOperand(0); + +    // A splat should always show up as a build vector node. +    if (auto *BV = dyn_cast<BuildVectorSDNode>(V)) { +      BitVector UndefElements; +      SDValue Splat = BV->getSplatValue(&UndefElements); +      // If this is a splat of an undef, shuffling it is also undef. +      if (Splat && Splat.getOpcode() == ISD::UNDEF) +        return getUNDEF(VT); + +      // We only have a splat which can skip shuffles if there is a splatted +      // value and no undef lanes rearranged by the shuffle. +      if (Splat && UndefElements.none()) { +        // Splat of <x, x, ..., x>, return <x, x, ..., x>, provided that the +        // number of elements match or the value splatted is a zero constant. +        if (V.getValueType().getVectorNumElements() == +            VT.getVectorNumElements()) +          return N1; +        if (auto *C = dyn_cast<ConstantSDNode>(Splat)) +          if (C->isNullValue()) +            return N1; +      } +    } +  } +    FoldingSetNodeID ID;    SDValue Ops[2] = { N1, N2 }; -  AddNodeIDNode(ID, ISD::VECTOR_SHUFFLE, getVTList(VT), Ops, 2); +  AddNodeIDNode(ID, ISD::VECTOR_SHUFFLE, getVTList(VT), Ops);    for (unsigned i = 0; i != NElts; ++i)      ID.AddInteger(MaskVec[i]); -  void* IP = 0; +  void* IP = nullptr;    if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))      return SDValue(E, 0); @@ -1433,6 +1598,27 @@ SDValue SelectionDAG::getVectorShuffle(EVT VT, SDLoc dl, SDValue N1,    return SDValue(N, 0);  } +SDValue SelectionDAG::getCommutedVectorShuffle(const ShuffleVectorSDNode &SV) { +  MVT VT = SV.getSimpleValueType(0); +  unsigned NumElems = VT.getVectorNumElements(); +  SmallVector<int, 8> MaskVec; + +  for (unsigned i = 0; i != NumElems; ++i) { +    int Idx = SV.getMaskElt(i); +    if (Idx >= 0) { +      if (Idx < (int)NumElems) +        Idx += NumElems; +      else +        Idx -= NumElems; +    } +    MaskVec.push_back(Idx); +  } + +  SDValue Op0 = SV.getOperand(0); +  SDValue Op1 = SV.getOperand(1); +  return getVectorShuffle(VT, SDLoc(&SV), Op1, Op0, &MaskVec[0]); +} +  SDValue SelectionDAG::getConvertRndSat(EVT VT, SDLoc dl,                                         SDValue Val, SDValue DTy,                                         SDValue STy, SDValue Rnd, SDValue Sat, @@ -1445,14 +1631,14 @@ SDValue SelectionDAG::getConvertRndSat(EVT VT, SDLoc dl,    FoldingSetNodeID ID;    SDValue Ops[] = { Val, DTy, STy, Rnd, Sat }; -  AddNodeIDNode(ID, ISD::CONVERT_RNDSAT, getVTList(VT), &Ops[0], 5); -  void* IP = 0; +  AddNodeIDNode(ID, ISD::CONVERT_RNDSAT, getVTList(VT), Ops); +  void* IP = nullptr;    if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))      return SDValue(E, 0);    CvtRndSatSDNode *N = new (NodeAllocator) CvtRndSatSDNode(VT, dl.getIROrder(),                                                             dl.getDebugLoc(), -                                                           Ops, 5, Code); +                                                           Ops, Code);    CSEMap.InsertNode(N, IP);    AllNodes.push_back(N);    return SDValue(N, 0); @@ -1460,9 +1646,9 @@ SDValue SelectionDAG::getConvertRndSat(EVT VT, SDLoc dl,  SDValue SelectionDAG::getRegister(unsigned RegNo, EVT VT) {    FoldingSetNodeID ID; -  AddNodeIDNode(ID, ISD::Register, getVTList(VT), 0, 0); +  AddNodeIDNode(ID, ISD::Register, getVTList(VT), None);    ID.AddInteger(RegNo); -  void *IP = 0; +  void *IP = nullptr;    if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))      return SDValue(E, 0); @@ -1474,9 +1660,9 @@ SDValue SelectionDAG::getRegister(unsigned RegNo, EVT VT) {  SDValue SelectionDAG::getRegisterMask(const uint32_t *RegMask) {    FoldingSetNodeID ID; -  AddNodeIDNode(ID, ISD::RegisterMask, getVTList(MVT::Untyped), 0, 0); +  AddNodeIDNode(ID, ISD::RegisterMask, getVTList(MVT::Untyped), None);    ID.AddPointer(RegMask); -  void *IP = 0; +  void *IP = nullptr;    if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))      return SDValue(E, 0); @@ -1489,9 +1675,9 @@ SDValue SelectionDAG::getRegisterMask(const uint32_t *RegMask) {  SDValue SelectionDAG::getEHLabel(SDLoc dl, SDValue Root, MCSymbol *Label) {    FoldingSetNodeID ID;    SDValue Ops[] = { Root }; -  AddNodeIDNode(ID, ISD::EH_LABEL, getVTList(MVT::Other), &Ops[0], 1); +  AddNodeIDNode(ID, ISD::EH_LABEL, getVTList(MVT::Other), Ops);    ID.AddPointer(Label); -  void *IP = 0; +  void *IP = nullptr;    if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))      return SDValue(E, 0); @@ -1510,11 +1696,11 @@ SDValue SelectionDAG::getBlockAddress(const BlockAddress *BA, EVT VT,    unsigned Opc = isTarget ? ISD::TargetBlockAddress : ISD::BlockAddress;    FoldingSetNodeID ID; -  AddNodeIDNode(ID, Opc, getVTList(VT), 0, 0); +  AddNodeIDNode(ID, Opc, getVTList(VT), None);    ID.AddPointer(BA);    ID.AddInteger(Offset);    ID.AddInteger(TargetFlags); -  void *IP = 0; +  void *IP = nullptr;    if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))      return SDValue(E, 0); @@ -1530,10 +1716,10 @@ SDValue SelectionDAG::getSrcValue(const Value *V) {           "SrcValue is not a pointer?");    FoldingSetNodeID ID; -  AddNodeIDNode(ID, ISD::SRCVALUE, getVTList(MVT::Other), 0, 0); +  AddNodeIDNode(ID, ISD::SRCVALUE, getVTList(MVT::Other), None);    ID.AddPointer(V); -  void *IP = 0; +  void *IP = nullptr;    if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))      return SDValue(E, 0); @@ -1546,10 +1732,10 @@ SDValue SelectionDAG::getSrcValue(const Value *V) {  /// getMDNode - Return an MDNodeSDNode which holds an MDNode.  SDValue SelectionDAG::getMDNode(const MDNode *MD) {    FoldingSetNodeID ID; -  AddNodeIDNode(ID, ISD::MDNODE_SDNODE, getVTList(MVT::Other), 0, 0); +  AddNodeIDNode(ID, ISD::MDNODE_SDNODE, getVTList(MVT::Other), None);    ID.AddPointer(MD); -  void *IP = 0; +  void *IP = nullptr;    if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))      return SDValue(E, 0); @@ -1564,11 +1750,11 @@ SDValue SelectionDAG::getAddrSpaceCast(SDLoc dl, EVT VT, SDValue Ptr,                                         unsigned SrcAS, unsigned DestAS) {    SDValue Ops[] = {Ptr};    FoldingSetNodeID ID; -  AddNodeIDNode(ID, ISD::ADDRSPACECAST, getVTList(VT), &Ops[0], 1); +  AddNodeIDNode(ID, ISD::ADDRSPACECAST, getVTList(VT), Ops);    ID.AddInteger(SrcAS);    ID.AddInteger(DestAS); -  void *IP = 0; +  void *IP = nullptr;    if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))      return SDValue(E, 0); @@ -1632,7 +1818,8 @@ SDValue SelectionDAG::FoldSetCC(EVT VT, SDValue N1,    case ISD::SETTRUE:    case ISD::SETTRUE2: {      const TargetLowering *TLI = TM.getTargetLowering(); -    TargetLowering::BooleanContent Cnt = TLI->getBooleanContents(VT.isVector()); +    TargetLowering::BooleanContent Cnt = +        TLI->getBooleanContents(N1->getValueType(0));      return getConstant(          Cnt == TargetLowering::ZeroOrNegativeOneBooleanContent ? -1ULL : 1, VT);    } @@ -1747,17 +1934,14 @@ bool SelectionDAG::SignBitIsZero(SDValue Op, unsigned Depth) const {  bool SelectionDAG::MaskedValueIsZero(SDValue Op, const APInt &Mask,                                       unsigned Depth) const {    APInt KnownZero, KnownOne; -  ComputeMaskedBits(Op, KnownZero, KnownOne, Depth); -  assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); +  computeKnownBits(Op, KnownZero, KnownOne, Depth);    return (KnownZero & Mask) == Mask;  } -/// ComputeMaskedBits - Determine which of the bits specified in Mask are -/// known to be either zero or one and return them in the KnownZero/KnownOne -/// bitsets.  This code only analyzes bits in Mask, in order to short-circuit -/// processing. -void SelectionDAG::ComputeMaskedBits(SDValue Op, APInt &KnownZero, -                                     APInt &KnownOne, unsigned Depth) const { +/// Determine which bits of Op are known to be either zero or one and return +/// them in the KnownZero/KnownOne bitsets. +void SelectionDAG::computeKnownBits(SDValue Op, APInt &KnownZero, +                                    APInt &KnownOne, unsigned Depth) const {    const TargetLowering *TLI = TM.getTargetLowering();    unsigned BitWidth = Op.getValueType().getScalarType().getSizeInBits(); @@ -1772,48 +1956,40 @@ void SelectionDAG::ComputeMaskedBits(SDValue Op, APInt &KnownZero,      // We know all of the bits for a constant!      KnownOne = cast<ConstantSDNode>(Op)->getAPIntValue();      KnownZero = ~KnownOne; -    return; +    break;    case ISD::AND:      // If either the LHS or the RHS are Zero, the result is zero. -    ComputeMaskedBits(Op.getOperand(1), KnownZero, KnownOne, Depth+1); -    ComputeMaskedBits(Op.getOperand(0), KnownZero2, KnownOne2, Depth+1); -    assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); -    assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?"); +    computeKnownBits(Op.getOperand(1), KnownZero, KnownOne, Depth+1); +    computeKnownBits(Op.getOperand(0), KnownZero2, KnownOne2, Depth+1);      // Output known-1 bits are only known if set in both the LHS & RHS.      KnownOne &= KnownOne2;      // Output known-0 are known to be clear if zero in either the LHS | RHS.      KnownZero |= KnownZero2; -    return; +    break;    case ISD::OR: -    ComputeMaskedBits(Op.getOperand(1), KnownZero, KnownOne, Depth+1); -    ComputeMaskedBits(Op.getOperand(0), KnownZero2, KnownOne2, Depth+1); -    assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); -    assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?"); +    computeKnownBits(Op.getOperand(1), KnownZero, KnownOne, Depth+1); +    computeKnownBits(Op.getOperand(0), KnownZero2, KnownOne2, Depth+1);      // Output known-0 bits are only known if clear in both the LHS & RHS.      KnownZero &= KnownZero2;      // Output known-1 are known to be set if set in either the LHS | RHS.      KnownOne |= KnownOne2; -    return; +    break;    case ISD::XOR: { -    ComputeMaskedBits(Op.getOperand(1), KnownZero, KnownOne, Depth+1); -    ComputeMaskedBits(Op.getOperand(0), KnownZero2, KnownOne2, Depth+1); -    assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); -    assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?"); +    computeKnownBits(Op.getOperand(1), KnownZero, KnownOne, Depth+1); +    computeKnownBits(Op.getOperand(0), KnownZero2, KnownOne2, Depth+1);      // Output known-0 bits are known if clear or set in both the LHS & RHS.      APInt KnownZeroOut = (KnownZero & KnownZero2) | (KnownOne & KnownOne2);      // Output known-1 are known to be set if set in only one of the LHS, RHS.      KnownOne = (KnownZero & KnownOne2) | (KnownOne & KnownZero2);      KnownZero = KnownZeroOut; -    return; +    break;    }    case ISD::MUL: { -    ComputeMaskedBits(Op.getOperand(1), KnownZero, KnownOne, Depth+1); -    ComputeMaskedBits(Op.getOperand(0), KnownZero2, KnownOne2, Depth+1); -    assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); -    assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?"); +    computeKnownBits(Op.getOperand(1), KnownZero, KnownOne, Depth+1); +    computeKnownBits(Op.getOperand(0), KnownZero2, KnownOne2, Depth+1);      // If low bits are zero in either operand, output low known-0 bits.      // Also compute a conserative estimate for high known-0 bits. @@ -1830,46 +2006,42 @@ void SelectionDAG::ComputeMaskedBits(SDValue Op, APInt &KnownZero,      LeadZ = std::min(LeadZ, BitWidth);      KnownZero = APInt::getLowBitsSet(BitWidth, TrailZ) |                  APInt::getHighBitsSet(BitWidth, LeadZ); -    return; +    break;    }    case ISD::UDIV: {      // For the purposes of computing leading zeros we can conservatively      // treat a udiv as a logical right shift by the power of 2 known to      // be less than the denominator. -    ComputeMaskedBits(Op.getOperand(0), KnownZero2, KnownOne2, Depth+1); +    computeKnownBits(Op.getOperand(0), KnownZero2, KnownOne2, Depth+1);      unsigned LeadZ = KnownZero2.countLeadingOnes();      KnownOne2.clearAllBits();      KnownZero2.clearAllBits(); -    ComputeMaskedBits(Op.getOperand(1), KnownZero2, KnownOne2, Depth+1); +    computeKnownBits(Op.getOperand(1), KnownZero2, KnownOne2, Depth+1);      unsigned RHSUnknownLeadingOnes = KnownOne2.countLeadingZeros();      if (RHSUnknownLeadingOnes != BitWidth)        LeadZ = std::min(BitWidth,                         LeadZ + BitWidth - RHSUnknownLeadingOnes - 1);      KnownZero = APInt::getHighBitsSet(BitWidth, LeadZ); -    return; +    break;    }    case ISD::SELECT: -    ComputeMaskedBits(Op.getOperand(2), KnownZero, KnownOne, Depth+1); -    ComputeMaskedBits(Op.getOperand(1), KnownZero2, KnownOne2, Depth+1); -    assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); -    assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?"); +    computeKnownBits(Op.getOperand(2), KnownZero, KnownOne, Depth+1); +    computeKnownBits(Op.getOperand(1), KnownZero2, KnownOne2, Depth+1);      // Only known if known in both the LHS and RHS.      KnownOne &= KnownOne2;      KnownZero &= KnownZero2; -    return; +    break;    case ISD::SELECT_CC: -    ComputeMaskedBits(Op.getOperand(3), KnownZero, KnownOne, Depth+1); -    ComputeMaskedBits(Op.getOperand(2), KnownZero2, KnownOne2, Depth+1); -    assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); -    assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?"); +    computeKnownBits(Op.getOperand(3), KnownZero, KnownOne, Depth+1); +    computeKnownBits(Op.getOperand(2), KnownZero2, KnownOne2, Depth+1);      // Only known if known in both the LHS and RHS.      KnownOne &= KnownOne2;      KnownZero &= KnownZero2; -    return; +    break;    case ISD::SADDO:    case ISD::UADDO:    case ISD::SSUBO: @@ -1877,14 +2049,23 @@ void SelectionDAG::ComputeMaskedBits(SDValue Op, APInt &KnownZero,    case ISD::SMULO:    case ISD::UMULO:      if (Op.getResNo() != 1) -      return; -    // The boolean result conforms to getBooleanContents.  Fall through. +      break; +    // The boolean result conforms to getBooleanContents. +    // If we know the result of a setcc has the top bits zero, use this info. +    // We know that we have an integer-based boolean since these operations +    // are only available for integer. +    if (TLI->getBooleanContents(Op.getValueType().isVector(), false) == +            TargetLowering::ZeroOrOneBooleanContent && +        BitWidth > 1) +      KnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - 1); +    break;    case ISD::SETCC:      // If we know the result of a setcc has the top bits zero, use this info. -    if (TLI->getBooleanContents(Op.getValueType().isVector()) == -        TargetLowering::ZeroOrOneBooleanContent && BitWidth > 1) +    if (TLI->getBooleanContents(Op.getOperand(0).getValueType()) == +            TargetLowering::ZeroOrOneBooleanContent && +        BitWidth > 1)        KnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - 1); -    return; +    break;    case ISD::SHL:      // (shl X, C1) & C2 == 0   iff   (X & C2 >>u C1) == 0      if (ConstantSDNode *SA = dyn_cast<ConstantSDNode>(Op.getOperand(1))) { @@ -1892,16 +2073,15 @@ void SelectionDAG::ComputeMaskedBits(SDValue Op, APInt &KnownZero,        // If the shift count is an invalid immediate, don't do anything.        if (ShAmt >= BitWidth) -        return; +        break; -      ComputeMaskedBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1); -      assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); +      computeKnownBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1);        KnownZero <<= ShAmt;        KnownOne  <<= ShAmt;        // low bits known zero.        KnownZero |= APInt::getLowBitsSet(BitWidth, ShAmt);      } -    return; +    break;    case ISD::SRL:      // (ushr X, C1) & C2 == 0   iff  (-1 >> C1) & C2 == 0      if (ConstantSDNode *SA = dyn_cast<ConstantSDNode>(Op.getOperand(1))) { @@ -1909,31 +2089,29 @@ void SelectionDAG::ComputeMaskedBits(SDValue Op, APInt &KnownZero,        // If the shift count is an invalid immediate, don't do anything.        if (ShAmt >= BitWidth) -        return; +        break; -      ComputeMaskedBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1); -      assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); +      computeKnownBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1);        KnownZero = KnownZero.lshr(ShAmt);        KnownOne  = KnownOne.lshr(ShAmt);        APInt HighBits = APInt::getHighBitsSet(BitWidth, ShAmt);        KnownZero |= HighBits;  // High bits known zero.      } -    return; +    break;    case ISD::SRA:      if (ConstantSDNode *SA = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {        unsigned ShAmt = SA->getZExtValue();        // If the shift count is an invalid immediate, don't do anything.        if (ShAmt >= BitWidth) -        return; +        break;        // If any of the demanded bits are produced by the sign extension, we also        // demand the input sign bit.        APInt HighBits = APInt::getHighBitsSet(BitWidth, ShAmt); -      ComputeMaskedBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1); -      assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); +      computeKnownBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1);        KnownZero = KnownZero.lshr(ShAmt);        KnownOne  = KnownOne.lshr(ShAmt); @@ -1947,7 +2125,7 @@ void SelectionDAG::ComputeMaskedBits(SDValue Op, APInt &KnownZero,          KnownOne  |= HighBits;  // New bits are known one.        }      } -    return; +    break;    case ISD::SIGN_EXTEND_INREG: {      EVT EVT = cast<VTSDNode>(Op.getOperand(1))->getVT();      unsigned EBits = EVT.getScalarType().getSizeInBits(); @@ -1965,10 +2143,9 @@ void SelectionDAG::ComputeMaskedBits(SDValue Op, APInt &KnownZero,      if (NewBits.getBoolValue())        InputDemandedBits |= InSignBit; -    ComputeMaskedBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1); +    computeKnownBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1);      KnownOne &= InputDemandedBits;      KnownZero &= InputDemandedBits; -    assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");      // If the sign bit of the input is known set or clear, then we know the      // top bits of the result. @@ -1982,7 +2159,7 @@ void SelectionDAG::ComputeMaskedBits(SDValue Op, APInt &KnownZero,        KnownZero &= ~NewBits;        KnownOne  &= ~NewBits;      } -    return; +    break;    }    case ISD::CTTZ:    case ISD::CTTZ_ZERO_UNDEF: @@ -1992,7 +2169,7 @@ void SelectionDAG::ComputeMaskedBits(SDValue Op, APInt &KnownZero,      unsigned LowBits = Log2_32(BitWidth)+1;      KnownZero = APInt::getHighBitsSet(BitWidth, BitWidth - LowBits);      KnownOne.clearAllBits(); -    return; +    break;    }    case ISD::LOAD: {      LoadSDNode *LD = cast<LoadSDNode>(Op); @@ -2002,9 +2179,9 @@ void SelectionDAG::ComputeMaskedBits(SDValue Op, APInt &KnownZero,        unsigned MemBits = VT.getScalarType().getSizeInBits();        KnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - MemBits);      } else if (const MDNode *Ranges = LD->getRanges()) { -      computeMaskedBitsLoad(*Ranges, KnownZero); +      computeKnownBitsFromRangeMetadata(*Ranges, KnownZero);      } -    return; +    break;    }    case ISD::ZERO_EXTEND: {      EVT InVT = Op.getOperand(0).getValueType(); @@ -2012,11 +2189,11 @@ void SelectionDAG::ComputeMaskedBits(SDValue Op, APInt &KnownZero,      APInt NewBits   = APInt::getHighBitsSet(BitWidth, BitWidth - InBits);      KnownZero = KnownZero.trunc(InBits);      KnownOne = KnownOne.trunc(InBits); -    ComputeMaskedBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1); +    computeKnownBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1);      KnownZero = KnownZero.zext(BitWidth);      KnownOne = KnownOne.zext(BitWidth);      KnownZero |= NewBits; -    return; +    break;    }    case ISD::SIGN_EXTEND: {      EVT InVT = Op.getOperand(0).getValueType(); @@ -2025,13 +2202,11 @@ void SelectionDAG::ComputeMaskedBits(SDValue Op, APInt &KnownZero,      KnownZero = KnownZero.trunc(InBits);      KnownOne = KnownOne.trunc(InBits); -    ComputeMaskedBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1); +    computeKnownBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1);      // Note if the sign bit is known to be zero or one.      bool SignBitKnownZero = KnownZero.isNegative();      bool SignBitKnownOne  = KnownOne.isNegative(); -    assert(!(SignBitKnownZero && SignBitKnownOne) && -           "Sign bit can't be known to be both zero and one!");      KnownZero = KnownZero.zext(BitWidth);      KnownOne = KnownOne.zext(BitWidth); @@ -2041,25 +2216,24 @@ void SelectionDAG::ComputeMaskedBits(SDValue Op, APInt &KnownZero,        KnownZero |= NewBits;      else if (SignBitKnownOne)        KnownOne  |= NewBits; -    return; +    break;    }    case ISD::ANY_EXTEND: {      EVT InVT = Op.getOperand(0).getValueType();      unsigned InBits = InVT.getScalarType().getSizeInBits();      KnownZero = KnownZero.trunc(InBits);      KnownOne = KnownOne.trunc(InBits); -    ComputeMaskedBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1); +    computeKnownBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1);      KnownZero = KnownZero.zext(BitWidth);      KnownOne = KnownOne.zext(BitWidth); -    return; +    break;    }    case ISD::TRUNCATE: {      EVT InVT = Op.getOperand(0).getValueType();      unsigned InBits = InVT.getScalarType().getSizeInBits();      KnownZero = KnownZero.zext(InBits);      KnownOne = KnownOne.zext(InBits); -    ComputeMaskedBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1); -    assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?"); +    computeKnownBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1);      KnownZero = KnownZero.trunc(BitWidth);      KnownOne = KnownOne.trunc(BitWidth);      break; @@ -2067,15 +2241,15 @@ void SelectionDAG::ComputeMaskedBits(SDValue Op, APInt &KnownZero,    case ISD::AssertZext: {      EVT VT = cast<VTSDNode>(Op.getOperand(1))->getVT();      APInt InMask = APInt::getLowBitsSet(BitWidth, VT.getSizeInBits()); -    ComputeMaskedBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1); +    computeKnownBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1);      KnownZero |= (~InMask);      KnownOne  &= (~KnownZero); -    return; +    break;    }    case ISD::FGETSIGN:      // All bits are zero except the low bit.      KnownZero = APInt::getHighBitsSet(BitWidth, BitWidth - 1); -    return; +    break;    case ISD::SUB: {      if (ConstantSDNode *CLHS = dyn_cast<ConstantSDNode>(Op.getOperand(0))) { @@ -2086,7 +2260,7 @@ void SelectionDAG::ComputeMaskedBits(SDValue Op, APInt &KnownZero,          unsigned NLZ = (CLHS->getAPIntValue()+1).countLeadingZeros();          // NLZ can't be BitWidth with no sign bit          APInt MaskV = APInt::getHighBitsSet(BitWidth, NLZ+1); -        ComputeMaskedBits(Op.getOperand(1), KnownZero2, KnownOne2, Depth+1); +        computeKnownBits(Op.getOperand(1), KnownZero2, KnownOne2, Depth+1);          // If all of the MaskV bits are known to be zero, then we know the          // output top bits are zero, because we now know that the output is @@ -2105,18 +2279,16 @@ void SelectionDAG::ComputeMaskedBits(SDValue Op, APInt &KnownZero,      // Output known-0 bits are known if clear or set in both the low clear bits      // common to both LHS & RHS.  For example, 8+(X<<3) is known to have the      // low 3 bits clear. -    ComputeMaskedBits(Op.getOperand(0), KnownZero2, KnownOne2, Depth+1); -    assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?"); +    computeKnownBits(Op.getOperand(0), KnownZero2, KnownOne2, Depth+1);      unsigned KnownZeroOut = KnownZero2.countTrailingOnes(); -    ComputeMaskedBits(Op.getOperand(1), KnownZero2, KnownOne2, Depth+1); -    assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?"); +    computeKnownBits(Op.getOperand(1), KnownZero2, KnownOne2, Depth+1);      KnownZeroOut = std::min(KnownZeroOut,                              KnownZero2.countTrailingOnes());      if (Op.getOpcode() == ISD::ADD) {        KnownZero |= APInt::getLowBitsSet(BitWidth, KnownZeroOut); -      return; +      break;      }      // With ADDE, a carry bit may be added in, so we can only use this @@ -2125,14 +2297,14 @@ void SelectionDAG::ComputeMaskedBits(SDValue Op, APInt &KnownZero,      // are known zero.      if (KnownZeroOut >= 2) // ADDE        KnownZero |= APInt::getBitsSet(BitWidth, 1, KnownZeroOut); -    return; +    break;    }    case ISD::SREM:      if (ConstantSDNode *Rem = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {        const APInt &RA = Rem->getAPIntValue().abs();        if (RA.isPowerOf2()) {          APInt LowBits = RA - 1; -        ComputeMaskedBits(Op.getOperand(0), KnownZero2,KnownOne2,Depth+1); +        computeKnownBits(Op.getOperand(0), KnownZero2,KnownOne2,Depth+1);          // The low bits of the first operand are unchanged by the srem.          KnownZero = KnownZero2 & LowBits; @@ -2150,36 +2322,38 @@ void SelectionDAG::ComputeMaskedBits(SDValue Op, APInt &KnownZero,          assert((KnownZero & KnownOne) == 0&&"Bits known to be one AND zero?");        }      } -    return; +    break;    case ISD::UREM: {      if (ConstantSDNode *Rem = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {        const APInt &RA = Rem->getAPIntValue();        if (RA.isPowerOf2()) {          APInt LowBits = (RA - 1); -        KnownZero |= ~LowBits; -        ComputeMaskedBits(Op.getOperand(0), KnownZero, KnownOne,Depth+1); -        assert((KnownZero & KnownOne) == 0&&"Bits known to be one AND zero?"); +        computeKnownBits(Op.getOperand(0), KnownZero2, KnownOne2, Depth + 1); + +        // The upper bits are all zero, the lower ones are unchanged. +        KnownZero = KnownZero2 | ~LowBits; +        KnownOne = KnownOne2 & LowBits;          break;        }      }      // Since the result is less than or equal to either operand, any leading      // zero bits in either operand must also exist in the result. -    ComputeMaskedBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1); -    ComputeMaskedBits(Op.getOperand(1), KnownZero2, KnownOne2, Depth+1); +    computeKnownBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1); +    computeKnownBits(Op.getOperand(1), KnownZero2, KnownOne2, Depth+1);      uint32_t Leaders = std::max(KnownZero.countLeadingOnes(),                                  KnownZero2.countLeadingOnes());      KnownOne.clearAllBits();      KnownZero = APInt::getHighBitsSet(BitWidth, Leaders); -    return; +    break;    }    case ISD::FrameIndex:    case ISD::TargetFrameIndex:      if (unsigned Align = InferPtrAlignment(Op)) {        // The low bits are known zero if the pointer is aligned.        KnownZero = APInt::getLowBitsSet(BitWidth, Log2_32(Align)); -      return; +      break;      }      break; @@ -2191,9 +2365,11 @@ void SelectionDAG::ComputeMaskedBits(SDValue Op, APInt &KnownZero,    case ISD::INTRINSIC_W_CHAIN:    case ISD::INTRINSIC_VOID:      // Allow the target to implement this method for its nodes. -    TLI->computeMaskedBitsForTargetNode(Op, KnownZero, KnownOne, *this, Depth); -    return; +    TLI->computeKnownBitsForTargetNode(Op, KnownZero, KnownOne, *this, Depth); +    break;    } + +  assert((KnownZero & KnownOne) == 0 && "Bits known to be one AND zero?");  }  /// ComputeNumSignBits - Return the number of times the sign bit of the @@ -2267,7 +2443,7 @@ unsigned SelectionDAG::ComputeNumSignBits(SDValue Op, unsigned Depth) const{        FirstAnswer = std::min(Tmp, Tmp2);        // We computed what we know about the sign bits as our first        // answer. Now proceed to the generic code that uses -      // ComputeMaskedBits, and pick whichever answer is better. +      // computeKnownBits, and pick whichever answer is better.      }      break; @@ -2286,9 +2462,16 @@ unsigned SelectionDAG::ComputeNumSignBits(SDValue Op, unsigned Depth) const{      if (Op.getResNo() != 1)        break;      // The boolean result conforms to getBooleanContents.  Fall through. +    // If setcc returns 0/-1, all bits are sign bits. +    // We know that we have an integer-based boolean since these operations +    // are only available for integer. +    if (TLI->getBooleanContents(Op.getValueType().isVector(), false) == +        TargetLowering::ZeroOrNegativeOneBooleanContent) +      return VTBits; +    break;    case ISD::SETCC:      // If setcc returns 0/-1, all bits are sign bits. -    if (TLI->getBooleanContents(Op.getValueType().isVector()) == +    if (TLI->getBooleanContents(Op.getOperand(0).getValueType()) ==          TargetLowering::ZeroOrNegativeOneBooleanContent)        return VTBits;      break; @@ -2317,7 +2500,7 @@ unsigned SelectionDAG::ComputeNumSignBits(SDValue Op, unsigned Depth) const{      if (ConstantSDNode *CRHS = dyn_cast<ConstantSDNode>(Op.getOperand(1)))        if (CRHS->isAllOnesValue()) {          APInt KnownZero, KnownOne; -        ComputeMaskedBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1); +        computeKnownBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1);          // If the input is known to be 0 or 1, the output is 0/-1, which is all          // sign bits set. @@ -2342,7 +2525,7 @@ unsigned SelectionDAG::ComputeNumSignBits(SDValue Op, unsigned Depth) const{      if (ConstantSDNode *CLHS = dyn_cast<ConstantSDNode>(Op.getOperand(0)))        if (CLHS->isNullValue()) {          APInt KnownZero, KnownOne; -        ComputeMaskedBits(Op.getOperand(1), KnownZero, KnownOne, Depth+1); +        computeKnownBits(Op.getOperand(1), KnownZero, KnownOne, Depth+1);          // If the input is known to be 0 or 1, the output is 0/-1, which is all          // sign bits set.          if ((KnownZero | APInt(VTBits, 1)).isAllOnesValue()) @@ -2389,14 +2572,14 @@ unsigned SelectionDAG::ComputeNumSignBits(SDValue Op, unsigned Depth) const{        Op.getOpcode() == ISD::INTRINSIC_WO_CHAIN ||        Op.getOpcode() == ISD::INTRINSIC_W_CHAIN ||        Op.getOpcode() == ISD::INTRINSIC_VOID) { -    unsigned NumBits = TLI->ComputeNumSignBitsForTargetNode(Op, Depth); +    unsigned NumBits = TLI->ComputeNumSignBitsForTargetNode(Op, *this, Depth);      if (NumBits > 1) FirstAnswer = std::max(FirstAnswer, NumBits);    }    // Finally, if we can prove that the top bits of the result are 0's or 1's,    // use this information.    APInt KnownZero, KnownOne; -  ComputeMaskedBits(Op, KnownZero, KnownOne, Depth); +  computeKnownBits(Op, KnownZero, KnownOne, Depth);    APInt Mask;    if (KnownZero.isNegative()) {        // sign bit is 0 @@ -2484,8 +2667,8 @@ bool SelectionDAG::isEqualTo(SDValue A, SDValue B) const {  ///  SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, EVT VT) {    FoldingSetNodeID ID; -  AddNodeIDNode(ID, Opcode, getVTList(VT), 0, 0); -  void *IP = 0; +  AddNodeIDNode(ID, Opcode, getVTList(VT), None); +  void *IP = nullptr;    if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))      return SDValue(E, 0); @@ -2502,17 +2685,23 @@ SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, EVT VT) {  SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL,                                EVT VT, SDValue Operand) { -  // Constant fold unary operations with an integer constant operand. +  // Constant fold unary operations with an integer constant operand. Even +  // opaque constant will be folded, because the folding of unary operations +  // doesn't create new constants with different values. Nevertheless, the +  // opaque flag is preserved during folding to prevent future folding with +  // other constants.    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Operand.getNode())) {      const APInt &Val = C->getAPIntValue();      switch (Opcode) {      default: break;      case ISD::SIGN_EXTEND: -      return getConstant(Val.sextOrTrunc(VT.getSizeInBits()), VT); +      return getConstant(Val.sextOrTrunc(VT.getSizeInBits()), VT, +                         C->isTargetOpcode(), C->isOpaque());      case ISD::ANY_EXTEND:      case ISD::ZERO_EXTEND:      case ISD::TRUNCATE: -      return getConstant(Val.zextOrTrunc(VT.getSizeInBits()), VT); +      return getConstant(Val.zextOrTrunc(VT.getSizeInBits()), VT, +                         C->isTargetOpcode(), C->isOpaque());      case ISD::UINT_TO_FP:      case ISD::SINT_TO_FP: {        APFloat apf(EVTToAPFloatSemantics(VT), @@ -2529,15 +2718,19 @@ SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL,          return getConstantFP(APFloat(APFloat::IEEEdouble, Val), VT);        break;      case ISD::BSWAP: -      return getConstant(Val.byteSwap(), VT); +      return getConstant(Val.byteSwap(), VT, C->isTargetOpcode(), +                         C->isOpaque());      case ISD::CTPOP: -      return getConstant(Val.countPopulation(), VT); +      return getConstant(Val.countPopulation(), VT, C->isTargetOpcode(), +                         C->isOpaque());      case ISD::CTLZ:      case ISD::CTLZ_ZERO_UNDEF: -      return getConstant(Val.countLeadingZeros(), VT); +      return getConstant(Val.countLeadingZeros(), VT, C->isTargetOpcode(), +                         C->isOpaque());      case ISD::CTTZ:      case ISD::CTTZ_ZERO_UNDEF: -      return getConstant(Val.countTrailingZeros(), VT); +      return getConstant(Val.countTrailingZeros(), VT, C->isTargetOpcode(), +                         C->isOpaque());      }    } @@ -2600,6 +2793,31 @@ SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL,      }    } +  // Constant fold unary operations with a vector integer operand. +  if (BuildVectorSDNode *BV = dyn_cast<BuildVectorSDNode>(Operand.getNode())) { +    if (BV->isConstant()) { +      switch (Opcode) { +      default: +        // FIXME: Entirely reasonable to perform folding of other unary +        // operations here as the need arises. +        break; +      case ISD::UINT_TO_FP: +      case ISD::SINT_TO_FP: { +        SmallVector<SDValue, 8> Ops; +        for (int i = 0, e = VT.getVectorNumElements(); i != e; ++i) { +          SDValue OpN = BV->getOperand(i); +          // Let the above scalar folding handle the conversion of each +          // element. +          OpN = getNode(ISD::SINT_TO_FP, DL, VT.getVectorElementType(), +                        OpN); +          Ops.push_back(OpN); +        } +        return getNode(ISD::BUILD_VECTOR, DL, VT, Ops); +      } +      } +    } +  } +    unsigned OpOpcode = Operand.getNode()->getOpcode();    switch (Opcode) {    case ISD::TokenFactor: @@ -2746,8 +2964,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL,    if (VT != MVT::Glue) { // Don't CSE flag producing nodes      FoldingSetNodeID ID;      SDValue Ops[1] = { Operand }; -    AddNodeIDNode(ID, Opcode, VTs, Ops, 1); -    void *IP = 0; +    AddNodeIDNode(ID, Opcode, VTs, Ops); +    void *IP = nullptr;      if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))        return SDValue(E, 0); @@ -2768,16 +2986,25 @@ SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL,  SDValue SelectionDAG::FoldConstantArithmetic(unsigned Opcode, EVT VT,                                               SDNode *Cst1, SDNode *Cst2) { +  // If the opcode is a target-specific ISD node, there's nothing we can +  // do here and the operand rules may not line up with the below, so +  // bail early. +  if (Opcode >= ISD::BUILTIN_OP_END) +    return SDValue(); +    SmallVector<std::pair<ConstantSDNode *, ConstantSDNode *>, 4> Inputs;    SmallVector<SDValue, 4> Outputs;    EVT SVT = VT.getScalarType();    ConstantSDNode *Scalar1 = dyn_cast<ConstantSDNode>(Cst1);    ConstantSDNode *Scalar2 = dyn_cast<ConstantSDNode>(Cst2); -  if (Scalar1 && Scalar2) { +  if (Scalar1 && Scalar2 && (Scalar1->isOpaque() || Scalar2->isOpaque())) +    return SDValue(); + +  if (Scalar1 && Scalar2)      // Scalar instruction.      Inputs.push_back(std::make_pair(Scalar1, Scalar2)); -  } else { +  else {      // For vectors extract each constant element into Inputs so we can constant      // fold them individually.      BuildVectorSDNode *BV1 = dyn_cast<BuildVectorSDNode>(Cst1); @@ -2793,6 +3020,9 @@ SDValue SelectionDAG::FoldConstantArithmetic(unsigned Opcode, EVT VT,        if (!V1 || !V2) // Not a constant, bail.          return SDValue(); +      if (V1->isOpaque() || V2->isOpaque()) +        return SDValue(); +        // Avoid BUILD_VECTOR nodes that perform implicit truncation.        // FIXME: This is valid and could be handled by truncating the APInts.        if (V1->getValueType(0) != SVT || V2->getValueType(0) != SVT) @@ -2866,17 +3096,22 @@ SDValue SelectionDAG::FoldConstantArithmetic(unsigned Opcode, EVT VT,      }    } +  assert((Scalar1 && Scalar2) || (VT.getVectorNumElements() == Outputs.size() && +                                  "Expected a scalar or vector!")); +    // Handle the scalar case first. -  if (Scalar1 && Scalar2) +  if (!VT.isVector())      return Outputs.back(); -  // Otherwise build a big vector out of the scalar elements we generated. -  return getNode(ISD::BUILD_VECTOR, SDLoc(), VT, Outputs.data(), -                 Outputs.size()); +  // We may have a vector type but a scalar result. Create a splat. +  Outputs.resize(VT.getVectorNumElements(), Outputs.back()); + +  // Build a big vector out of the scalar elements we generated. +  return getNode(ISD::BUILD_VECTOR, SDLoc(), VT, Outputs);  }  SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, EVT VT, SDValue N1, -                              SDValue N2) { +                              SDValue N2, bool nuw, bool nsw, bool exact) {    ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.getNode());    ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2.getNode());    switch (Opcode) { @@ -2902,7 +3137,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, EVT VT, SDValue N1,        SmallVector<SDValue, 16> Elts(N1.getNode()->op_begin(),                                      N1.getNode()->op_end());        Elts.append(N2.getNode()->op_begin(), N2.getNode()->op_end()); -      return getNode(ISD::BUILD_VECTOR, DL, VT, &Elts[0], Elts.size()); +      return getNode(ISD::BUILD_VECTOR, DL, VT, Elts);      }      break;    case ISD::AND: @@ -3316,22 +3551,25 @@ SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, EVT VT, SDValue N1,    }    // Memoize this node if possible. -  SDNode *N; +  BinarySDNode *N;    SDVTList VTs = getVTList(VT); +  const bool BinOpHasFlags = isBinOpWithFlags(Opcode);    if (VT != MVT::Glue) { -    SDValue Ops[] = { N1, N2 }; +    SDValue Ops[] = {N1, N2};      FoldingSetNodeID ID; -    AddNodeIDNode(ID, Opcode, VTs, Ops, 2); -    void *IP = 0; +    AddNodeIDNode(ID, Opcode, VTs, Ops); +    if (BinOpHasFlags) +      AddBinaryNodeIDCustom(ID, Opcode, nuw, nsw, exact); +    void *IP = nullptr;      if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))        return SDValue(E, 0); -    N = new (NodeAllocator) BinarySDNode(Opcode, DL.getIROrder(), -                                         DL.getDebugLoc(), VTs, N1, N2); +    N = GetBinarySDNode(Opcode, DL, VTs, N1, N2, nuw, nsw, exact); +      CSEMap.InsertNode(N, IP);    } else { -    N = new (NodeAllocator) BinarySDNode(Opcode, DL.getIROrder(), -                                         DL.getDebugLoc(), VTs, N1, N2); + +    N = GetBinarySDNode(Opcode, DL, VTs, N1, N2, nuw, nsw, exact);    }    AllNodes.push_back(N); @@ -3371,7 +3609,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, EVT VT,                                      N1.getNode()->op_end());        Elts.append(N2.getNode()->op_begin(), N2.getNode()->op_end());        Elts.append(N3.getNode()->op_begin(), N3.getNode()->op_end()); -      return getNode(ISD::BUILD_VECTOR, DL, VT, &Elts[0], Elts.size()); +      return getNode(ISD::BUILD_VECTOR, DL, VT, Elts);      }      break;    case ISD::SETCC: { @@ -3428,8 +3666,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, EVT VT,    if (VT != MVT::Glue) {      SDValue Ops[] = { N1, N2, N3 };      FoldingSetNodeID ID; -    AddNodeIDNode(ID, Opcode, VTs, Ops, 3); -    void *IP = 0; +    AddNodeIDNode(ID, Opcode, VTs, Ops); +    void *IP = nullptr;      if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))        return SDValue(E, 0); @@ -3452,14 +3690,14 @@ SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, EVT VT,                                SDValue N1, SDValue N2, SDValue N3,                                SDValue N4) {    SDValue Ops[] = { N1, N2, N3, N4 }; -  return getNode(Opcode, DL, VT, Ops, 4); +  return getNode(Opcode, DL, VT, Ops);  }  SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, EVT VT,                                SDValue N1, SDValue N2, SDValue N3,                                SDValue N4, SDValue N5) {    SDValue Ops[] = { N1, N2, N3, N4, N5 }; -  return getNode(Opcode, DL, VT, Ops, 5); +  return getNode(Opcode, DL, VT, Ops);  }  /// getStackArgumentTokenFactor - Compute a TokenFactor to force all @@ -3481,8 +3719,7 @@ SDValue SelectionDAG::getStackArgumentTokenFactor(SDValue Chain) {            ArgChains.push_back(SDValue(L, 1));    // Build a tokenfactor for all the chains. -  return getNode(ISD::TokenFactor, SDLoc(Chain), MVT::Other, -                 &ArgChains[0], ArgChains.size()); +  return getNode(ISD::TokenFactor, SDLoc(Chain), MVT::Other, ArgChains);  }  /// getMemsetValue - Vectorized representation of the memset value @@ -3520,7 +3757,7 @@ static SDValue getMemsetStringVal(EVT VT, SDLoc dl, SelectionDAG &DAG,    if (Str.empty()) {      if (VT.isInteger())        return DAG.getConstant(0, VT); -    else if (VT == MVT::f32 || VT == MVT::f64) +    else if (VT == MVT::f32 || VT == MVT::f64 || VT == MVT::f128)        return DAG.getConstantFP(0.0, VT);      else if (VT.isVector()) {        unsigned NumElts = VT.getVectorNumElements(); @@ -3546,12 +3783,12 @@ static SDValue getMemsetStringVal(EVT VT, SDLoc dl, SelectionDAG &DAG,        Val |= (uint64_t)(unsigned char)Str[i] << (NumVTBytes-i-1)*8;    } -  // If the "cost" of materializing the integer immediate is 1 or free, then -  // it is cost effective to turn the load into the immediate. -  const TargetTransformInfo *TTI = DAG.getTargetTransformInfo(); -  if (TTI->getIntImmCost(Val, VT.getTypeForEVT(*DAG.getContext())) < 2) +  // If the "cost" of materializing the integer immediate is less than the cost +  // of a load, then it is cost effective to turn the load into the immediate. +  Type *Ty = VT.getTypeForEVT(*DAG.getContext()); +  if (TLI.shouldConvertConstantLoadToIntImm(Val, Ty))      return DAG.getConstant(Val, VT); -  return SDValue(0, 0); +  return SDValue(nullptr, 0);  }  /// getMemBasePlusOffset - Returns base and offset node for the @@ -3567,7 +3804,7 @@ static SDValue getMemBasePlusOffset(SDValue Base, unsigned Offset, SDLoc dl,  ///  static bool isMemSrcFromString(SDValue Src, StringRef &Str) {    unsigned SrcDelta = 0; -  GlobalAddressSDNode *G = NULL; +  GlobalAddressSDNode *G = nullptr;    if (Src.getOpcode() == ISD::GlobalAddress)      G = cast<GlobalAddressSDNode>(Src);    else if (Src.getOpcode() == ISD::ADD && @@ -3609,8 +3846,9 @@ static bool FindOptimalMemOpLowering(std::vector<EVT> &MemOps,                                     DAG.getMachineFunction());    if (VT == MVT::Other) { -    if (DstAlign >= TLI.getDataLayout()->getPointerPrefAlignment() || -        TLI.allowsUnalignedMemoryAccesses(VT)) { +    unsigned AS = 0; +    if (DstAlign >= TLI.getDataLayout()->getPointerPrefAlignment(AS) || +        TLI.allowsUnalignedMemoryAccesses(VT, AS)) {        VT = TLI.getPointerTy();      } else {        switch (DstAlign & 7) { @@ -3667,9 +3905,10 @@ static bool FindOptimalMemOpLowering(std::vector<EVT> &MemOps,        // FIXME: Only does this for 64-bit or more since we don't have proper        // cost model for unaligned load / store.        bool Fast; +      unsigned AS = 0;        if (NumMemOps && AllowOverlap &&            VTSize >= 8 && NewVTSize < Size && -          TLI.allowsUnalignedMemoryAccesses(VT, &Fast) && Fast) +          TLI.allowsUnalignedMemoryAccesses(VT, AS, &Fast) && Fast)          VTSize = Size;        else {          VT = NewVT; @@ -3801,8 +4040,7 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, SDLoc dl,      Size -= VTSize;    } -  return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, -                     &OutChains[0], OutChains.size()); +  return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains);  }  static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, SDLoc dl, @@ -3867,8 +4105,7 @@ static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, SDLoc dl,      LoadChains.push_back(Value.getValue(1));      SrcOff += VTSize;    } -  Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, -                      &LoadChains[0], LoadChains.size()); +  Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, LoadChains);    OutChains.clear();    for (unsigned i = 0; i < NumMemOps; i++) {      EVT VT = MemOps[i]; @@ -3882,8 +4119,7 @@ static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, SDLoc dl,      DstOff += VTSize;    } -  return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, -                     &OutChains[0], OutChains.size()); +  return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains);  }  /// \brief Lower the call to 'memset' intrinsic function into a series of store @@ -3984,8 +4220,7 @@ static SDValue getMemsetStores(SelectionDAG &DAG, SDLoc dl,      Size -= VTSize;    } -  return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, -                     &OutChains[0], OutChains.size()); +  return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains);  }  SDValue SelectionDAG::getMemcpy(SDValue Chain, SDLoc dl, SDValue Dst, @@ -4044,15 +4279,13 @@ SDValue SelectionDAG::getMemcpy(SDValue Chain, SDLoc dl, SDValue Dst,    Entry.Node = Src; Args.push_back(Entry);    Entry.Node = Size; Args.push_back(Entry);    // FIXME: pass in SDLoc -  TargetLowering:: -  CallLoweringInfo CLI(Chain, Type::getVoidTy(*getContext()), -                    false, false, false, false, 0, -                    TLI->getLibcallCallingConv(RTLIB::MEMCPY), -                    /*isTailCall=*/false, -                    /*doesNotReturn=*/false, /*isReturnValueUsed=*/false, -                    getExternalSymbol(TLI->getLibcallName(RTLIB::MEMCPY), -                                      TLI->getPointerTy()), -                    Args, *this, dl); +  TargetLowering::CallLoweringInfo CLI(*this); +  CLI.setDebugLoc(dl).setChain(Chain) +    .setCallee(TLI->getLibcallCallingConv(RTLIB::MEMCPY), +               Type::getVoidTy(*getContext()), +               getExternalSymbol(TLI->getLibcallName(RTLIB::MEMCPY), +                                 TLI->getPointerTy()), std::move(Args), 0) +    .setDiscardResult();    std::pair<SDValue,SDValue> CallResult = TLI->LowerCallTo(CLI);    return CallResult.second; @@ -4102,15 +4335,13 @@ SDValue SelectionDAG::getMemmove(SDValue Chain, SDLoc dl, SDValue Dst,    Entry.Node = Src; Args.push_back(Entry);    Entry.Node = Size; Args.push_back(Entry);    // FIXME:  pass in SDLoc -  TargetLowering:: -  CallLoweringInfo CLI(Chain, Type::getVoidTy(*getContext()), -                    false, false, false, false, 0, -                    TLI->getLibcallCallingConv(RTLIB::MEMMOVE), -                    /*isTailCall=*/false, -                    /*doesNotReturn=*/false, /*isReturnValueUsed=*/false, -                    getExternalSymbol(TLI->getLibcallName(RTLIB::MEMMOVE), -                                      TLI->getPointerTy()), -                    Args, *this, dl); +  TargetLowering::CallLoweringInfo CLI(*this); +  CLI.setDebugLoc(dl).setChain(Chain) +    .setCallee(TLI->getLibcallCallingConv(RTLIB::MEMMOVE), +               Type::getVoidTy(*getContext()), +               getExternalSymbol(TLI->getLibcallName(RTLIB::MEMMOVE), +                                 TLI->getPointerTy()), std::move(Args), 0) +    .setDiscardResult();    std::pair<SDValue,SDValue> CallResult = TLI->LowerCallTo(CLI);    return CallResult.second; @@ -4166,31 +4397,31 @@ SDValue SelectionDAG::getMemset(SDValue Chain, SDLoc dl, SDValue Dst,    Entry.Ty = IntPtrTy;    Entry.isSExt = false;    Args.push_back(Entry); +    // FIXME: pass in SDLoc -  TargetLowering:: -  CallLoweringInfo CLI(Chain, Type::getVoidTy(*getContext()), -                    false, false, false, false, 0, -                    TLI->getLibcallCallingConv(RTLIB::MEMSET), -                    /*isTailCall=*/false, -                    /*doesNotReturn*/false, /*isReturnValueUsed=*/false, -                    getExternalSymbol(TLI->getLibcallName(RTLIB::MEMSET), -                                      TLI->getPointerTy()), -                    Args, *this, dl); -  std::pair<SDValue,SDValue> CallResult = TLI->LowerCallTo(CLI); +  TargetLowering::CallLoweringInfo CLI(*this); +  CLI.setDebugLoc(dl).setChain(Chain) +    .setCallee(TLI->getLibcallCallingConv(RTLIB::MEMSET), +               Type::getVoidTy(*getContext()), +               getExternalSymbol(TLI->getLibcallName(RTLIB::MEMSET), +                                 TLI->getPointerTy()), std::move(Args), 0) +    .setDiscardResult(); +  std::pair<SDValue,SDValue> CallResult = TLI->LowerCallTo(CLI);    return CallResult.second;  }  SDValue SelectionDAG::getAtomic(unsigned Opcode, SDLoc dl, EVT MemVT, -                                SDVTList VTList, SDValue* Ops, unsigned NumOps, +                                SDVTList VTList, ArrayRef<SDValue> Ops,                                  MachineMemOperand *MMO, -                                AtomicOrdering Ordering, +                                AtomicOrdering SuccessOrdering, +                                AtomicOrdering FailureOrdering,                                  SynchronizationScope SynchScope) {    FoldingSetNodeID ID;    ID.AddInteger(MemVT.getRawBits()); -  AddNodeIDNode(ID, Opcode, VTList, Ops, NumOps); +  AddNodeIDNode(ID, Opcode, VTList, Ops);    ID.AddInteger(MMO->getPointerInfo().getAddrSpace()); -  void* IP = 0; +  void* IP = nullptr;    if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) {      cast<AtomicSDNode>(E)->refineAlignment(MMO);      return SDValue(E, 0); @@ -4201,59 +4432,70 @@ SDValue SelectionDAG::getAtomic(unsigned Opcode, SDLoc dl, EVT MemVT,    // the node is deallocated, but recovered when the allocator is released.    // If the number of operands is less than 5 we use AtomicSDNode's internal    // storage. -  SDUse *DynOps = NumOps > 4 ? OperandAllocator.Allocate<SDUse>(NumOps) : 0; +  unsigned NumOps = Ops.size(); +  SDUse *DynOps = NumOps > 4 ? OperandAllocator.Allocate<SDUse>(NumOps) +                             : nullptr;    SDNode *N = new (NodeAllocator) AtomicSDNode(Opcode, dl.getIROrder(),                                                 dl.getDebugLoc(), VTList, MemVT, -                                               Ops, DynOps, NumOps, MMO, -                                               Ordering, SynchScope); +                                               Ops.data(), DynOps, NumOps, MMO, +                                               SuccessOrdering, FailureOrdering, +                                               SynchScope);    CSEMap.InsertNode(N, IP);    AllNodes.push_back(N);    return SDValue(N, 0);  }  SDValue SelectionDAG::getAtomic(unsigned Opcode, SDLoc dl, EVT MemVT, -                                SDValue Chain, SDValue Ptr, SDValue Cmp, -                                SDValue Swp, MachinePointerInfo PtrInfo, -                                unsigned Alignment, +                                SDVTList VTList, ArrayRef<SDValue> Ops, +                                MachineMemOperand *MMO,                                  AtomicOrdering Ordering,                                  SynchronizationScope SynchScope) { +  return getAtomic(Opcode, dl, MemVT, VTList, Ops, MMO, Ordering, +                   Ordering, SynchScope); +} + +SDValue SelectionDAG::getAtomicCmpSwap( +    unsigned Opcode, SDLoc dl, EVT MemVT, SDVTList VTs, SDValue Chain, +    SDValue Ptr, SDValue Cmp, SDValue Swp, MachinePointerInfo PtrInfo, +    unsigned Alignment, AtomicOrdering SuccessOrdering, +    AtomicOrdering FailureOrdering, SynchronizationScope SynchScope) { +  assert(Opcode == ISD::ATOMIC_CMP_SWAP || +         Opcode == ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS); +  assert(Cmp.getValueType() == Swp.getValueType() && "Invalid Atomic Op Types"); +    if (Alignment == 0)  // Ensure that codegen never sees alignment 0      Alignment = getEVTAlignment(MemVT);    MachineFunction &MF = getMachineFunction(); -  // All atomics are load and store, except for ATMOIC_LOAD and ATOMIC_STORE. -  // For now, atomics are considered to be volatile always.    // FIXME: Volatile isn't really correct; we should keep track of atomic    // orderings in the memoperand.    unsigned Flags = MachineMemOperand::MOVolatile; -  if (Opcode != ISD::ATOMIC_STORE) -    Flags |= MachineMemOperand::MOLoad; -  if (Opcode != ISD::ATOMIC_LOAD) -    Flags |= MachineMemOperand::MOStore; +  Flags |= MachineMemOperand::MOLoad; +  Flags |= MachineMemOperand::MOStore;    MachineMemOperand *MMO =      MF.getMachineMemOperand(PtrInfo, Flags, MemVT.getStoreSize(), Alignment); -  return getAtomic(Opcode, dl, MemVT, Chain, Ptr, Cmp, Swp, MMO, -                   Ordering, SynchScope); +  return getAtomicCmpSwap(Opcode, dl, MemVT, VTs, Chain, Ptr, Cmp, Swp, MMO, +                          SuccessOrdering, FailureOrdering, SynchScope);  } -SDValue SelectionDAG::getAtomic(unsigned Opcode, SDLoc dl, EVT MemVT, -                                SDValue Chain, -                                SDValue Ptr, SDValue Cmp, -                                SDValue Swp, MachineMemOperand *MMO, -                                AtomicOrdering Ordering, -                                SynchronizationScope SynchScope) { -  assert(Opcode == ISD::ATOMIC_CMP_SWAP && "Invalid Atomic Op"); +SDValue SelectionDAG::getAtomicCmpSwap(unsigned Opcode, SDLoc dl, EVT MemVT, +                                       SDVTList VTs, SDValue Chain, SDValue Ptr, +                                       SDValue Cmp, SDValue Swp, +                                       MachineMemOperand *MMO, +                                       AtomicOrdering SuccessOrdering, +                                       AtomicOrdering FailureOrdering, +                                       SynchronizationScope SynchScope) { +  assert(Opcode == ISD::ATOMIC_CMP_SWAP || +         Opcode == ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS);    assert(Cmp.getValueType() == Swp.getValueType() && "Invalid Atomic Op Types"); -  EVT VT = Cmp.getValueType(); - -  SDVTList VTs = getVTList(VT, MVT::Other);    SDValue Ops[] = {Chain, Ptr, Cmp, Swp}; -  return getAtomic(Opcode, dl, MemVT, VTs, Ops, 4, MMO, Ordering, SynchScope); +  return getAtomic(Opcode, dl, MemVT, VTs, Ops, MMO, +                   SuccessOrdering, FailureOrdering, SynchScope);  }  SDValue SelectionDAG::getAtomic(unsigned Opcode, SDLoc dl, EVT MemVT, @@ -4312,38 +4554,7 @@ SDValue SelectionDAG::getAtomic(unsigned Opcode, SDLoc dl, EVT MemVT,    SDVTList VTs = Opcode == ISD::ATOMIC_STORE ? getVTList(MVT::Other) :                                                 getVTList(VT, MVT::Other);    SDValue Ops[] = {Chain, Ptr, Val}; -  return getAtomic(Opcode, dl, MemVT, VTs, Ops, 3, MMO, Ordering, SynchScope); -} - -SDValue SelectionDAG::getAtomic(unsigned Opcode, SDLoc dl, EVT MemVT, -                                EVT VT, SDValue Chain, -                                SDValue Ptr, -                                const Value* PtrVal, -                                unsigned Alignment, -                                AtomicOrdering Ordering, -                                SynchronizationScope SynchScope) { -  if (Alignment == 0)  // Ensure that codegen never sees alignment 0 -    Alignment = getEVTAlignment(MemVT); - -  MachineFunction &MF = getMachineFunction(); -  // An atomic store does not load. An atomic load does not store. -  // (An atomicrmw obviously both loads and stores.) -  // For now, atomics are considered to be volatile always, and they are -  // chained as such. -  // FIXME: Volatile isn't really correct; we should keep track of atomic -  // orderings in the memoperand. -  unsigned Flags = MachineMemOperand::MOVolatile; -  if (Opcode != ISD::ATOMIC_STORE) -    Flags |= MachineMemOperand::MOLoad; -  if (Opcode != ISD::ATOMIC_LOAD) -    Flags |= MachineMemOperand::MOStore; - -  MachineMemOperand *MMO = -    MF.getMachineMemOperand(MachinePointerInfo(PtrVal), Flags, -                            MemVT.getStoreSize(), Alignment); - -  return getAtomic(Opcode, dl, MemVT, VT, Chain, Ptr, MMO, -                   Ordering, SynchScope); +  return getAtomic(Opcode, dl, MemVT, VTs, Ops, MMO, Ordering, SynchScope);  }  SDValue SelectionDAG::getAtomic(unsigned Opcode, SDLoc dl, EVT MemVT, @@ -4356,38 +4567,24 @@ SDValue SelectionDAG::getAtomic(unsigned Opcode, SDLoc dl, EVT MemVT,    SDVTList VTs = getVTList(VT, MVT::Other);    SDValue Ops[] = {Chain, Ptr}; -  return getAtomic(Opcode, dl, MemVT, VTs, Ops, 2, MMO, Ordering, SynchScope); +  return getAtomic(Opcode, dl, MemVT, VTs, Ops, MMO, Ordering, SynchScope);  }  /// getMergeValues - Create a MERGE_VALUES node from the given operands. -SDValue SelectionDAG::getMergeValues(const SDValue *Ops, unsigned NumOps, -                                     SDLoc dl) { -  if (NumOps == 1) +SDValue SelectionDAG::getMergeValues(ArrayRef<SDValue> Ops, SDLoc dl) { +  if (Ops.size() == 1)      return Ops[0];    SmallVector<EVT, 4> VTs; -  VTs.reserve(NumOps); -  for (unsigned i = 0; i < NumOps; ++i) +  VTs.reserve(Ops.size()); +  for (unsigned i = 0; i < Ops.size(); ++i)      VTs.push_back(Ops[i].getValueType()); -  return getNode(ISD::MERGE_VALUES, dl, getVTList(&VTs[0], NumOps), -                 Ops, NumOps); -} - -SDValue -SelectionDAG::getMemIntrinsicNode(unsigned Opcode, SDLoc dl, -                                  const EVT *VTs, unsigned NumVTs, -                                  const SDValue *Ops, unsigned NumOps, -                                  EVT MemVT, MachinePointerInfo PtrInfo, -                                  unsigned Align, bool Vol, -                                  bool ReadMem, bool WriteMem) { -  return getMemIntrinsicNode(Opcode, dl, makeVTList(VTs, NumVTs), Ops, NumOps, -                             MemVT, PtrInfo, Align, Vol, -                             ReadMem, WriteMem); +  return getNode(ISD::MERGE_VALUES, dl, getVTList(VTs), Ops);  }  SDValue  SelectionDAG::getMemIntrinsicNode(unsigned Opcode, SDLoc dl, SDVTList VTList, -                                  const SDValue *Ops, unsigned NumOps, +                                  ArrayRef<SDValue> Ops,                                    EVT MemVT, MachinePointerInfo PtrInfo,                                    unsigned Align, bool Vol,                                    bool ReadMem, bool WriteMem) { @@ -4405,13 +4602,13 @@ SelectionDAG::getMemIntrinsicNode(unsigned Opcode, SDLoc dl, SDVTList VTList,    MachineMemOperand *MMO =      MF.getMachineMemOperand(PtrInfo, Flags, MemVT.getStoreSize(), Align); -  return getMemIntrinsicNode(Opcode, dl, VTList, Ops, NumOps, MemVT, MMO); +  return getMemIntrinsicNode(Opcode, dl, VTList, Ops, MemVT, MMO);  }  SDValue  SelectionDAG::getMemIntrinsicNode(unsigned Opcode, SDLoc dl, SDVTList VTList, -                                  const SDValue *Ops, unsigned NumOps, -                                  EVT MemVT, MachineMemOperand *MMO) { +                                  ArrayRef<SDValue> Ops, EVT MemVT, +                                  MachineMemOperand *MMO) {    assert((Opcode == ISD::INTRINSIC_VOID ||            Opcode == ISD::INTRINSIC_W_CHAIN ||            Opcode == ISD::PREFETCH || @@ -4425,9 +4622,9 @@ SelectionDAG::getMemIntrinsicNode(unsigned Opcode, SDLoc dl, SDVTList VTList,    MemIntrinsicSDNode *N;    if (VTList.VTs[VTList.NumVTs-1] != MVT::Glue) {      FoldingSetNodeID ID; -    AddNodeIDNode(ID, Opcode, VTList, Ops, NumOps); +    AddNodeIDNode(ID, Opcode, VTList, Ops);      ID.AddInteger(MMO->getPointerInfo().getAddrSpace()); -    void *IP = 0; +    void *IP = nullptr;      if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) {        cast<MemIntrinsicSDNode>(E)->refineAlignment(MMO);        return SDValue(E, 0); @@ -4435,12 +4632,12 @@ SelectionDAG::getMemIntrinsicNode(unsigned Opcode, SDLoc dl, SDVTList VTList,      N = new (NodeAllocator) MemIntrinsicSDNode(Opcode, dl.getIROrder(),                                                 dl.getDebugLoc(), VTList, Ops, -                                               NumOps, MemVT, MMO); +                                               MemVT, MMO);      CSEMap.InsertNode(N, IP);    } else {      N = new (NodeAllocator) MemIntrinsicSDNode(Opcode, dl.getIROrder(),                                                 dl.getDebugLoc(), VTList, Ops, -                                               NumOps, MemVT, MMO); +                                               MemVT, MMO);    }    AllNodes.push_back(N);    return SDValue(N, 0); @@ -4503,7 +4700,7 @@ SelectionDAG::getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType,    // If we don't have a PtrInfo, infer the trivial frame index case to simplify    // clients. -  if (PtrInfo.V == 0) +  if (PtrInfo.V.isNull())      PtrInfo = InferPointerInfo(Ptr, Offset);    MachineFunction &MF = getMachineFunction(); @@ -4543,13 +4740,13 @@ SelectionDAG::getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType,      getVTList(VT, Ptr.getValueType(), MVT::Other) : getVTList(VT, MVT::Other);    SDValue Ops[] = { Chain, Ptr, Offset };    FoldingSetNodeID ID; -  AddNodeIDNode(ID, ISD::LOAD, VTs, Ops, 3); +  AddNodeIDNode(ID, ISD::LOAD, VTs, Ops);    ID.AddInteger(MemVT.getRawBits());    ID.AddInteger(encodeMemSDNodeFlags(ExtType, AM, MMO->isVolatile(),                                       MMO->isNonTemporal(),                                       MMO->isInvariant()));    ID.AddInteger(MMO->getPointerInfo().getAddrSpace()); -  void *IP = 0; +  void *IP = nullptr;    if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) {      cast<LoadSDNode>(E)->refineAlignment(MMO);      return SDValue(E, 0); @@ -4630,7 +4827,7 @@ SDValue SelectionDAG::getStore(SDValue Chain, SDLoc dl, SDValue Val,    if (isNonTemporal)      Flags |= MachineMemOperand::MONonTemporal; -  if (PtrInfo.V == 0) +  if (PtrInfo.V.isNull())      PtrInfo = InferPointerInfo(Ptr);    MachineFunction &MF = getMachineFunction(); @@ -4651,12 +4848,12 @@ SDValue SelectionDAG::getStore(SDValue Chain, SDLoc dl, SDValue Val,    SDValue Undef = getUNDEF(Ptr.getValueType());    SDValue Ops[] = { Chain, Val, Ptr, Undef };    FoldingSetNodeID ID; -  AddNodeIDNode(ID, ISD::STORE, VTs, Ops, 4); +  AddNodeIDNode(ID, ISD::STORE, VTs, Ops);    ID.AddInteger(VT.getRawBits());    ID.AddInteger(encodeMemSDNodeFlags(false, ISD::UNINDEXED, MMO->isVolatile(),                                       MMO->isNonTemporal(), MMO->isInvariant()));    ID.AddInteger(MMO->getPointerInfo().getAddrSpace()); -  void *IP = 0; +  void *IP = nullptr;    if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) {      cast<StoreSDNode>(E)->refineAlignment(MMO);      return SDValue(E, 0); @@ -4685,7 +4882,7 @@ SDValue SelectionDAG::getTruncStore(SDValue Chain, SDLoc dl, SDValue Val,    if (isNonTemporal)      Flags |= MachineMemOperand::MONonTemporal; -  if (PtrInfo.V == 0) +  if (PtrInfo.V.isNull())      PtrInfo = InferPointerInfo(Ptr);    MachineFunction &MF = getMachineFunction(); @@ -4720,12 +4917,12 @@ SDValue SelectionDAG::getTruncStore(SDValue Chain, SDLoc dl, SDValue Val,    SDValue Undef = getUNDEF(Ptr.getValueType());    SDValue Ops[] = { Chain, Val, Ptr, Undef };    FoldingSetNodeID ID; -  AddNodeIDNode(ID, ISD::STORE, VTs, Ops, 4); +  AddNodeIDNode(ID, ISD::STORE, VTs, Ops);    ID.AddInteger(SVT.getRawBits());    ID.AddInteger(encodeMemSDNodeFlags(true, ISD::UNINDEXED, MMO->isVolatile(),                                       MMO->isNonTemporal(), MMO->isInvariant()));    ID.AddInteger(MMO->getPointerInfo().getAddrSpace()); -  void *IP = 0; +  void *IP = nullptr;    if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) {      cast<StoreSDNode>(E)->refineAlignment(MMO);      return SDValue(E, 0); @@ -4747,11 +4944,11 @@ SelectionDAG::getIndexedStore(SDValue OrigStore, SDLoc dl, SDValue Base,    SDVTList VTs = getVTList(Base.getValueType(), MVT::Other);    SDValue Ops[] = { ST->getChain(), ST->getValue(), Base, Offset };    FoldingSetNodeID ID; -  AddNodeIDNode(ID, ISD::STORE, VTs, Ops, 4); +  AddNodeIDNode(ID, ISD::STORE, VTs, Ops);    ID.AddInteger(ST->getMemoryVT().getRawBits());    ID.AddInteger(ST->getRawSubclassData());    ID.AddInteger(ST->getPointerInfo().getAddrSpace()); -  void *IP = 0; +  void *IP = nullptr;    if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))      return SDValue(E, 0); @@ -4770,14 +4967,14 @@ SDValue SelectionDAG::getVAArg(EVT VT, SDLoc dl,                                 SDValue SV,                                 unsigned Align) {    SDValue Ops[] = { Chain, Ptr, SV, getTargetConstant(Align, MVT::i32) }; -  return getNode(ISD::VAARG, dl, getVTList(VT, MVT::Other), Ops, 4); +  return getNode(ISD::VAARG, dl, getVTList(VT, MVT::Other), Ops);  }  SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, EVT VT, -                              const SDUse *Ops, unsigned NumOps) { -  switch (NumOps) { +                              ArrayRef<SDUse> Ops) { +  switch (Ops.size()) {    case 0: return getNode(Opcode, DL, VT); -  case 1: return getNode(Opcode, DL, VT, Ops[0]); +  case 1: return getNode(Opcode, DL, VT, static_cast<const SDValue>(Ops[0]));    case 2: return getNode(Opcode, DL, VT, Ops[0], Ops[1]);    case 3: return getNode(Opcode, DL, VT, Ops[0], Ops[1], Ops[2]);    default: break; @@ -4785,12 +4982,13 @@ SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, EVT VT,    // Copy from an SDUse array into an SDValue array for use with    // the regular getNode logic. -  SmallVector<SDValue, 8> NewOps(Ops, Ops + NumOps); -  return getNode(Opcode, DL, VT, &NewOps[0], NumOps); +  SmallVector<SDValue, 8> NewOps(Ops.begin(), Ops.end()); +  return getNode(Opcode, DL, VT, NewOps);  }  SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, EVT VT, -                              const SDValue *Ops, unsigned NumOps) { +                              ArrayRef<SDValue> Ops) { +  unsigned NumOps = Ops.size();    switch (NumOps) {    case 0: return getNode(Opcode, DL, VT);    case 1: return getNode(Opcode, DL, VT, Ops[0]); @@ -4825,18 +5023,18 @@ SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, EVT VT,    if (VT != MVT::Glue) {      FoldingSetNodeID ID; -    AddNodeIDNode(ID, Opcode, VTs, Ops, NumOps); -    void *IP = 0; +    AddNodeIDNode(ID, Opcode, VTs, Ops); +    void *IP = nullptr;      if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))        return SDValue(E, 0);      N = new (NodeAllocator) SDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), -                                   VTs, Ops, NumOps); +                                   VTs, Ops);      CSEMap.InsertNode(N, IP);    } else {      N = new (NodeAllocator) SDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), -                                   VTs, Ops, NumOps); +                                   VTs, Ops);    }    AllNodes.push_back(N); @@ -4847,24 +5045,14 @@ SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, EVT VT,  }  SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, -                              ArrayRef<EVT> ResultTys, -                              const SDValue *Ops, unsigned NumOps) { -  return getNode(Opcode, DL, getVTList(&ResultTys[0], ResultTys.size()), -                 Ops, NumOps); -} - -SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, -                              const EVT *VTs, unsigned NumVTs, -                              const SDValue *Ops, unsigned NumOps) { -  if (NumVTs == 1) -    return getNode(Opcode, DL, VTs[0], Ops, NumOps); -  return getNode(Opcode, DL, makeVTList(VTs, NumVTs), Ops, NumOps); +                              ArrayRef<EVT> ResultTys, ArrayRef<SDValue> Ops) { +  return getNode(Opcode, DL, getVTList(ResultTys), Ops);  }  SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, SDVTList VTList, -                              const SDValue *Ops, unsigned NumOps) { +                              ArrayRef<SDValue> Ops) {    if (VTList.NumVTs == 1) -    return getNode(Opcode, DL, VTList.VTs[0], Ops, NumOps); +    return getNode(Opcode, DL, VTList.VTs[0], Ops);  #if 0    switch (Opcode) { @@ -4891,10 +5079,11 @@ SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, SDVTList VTList,    // Memoize the node unless it returns a flag.    SDNode *N; +  unsigned NumOps = Ops.size();    if (VTList.VTs[VTList.NumVTs-1] != MVT::Glue) {      FoldingSetNodeID ID; -    AddNodeIDNode(ID, Opcode, VTList, Ops, NumOps); -    void *IP = 0; +    AddNodeIDNode(ID, Opcode, VTList, Ops); +    void *IP = nullptr;      if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))        return SDValue(E, 0); @@ -4911,7 +5100,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, SDVTList VTList,                                              Ops[1], Ops[2]);      } else {        N = new (NodeAllocator) SDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), -                                     VTList, Ops, NumOps); +                                     VTList, Ops);      }      CSEMap.InsertNode(N, IP);    } else { @@ -4928,7 +5117,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, SDVTList VTList,                                              Ops[1], Ops[2]);      } else {        N = new (NodeAllocator) SDNode(Opcode, DL.getIROrder(), DL.getDebugLoc(), -                                     VTList, Ops, NumOps); +                                     VTList, Ops);      }    }    AllNodes.push_back(N); @@ -4939,39 +5128,39 @@ SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, SDVTList VTList,  }  SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, SDVTList VTList) { -  return getNode(Opcode, DL, VTList, 0, 0); +  return getNode(Opcode, DL, VTList, ArrayRef<SDValue>());  }  SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, SDVTList VTList,                                SDValue N1) {    SDValue Ops[] = { N1 }; -  return getNode(Opcode, DL, VTList, Ops, 1); +  return getNode(Opcode, DL, VTList, Ops);  }  SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, SDVTList VTList,                                SDValue N1, SDValue N2) {    SDValue Ops[] = { N1, N2 }; -  return getNode(Opcode, DL, VTList, Ops, 2); +  return getNode(Opcode, DL, VTList, Ops);  }  SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, SDVTList VTList,                                SDValue N1, SDValue N2, SDValue N3) {    SDValue Ops[] = { N1, N2, N3 }; -  return getNode(Opcode, DL, VTList, Ops, 3); +  return getNode(Opcode, DL, VTList, Ops);  }  SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, SDVTList VTList,                                SDValue N1, SDValue N2, SDValue N3,                                SDValue N4) {    SDValue Ops[] = { N1, N2, N3, N4 }; -  return getNode(Opcode, DL, VTList, Ops, 4); +  return getNode(Opcode, DL, VTList, Ops);  }  SDValue SelectionDAG::getNode(unsigned Opcode, SDLoc DL, SDVTList VTList,                                SDValue N1, SDValue N2, SDValue N3,                                SDValue N4, SDValue N5) {    SDValue Ops[] = { N1, N2, N3, N4, N5 }; -  return getNode(Opcode, DL, VTList, Ops, 5); +  return getNode(Opcode, DL, VTList, Ops);  }  SDVTList SelectionDAG::getVTList(EVT VT) { @@ -4984,9 +5173,9 @@ SDVTList SelectionDAG::getVTList(EVT VT1, EVT VT2) {    ID.AddInteger(VT1.getRawBits());    ID.AddInteger(VT2.getRawBits()); -  void *IP = 0; +  void *IP = nullptr;    SDVTListNode *Result = VTListMap.FindNodeOrInsertPos(ID, IP); -  if (Result == NULL) { +  if (!Result) {      EVT *Array = Allocator.Allocate<EVT>(2);      Array[0] = VT1;      Array[1] = VT2; @@ -5003,9 +5192,9 @@ SDVTList SelectionDAG::getVTList(EVT VT1, EVT VT2, EVT VT3) {    ID.AddInteger(VT2.getRawBits());    ID.AddInteger(VT3.getRawBits()); -  void *IP = 0; +  void *IP = nullptr;    SDVTListNode *Result = VTListMap.FindNodeOrInsertPos(ID, IP); -  if (Result == NULL) { +  if (!Result) {      EVT *Array = Allocator.Allocate<EVT>(3);      Array[0] = VT1;      Array[1] = VT2; @@ -5024,9 +5213,9 @@ SDVTList SelectionDAG::getVTList(EVT VT1, EVT VT2, EVT VT3, EVT VT4) {    ID.AddInteger(VT3.getRawBits());    ID.AddInteger(VT4.getRawBits()); -  void *IP = 0; +  void *IP = nullptr;    SDVTListNode *Result = VTListMap.FindNodeOrInsertPos(ID, IP); -  if (Result == NULL) { +  if (!Result) {      EVT *Array = Allocator.Allocate<EVT>(4);      Array[0] = VT1;      Array[1] = VT2; @@ -5038,18 +5227,19 @@ SDVTList SelectionDAG::getVTList(EVT VT1, EVT VT2, EVT VT3, EVT VT4) {    return Result->getSDVTList();  } -SDVTList SelectionDAG::getVTList(const EVT *VTs, unsigned NumVTs) { +SDVTList SelectionDAG::getVTList(ArrayRef<EVT> VTs) { +  unsigned NumVTs = VTs.size();    FoldingSetNodeID ID;    ID.AddInteger(NumVTs);    for (unsigned index = 0; index < NumVTs; index++) {      ID.AddInteger(VTs[index].getRawBits());    } -  void *IP = 0; +  void *IP = nullptr;    SDVTListNode *Result = VTListMap.FindNodeOrInsertPos(ID, IP); -  if (Result == NULL) { +  if (!Result) {      EVT *Array = Allocator.Allocate<EVT>(NumVTs); -    std::copy(VTs, VTs + NumVTs, Array); +    std::copy(VTs.begin(), VTs.end(), Array);      Result = new (Allocator) SDVTListNode(ID.Intern(Allocator), Array, NumVTs);      VTListMap.InsertNode(Result, IP);    } @@ -5070,14 +5260,14 @@ SDNode *SelectionDAG::UpdateNodeOperands(SDNode *N, SDValue Op) {    if (Op == N->getOperand(0)) return N;    // See if the modified node already exists. -  void *InsertPos = 0; +  void *InsertPos = nullptr;    if (SDNode *Existing = FindModifiedNodeSlot(N, Op, InsertPos))      return Existing;    // Nope it doesn't.  Remove the node from its current place in the maps.    if (InsertPos)      if (!RemoveNodeFromCSEMaps(N)) -      InsertPos = 0; +      InsertPos = nullptr;    // Now we update the operands.    N->OperandList[0].set(Op); @@ -5095,14 +5285,14 @@ SDNode *SelectionDAG::UpdateNodeOperands(SDNode *N, SDValue Op1, SDValue Op2) {      return N;   // No operands changed, just return the input node.    // See if the modified node already exists. -  void *InsertPos = 0; +  void *InsertPos = nullptr;    if (SDNode *Existing = FindModifiedNodeSlot(N, Op1, Op2, InsertPos))      return Existing;    // Nope it doesn't.  Remove the node from its current place in the maps.    if (InsertPos)      if (!RemoveNodeFromCSEMaps(N)) -      InsertPos = 0; +      InsertPos = nullptr;    // Now we update the operands.    if (N->OperandList[0] != Op1) @@ -5118,25 +5308,26 @@ SDNode *SelectionDAG::UpdateNodeOperands(SDNode *N, SDValue Op1, SDValue Op2) {  SDNode *SelectionDAG::  UpdateNodeOperands(SDNode *N, SDValue Op1, SDValue Op2, SDValue Op3) {    SDValue Ops[] = { Op1, Op2, Op3 }; -  return UpdateNodeOperands(N, Ops, 3); +  return UpdateNodeOperands(N, Ops);  }  SDNode *SelectionDAG::  UpdateNodeOperands(SDNode *N, SDValue Op1, SDValue Op2,                     SDValue Op3, SDValue Op4) {    SDValue Ops[] = { Op1, Op2, Op3, Op4 }; -  return UpdateNodeOperands(N, Ops, 4); +  return UpdateNodeOperands(N, Ops);  }  SDNode *SelectionDAG::  UpdateNodeOperands(SDNode *N, SDValue Op1, SDValue Op2,                     SDValue Op3, SDValue Op4, SDValue Op5) {    SDValue Ops[] = { Op1, Op2, Op3, Op4, Op5 }; -  return UpdateNodeOperands(N, Ops, 5); +  return UpdateNodeOperands(N, Ops);  }  SDNode *SelectionDAG:: -UpdateNodeOperands(SDNode *N, const SDValue *Ops, unsigned NumOps) { +UpdateNodeOperands(SDNode *N, ArrayRef<SDValue> Ops) { +  unsigned NumOps = Ops.size();    assert(N->getNumOperands() == NumOps &&           "Update with wrong number of operands"); @@ -5153,14 +5344,14 @@ UpdateNodeOperands(SDNode *N, const SDValue *Ops, unsigned NumOps) {    if (!AnyChange) return N;    // See if the modified node already exists. -  void *InsertPos = 0; -  if (SDNode *Existing = FindModifiedNodeSlot(N, Ops, NumOps, InsertPos)) +  void *InsertPos = nullptr; +  if (SDNode *Existing = FindModifiedNodeSlot(N, Ops, InsertPos))      return Existing;    // Nope it doesn't.  Remove the node from its current place in the maps.    if (InsertPos)      if (!RemoveNodeFromCSEMaps(N)) -      InsertPos = 0; +      InsertPos = nullptr;    // Now we update the operands.    for (unsigned i = 0; i != NumOps; ++i) @@ -5189,14 +5380,14 @@ void SDNode::DropOperands() {  SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc,                                     EVT VT) {    SDVTList VTs = getVTList(VT); -  return SelectNodeTo(N, MachineOpc, VTs, 0, 0); +  return SelectNodeTo(N, MachineOpc, VTs, None);  }  SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc,                                     EVT VT, SDValue Op1) {    SDVTList VTs = getVTList(VT);    SDValue Ops[] = { Op1 }; -  return SelectNodeTo(N, MachineOpc, VTs, Ops, 1); +  return SelectNodeTo(N, MachineOpc, VTs, Ops);  }  SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc, @@ -5204,7 +5395,7 @@ SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc,                                     SDValue Op2) {    SDVTList VTs = getVTList(VT);    SDValue Ops[] = { Op1, Op2 }; -  return SelectNodeTo(N, MachineOpc, VTs, Ops, 2); +  return SelectNodeTo(N, MachineOpc, VTs, Ops);  }  SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc, @@ -5212,41 +5403,39 @@ SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc,                                     SDValue Op2, SDValue Op3) {    SDVTList VTs = getVTList(VT);    SDValue Ops[] = { Op1, Op2, Op3 }; -  return SelectNodeTo(N, MachineOpc, VTs, Ops, 3); +  return SelectNodeTo(N, MachineOpc, VTs, Ops);  }  SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc, -                                   EVT VT, const SDValue *Ops, -                                   unsigned NumOps) { +                                   EVT VT, ArrayRef<SDValue> Ops) {    SDVTList VTs = getVTList(VT); -  return SelectNodeTo(N, MachineOpc, VTs, Ops, NumOps); +  return SelectNodeTo(N, MachineOpc, VTs, Ops);  }  SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc, -                                   EVT VT1, EVT VT2, const SDValue *Ops, -                                   unsigned NumOps) { +                                   EVT VT1, EVT VT2, ArrayRef<SDValue> Ops) {    SDVTList VTs = getVTList(VT1, VT2); -  return SelectNodeTo(N, MachineOpc, VTs, Ops, NumOps); +  return SelectNodeTo(N, MachineOpc, VTs, Ops);  }  SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc,                                     EVT VT1, EVT VT2) {    SDVTList VTs = getVTList(VT1, VT2); -  return SelectNodeTo(N, MachineOpc, VTs, (SDValue *)0, 0); +  return SelectNodeTo(N, MachineOpc, VTs, None);  }  SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc,                                     EVT VT1, EVT VT2, EVT VT3, -                                   const SDValue *Ops, unsigned NumOps) { +                                   ArrayRef<SDValue> Ops) {    SDVTList VTs = getVTList(VT1, VT2, VT3); -  return SelectNodeTo(N, MachineOpc, VTs, Ops, NumOps); +  return SelectNodeTo(N, MachineOpc, VTs, Ops);  }  SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc,                                     EVT VT1, EVT VT2, EVT VT3, EVT VT4, -                                   const SDValue *Ops, unsigned NumOps) { +                                   ArrayRef<SDValue> Ops) {    SDVTList VTs = getVTList(VT1, VT2, VT3, VT4); -  return SelectNodeTo(N, MachineOpc, VTs, Ops, NumOps); +  return SelectNodeTo(N, MachineOpc, VTs, Ops);  }  SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc, @@ -5254,7 +5443,7 @@ SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc,                                     SDValue Op1) {    SDVTList VTs = getVTList(VT1, VT2);    SDValue Ops[] = { Op1 }; -  return SelectNodeTo(N, MachineOpc, VTs, Ops, 1); +  return SelectNodeTo(N, MachineOpc, VTs, Ops);  }  SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc, @@ -5262,7 +5451,7 @@ SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc,                                     SDValue Op1, SDValue Op2) {    SDVTList VTs = getVTList(VT1, VT2);    SDValue Ops[] = { Op1, Op2 }; -  return SelectNodeTo(N, MachineOpc, VTs, Ops, 2); +  return SelectNodeTo(N, MachineOpc, VTs, Ops);  }  SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc, @@ -5271,7 +5460,7 @@ SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc,                                     SDValue Op3) {    SDVTList VTs = getVTList(VT1, VT2);    SDValue Ops[] = { Op1, Op2, Op3 }; -  return SelectNodeTo(N, MachineOpc, VTs, Ops, 3); +  return SelectNodeTo(N, MachineOpc, VTs, Ops);  }  SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc, @@ -5280,13 +5469,12 @@ SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc,                                     SDValue Op3) {    SDVTList VTs = getVTList(VT1, VT2, VT3);    SDValue Ops[] = { Op1, Op2, Op3 }; -  return SelectNodeTo(N, MachineOpc, VTs, Ops, 3); +  return SelectNodeTo(N, MachineOpc, VTs, Ops);  }  SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc, -                                   SDVTList VTs, const SDValue *Ops, -                                   unsigned NumOps) { -  N = MorphNodeTo(N, ~MachineOpc, VTs, Ops, NumOps); +                                   SDVTList VTs,ArrayRef<SDValue> Ops) { +  N = MorphNodeTo(N, ~MachineOpc, VTs, Ops);    // Reset the NodeID to -1.    N->setNodeId(-1);    return N; @@ -5323,19 +5511,19 @@ SDNode *SelectionDAG::UpdadeSDLocOnMergedSDNode(SDNode *N, SDLoc OLoc) {  /// the node's users.  ///  SDNode *SelectionDAG::MorphNodeTo(SDNode *N, unsigned Opc, -                                  SDVTList VTs, const SDValue *Ops, -                                  unsigned NumOps) { +                                  SDVTList VTs, ArrayRef<SDValue> Ops) { +  unsigned NumOps = Ops.size();    // If an identical node already exists, use it. -  void *IP = 0; +  void *IP = nullptr;    if (VTs.VTs[VTs.NumVTs-1] != MVT::Glue) {      FoldingSetNodeID ID; -    AddNodeIDNode(ID, Opc, VTs, Ops, NumOps); +    AddNodeIDNode(ID, Opc, VTs, Ops);      if (SDNode *ON = CSEMap.FindNodeOrInsertPos(ID, IP))        return UpdadeSDLocOnMergedSDNode(ON, SDLoc(N));    }    if (!RemoveNodeFromCSEMaps(N)) -    IP = 0; +    IP = nullptr;    // Start the morphing.    N->NodeType = Opc; @@ -5355,7 +5543,7 @@ SDNode *SelectionDAG::MorphNodeTo(SDNode *N, unsigned Opc,    if (MachineSDNode *MN = dyn_cast<MachineSDNode>(N)) {      // Initialize the memory references information. -    MN->setMemRefs(0, 0); +    MN->setMemRefs(nullptr, nullptr);      // If NumOps is larger than the # of operands we can have in a      // MachineSDNode, reallocate the operand list.      if (NumOps > MN->NumOperands || !MN->OperandsNeedDelete) { @@ -5366,22 +5554,22 @@ SDNode *SelectionDAG::MorphNodeTo(SDNode *N, unsigned Opc,          // remainder of the current SelectionDAG iteration, so we can allocate          // the operands directly out of a pool with no recycling metadata.          MN->InitOperands(OperandAllocator.Allocate<SDUse>(NumOps), -                         Ops, NumOps); +                         Ops.data(), NumOps);        else -        MN->InitOperands(MN->LocalOperands, Ops, NumOps); +        MN->InitOperands(MN->LocalOperands, Ops.data(), NumOps);        MN->OperandsNeedDelete = false;      } else -      MN->InitOperands(MN->OperandList, Ops, NumOps); +      MN->InitOperands(MN->OperandList, Ops.data(), NumOps);    } else {      // If NumOps is larger than the # of operands we currently have, reallocate      // the operand list.      if (NumOps > N->NumOperands) {        if (N->OperandsNeedDelete)          delete[] N->OperandList; -      N->InitOperands(new SDUse[NumOps], Ops, NumOps); +      N->InitOperands(new SDUse[NumOps], Ops.data(), NumOps);        N->OperandsNeedDelete = true;      } else -      N->InitOperands(N->OperandList, Ops, NumOps); +      N->InitOperands(N->OperandList, Ops.data(), NumOps);    }    // Delete any nodes that are still dead after adding the uses for the @@ -5520,7 +5708,7 @@ MachineSDNode *  SelectionDAG::getMachineNode(unsigned Opcode, SDLoc dl,                               ArrayRef<EVT> ResultTys,                               ArrayRef<SDValue> Ops) { -  SDVTList VTs = getVTList(&ResultTys[0], ResultTys.size()); +  SDVTList VTs = getVTList(ResultTys);    return getMachineNode(Opcode, dl, VTs, Ops);  } @@ -5529,14 +5717,14 @@ SelectionDAG::getMachineNode(unsigned Opcode, SDLoc DL, SDVTList VTs,                               ArrayRef<SDValue> OpsArray) {    bool DoCSE = VTs.VTs[VTs.NumVTs-1] != MVT::Glue;    MachineSDNode *N; -  void *IP = 0; +  void *IP = nullptr;    const SDValue *Ops = OpsArray.data();    unsigned NumOps = OpsArray.size();    if (DoCSE) {      FoldingSetNodeID ID; -    AddNodeIDNode(ID, ~Opcode, VTs, Ops, NumOps); -    IP = 0; +    AddNodeIDNode(ID, ~Opcode, VTs, OpsArray); +    IP = nullptr;      if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) {        return cast<MachineSDNode>(UpdadeSDLocOnMergedSDNode(E, DL));      } @@ -5592,34 +5780,42 @@ SelectionDAG::getTargetInsertSubreg(int SRIdx, SDLoc DL, EVT VT,  /// getNodeIfExists - Get the specified node if it's already available, or  /// else return NULL.  SDNode *SelectionDAG::getNodeIfExists(unsigned Opcode, SDVTList VTList, -                                      const SDValue *Ops, unsigned NumOps) { -  if (VTList.VTs[VTList.NumVTs-1] != MVT::Glue) { +                                      ArrayRef<SDValue> Ops, bool nuw, bool nsw, +                                      bool exact) { +  if (VTList.VTs[VTList.NumVTs - 1] != MVT::Glue) {      FoldingSetNodeID ID; -    AddNodeIDNode(ID, Opcode, VTList, Ops, NumOps); -    void *IP = 0; +    AddNodeIDNode(ID, Opcode, VTList, Ops); +    if (isBinOpWithFlags(Opcode)) +      AddBinaryNodeIDCustom(ID, nuw, nsw, exact); +    void *IP = nullptr;      if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))        return E;    } -  return NULL; +  return nullptr;  }  /// getDbgValue - Creates a SDDbgValue node.  /// +/// SDNode  SDDbgValue * -SelectionDAG::getDbgValue(MDNode *MDPtr, SDNode *N, unsigned R, uint64_t Off, +SelectionDAG::getDbgValue(MDNode *MDPtr, SDNode *N, unsigned R, +			  bool IsIndirect, uint64_t Off,                            DebugLoc DL, unsigned O) { -  return new (Allocator) SDDbgValue(MDPtr, N, R, Off, DL, O); +  return new (Allocator) SDDbgValue(MDPtr, N, R, IsIndirect, Off, DL, O);  } +/// Constant  SDDbgValue * -SelectionDAG::getDbgValue(MDNode *MDPtr, const Value *C, uint64_t Off, -                          DebugLoc DL, unsigned O) { +SelectionDAG::getConstantDbgValue(MDNode *MDPtr, const Value *C, +				  uint64_t Off, +				  DebugLoc DL, unsigned O) {    return new (Allocator) SDDbgValue(MDPtr, C, Off, DL, O);  } +/// FrameIndex  SDDbgValue * -SelectionDAG::getDbgValue(MDNode *MDPtr, unsigned FI, uint64_t Off, -                          DebugLoc DL, unsigned O) { +SelectionDAG::getFrameIndexDbgValue(MDNode *MDPtr, unsigned FI, uint64_t Off, +				    DebugLoc DL, unsigned O) {    return new (Allocator) SDDbgValue(MDPtr, FI, Off, DL, O);  } @@ -5633,7 +5829,7 @@ class RAUWUpdateListener : public SelectionDAG::DAGUpdateListener {    SDNode::use_iterator &UI;    SDNode::use_iterator &UE; -  virtual void NodeDeleted(SDNode *N, SDNode *E) { +  void NodeDeleted(SDNode *N, SDNode *E) override {      // Increment the iterator as needed.      while (UI != UE && N == *UI)        ++UI; @@ -5937,7 +6133,7 @@ unsigned SelectionDAG::AssignTopologicalOrder() {    // count of outstanding operands.    for (allnodes_iterator I = allnodes_begin(),E = allnodes_end(); I != E; ) {      SDNode *N = I++; -    checkForCycles(N); +    checkForCycles(N, this);      unsigned Degree = N->getNumOperands();      if (Degree == 0) {        // A node with no uses, add it to the result array immediately. @@ -5957,7 +6153,7 @@ unsigned SelectionDAG::AssignTopologicalOrder() {    // such that by the time the end is reached all nodes will be sorted.    for (allnodes_iterator I = allnodes_begin(),E = allnodes_end(); I != E; ++I) {      SDNode *N = I; -    checkForCycles(N); +    checkForCycles(N, this);      // N is in sorted position, so all its uses have one less operand      // that needs to be sorted.      for (SDNode::use_iterator UI = N->use_begin(), UE = N->use_end(); @@ -5982,9 +6178,11 @@ unsigned SelectionDAG::AssignTopologicalOrder() {  #ifndef NDEBUG        SDNode *S = ++I;        dbgs() << "Overran sorted position:\n"; -      S->dumprFull(); +      S->dumprFull(this); dbgs() << "\n"; +      dbgs() << "Checking if this is due to cycles\n"; +      checkForCycles(this, true);  #endif -      llvm_unreachable(0); +      llvm_unreachable(nullptr);      }    } @@ -6025,6 +6223,7 @@ void SelectionDAG::TransferDbgValues(SDValue From, SDValue To) {      SDDbgValue *Dbg = *I;      if (Dbg->getKind() == SDDbgValue::SDNODE) {        SDDbgValue *Clone = getDbgValue(Dbg->getMDPtr(), ToNode, To.getResNo(), +				      Dbg->isIndirect(),                                        Dbg->getOffset(), Dbg->getDebugLoc(),                                        Dbg->getOrder());        ClonedDVs.push_back(Clone); @@ -6068,9 +6267,8 @@ MemSDNode::MemSDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs,  }  MemSDNode::MemSDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs, -                     const SDValue *Ops, unsigned NumOps, EVT memvt, -                     MachineMemOperand *mmo) -   : SDNode(Opc, Order, dl, VTs, Ops, NumOps), +                     ArrayRef<SDValue> Ops, EVT memvt, MachineMemOperand *mmo) +   : SDNode(Opc, Order, dl, VTs, Ops),       MemoryVT(memvt), MMO(mmo) {    SubclassData = encodeMemSDNodeFlags(0, ISD::UNINDEXED, MMO->isVolatile(),                                        MMO->isNonTemporal(), MMO->isInvariant()); @@ -6289,12 +6487,10 @@ SDValue SelectionDAG::UnrollVectorOp(SDNode *N, unsigned ResNE) {      switch (N->getOpcode()) {      default: -      Scalars.push_back(getNode(N->getOpcode(), dl, EltVT, -                                &Operands[0], Operands.size())); +      Scalars.push_back(getNode(N->getOpcode(), dl, EltVT, Operands));        break;      case ISD::VSELECT: -      Scalars.push_back(getNode(ISD::SELECT, dl, EltVT, -                                &Operands[0], Operands.size())); +      Scalars.push_back(getNode(ISD::SELECT, dl, EltVT, Operands));        break;      case ISD::SHL:      case ISD::SRA: @@ -6319,8 +6515,7 @@ SDValue SelectionDAG::UnrollVectorOp(SDNode *N, unsigned ResNE) {      Scalars.push_back(getUNDEF(EltVT));    return getNode(ISD::BUILD_VECTOR, dl, -                 EVT::getVectorVT(*getContext(), EltVT, ResNE), -                 &Scalars[0], Scalars.size()); +                 EVT::getVectorVT(*getContext(), EltVT, ResNE), Scalars);  } @@ -6354,8 +6549,8 @@ bool SelectionDAG::isConsecutiveLoad(LoadSDNode *LD, LoadSDNode *Base,        cast<ConstantSDNode>(Loc.getOperand(1))->getSExtValue() == Dist*Bytes)      return true; -  const GlobalValue *GV1 = NULL; -  const GlobalValue *GV2 = NULL; +  const GlobalValue *GV1 = nullptr; +  const GlobalValue *GV2 = nullptr;    int64_t Offset1 = 0;    int64_t Offset2 = 0;    const TargetLowering *TLI = TM.getTargetLowering(); @@ -6377,8 +6572,8 @@ unsigned SelectionDAG::InferPtrAlignment(SDValue Ptr) const {    if (TLI->isGAPlusOffset(Ptr.getNode(), GV, GVOffset)) {      unsigned PtrWidth = TLI->getPointerTypeSizeInBits(GV->getType());      APInt KnownZero(PtrWidth, 0), KnownOne(PtrWidth, 0); -    llvm::ComputeMaskedBits(const_cast<GlobalValue*>(GV), KnownZero, KnownOne, -                            TLI->getDataLayout()); +    llvm::computeKnownBits(const_cast<GlobalValue*>(GV), KnownZero, KnownOne, +                           TLI->getDataLayout());      unsigned AlignBits = KnownZero.countTrailingOnes();      unsigned Align = AlignBits ? 1 << std::min(31U, AlignBits) : 0;      if (Align) @@ -6440,6 +6635,22 @@ SelectionDAG::SplitVector(const SDValue &N, const SDLoc &DL, const EVT &LoVT,    return std::make_pair(Lo, Hi);  } +void SelectionDAG::ExtractVectorElements(SDValue Op, +                                         SmallVectorImpl<SDValue> &Args, +                                         unsigned Start, unsigned Count) { +  EVT VT = Op.getValueType(); +  if (Count == 0) +    Count = VT.getVectorNumElements(); + +  EVT EltVT = VT.getVectorElementType(); +  EVT IdxTy = TLI->getVectorIdxTy(); +  SDLoc SL(Op); +  for (unsigned i = Start, e = Start + Count; i != e; ++i) { +    Args.push_back(getNode(ISD::EXTRACT_VECTOR_ELT, SL, EltVT, +                           Op, getConstant(i, IdxTy))); +  } +} +  // getAddressSpace - Return the address space this GlobalAddress belongs to.  unsigned GlobalAddressSDNode::getAddressSpace() const {    return getGlobal()->getType()->getAddressSpace(); @@ -6457,7 +6668,7 @@ bool BuildVectorSDNode::isConstantSplat(APInt &SplatValue,                                          unsigned &SplatBitSize,                                          bool &HasAnyUndefs,                                          unsigned MinSplatBits, -                                        bool isBigEndian) { +                                        bool isBigEndian) const {    EVT VT = getValueType(0);    assert(VT.isVector() && "Expected a vector type");    unsigned sz = VT.getSizeInBits(); @@ -6518,6 +6729,54 @@ bool BuildVectorSDNode::isConstantSplat(APInt &SplatValue,    return true;  } +SDValue BuildVectorSDNode::getSplatValue(BitVector *UndefElements) const { +  if (UndefElements) { +    UndefElements->clear(); +    UndefElements->resize(getNumOperands()); +  } +  SDValue Splatted; +  for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { +    SDValue Op = getOperand(i); +    if (Op.getOpcode() == ISD::UNDEF) { +      if (UndefElements) +        (*UndefElements)[i] = true; +    } else if (!Splatted) { +      Splatted = Op; +    } else if (Splatted != Op) { +      return SDValue(); +    } +  } + +  if (!Splatted) { +    assert(getOperand(0).getOpcode() == ISD::UNDEF && +           "Can only have a splat without a constant for all undefs."); +    return getOperand(0); +  } + +  return Splatted; +} + +ConstantSDNode * +BuildVectorSDNode::getConstantSplatNode(BitVector *UndefElements) const { +  return dyn_cast_or_null<ConstantSDNode>( +      getSplatValue(UndefElements).getNode()); +} + +ConstantFPSDNode * +BuildVectorSDNode::getConstantFPSplatNode(BitVector *UndefElements) const { +  return dyn_cast_or_null<ConstantFPSDNode>( +      getSplatValue(UndefElements).getNode()); +} + +bool BuildVectorSDNode::isConstant() const { +  for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { +    unsigned Opc = getOperand(i).getOpcode(); +    if (Opc != ISD::UNDEF && Opc != ISD::Constant && Opc != ISD::ConstantFP) +      return false; +  } +  return true; +} +  bool ShuffleVectorSDNode::isSplatMask(const int *Mask, EVT VT) {    // Find the first non-undef value in the shuffle mask.    unsigned i, e; @@ -6534,10 +6793,11 @@ bool ShuffleVectorSDNode::isSplatMask(const int *Mask, EVT VT) {    return true;  } -#ifdef XDEBUG +#ifndef NDEBUG  static void checkForCyclesHelper(const SDNode *N,                                   SmallPtrSet<const SDNode*, 32> &Visited, -                                 SmallPtrSet<const SDNode*, 32> &Checked) { +                                 SmallPtrSet<const SDNode*, 32> &Checked, +                                 const llvm::SelectionDAG *DAG) {    // If this node has already been checked, don't check it again.    if (Checked.count(N))      return; @@ -6545,29 +6805,37 @@ static void checkForCyclesHelper(const SDNode *N,    // If a node has already been visited on this depth-first walk, reject it as    // a cycle.    if (!Visited.insert(N)) { -    dbgs() << "Offending node:\n"; -    N->dumprFull();      errs() << "Detected cycle in SelectionDAG\n"; +    dbgs() << "Offending node:\n"; +    N->dumprFull(DAG); dbgs() << "\n";      abort();    }    for(unsigned i = 0, e = N->getNumOperands(); i != e; ++i) -    checkForCyclesHelper(N->getOperand(i).getNode(), Visited, Checked); +    checkForCyclesHelper(N->getOperand(i).getNode(), Visited, Checked, DAG);    Checked.insert(N);    Visited.erase(N);  }  #endif -void llvm::checkForCycles(const llvm::SDNode *N) { +void llvm::checkForCycles(const llvm::SDNode *N, +                          const llvm::SelectionDAG *DAG, +                          bool force) { +#ifndef NDEBUG +  bool check = force;  #ifdef XDEBUG -  assert(N && "Checking nonexistent SDNode"); -  SmallPtrSet<const SDNode*, 32> visited; -  SmallPtrSet<const SDNode*, 32> checked; -  checkForCyclesHelper(N, visited, checked); -#endif +  check = true; +#endif  // XDEBUG +  if (check) { +    assert(N && "Checking nonexistent SDNode"); +    SmallPtrSet<const SDNode*, 32> visited; +    SmallPtrSet<const SDNode*, 32> checked; +    checkForCyclesHelper(N, visited, checked, DAG); +  } +#endif  // !NDEBUG  } -void llvm::checkForCycles(const llvm::SelectionDAG *DAG) { -  checkForCycles(DAG->getRoot().getNode()); +void llvm::checkForCycles(const llvm::SelectionDAG *DAG, bool force) { +  checkForCycles(DAG->getRoot().getNode(), DAG, force);  } | 
