SelectionDAG.cpp revision bcd2498f4f1682dbdc41452add5b9bc72cbd6b3f
1179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org//===-- SelectionDAG.cpp - Implement the SelectionDAG data structures -----===//
2179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org//
3179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org//                     The LLVM Compiler Infrastructure
4179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org//
5179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// This file was developed by the LLVM research group and is distributed under
6179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// the University of Illinois Open Source License. See LICENSE.TXT for details.
7179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org//
8179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org//===----------------------------------------------------------------------===//
9179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org//
10179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// This implements the SelectionDAG class.
11179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org//
12179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org//===----------------------------------------------------------------------===//
13179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
14179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "llvm/CodeGen/SelectionDAG.h"
15179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "llvm/Constants.h"
16179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "llvm/GlobalValue.h"
17179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "llvm/Intrinsics.h"
18179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "llvm/Assembly/Writer.h"
19179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "llvm/CodeGen/MachineBasicBlock.h"
20179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "llvm/CodeGen/MachineConstantPool.h"
21179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "llvm/Support/MathExtras.h"
22179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "llvm/Target/MRegisterInfo.h"
23fbd97aa4c5325eace57d24b89845b9581bac9324jorlow@chromium.org#include "llvm/Target/TargetLowering.h"
24fbd97aa4c5325eace57d24b89845b9581bac9324jorlow@chromium.org#include "llvm/Target/TargetInstrInfo.h"
25fbd97aa4c5325eace57d24b89845b9581bac9324jorlow@chromium.org#include "llvm/Target/TargetMachine.h"
26fbd97aa4c5325eace57d24b89845b9581bac9324jorlow@chromium.org#include "llvm/ADT/SetVector.h"
27fbd97aa4c5325eace57d24b89845b9581bac9324jorlow@chromium.org#include "llvm/ADT/SmallVector.h"
28179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "llvm/ADT/StringExtras.h"
29179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include <set>
30179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include <algorithm>
31179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include <cmath>
32179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgusing namespace llvm;
33179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
34179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// makeVTList - Return an instance of the SDVTList struct initialized with the
35179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// specified members.
36179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgstatic SDVTList makeVTList(const MVT::ValueType *VTs, unsigned NumVTs) {
37179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  SDVTList Res = {VTs, NumVTs};
3811042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.org  return Res;
3911042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.org}
4013daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com
4113daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com//===----------------------------------------------------------------------===//
4213daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com//                              ConstantFPSDNode Class
4313daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com//===----------------------------------------------------------------------===//
4413daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com
4513daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com/// isExactlyValue - We don't rely on operator== working on double values, as
4613daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com/// it returns true for things that are clearly not equal, like -0.0 and 0.0.
4713daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com/// As such, this method can be used to do an exact bit-for-bit comparison of
4813daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com/// two floating point values.
4913daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.combool ConstantFPSDNode::isExactlyValue(double V) const {
5013daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com  return DoubleToBits(V) == DoubleToBits(Value);
51179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
52179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
53179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org//===----------------------------------------------------------------------===//
54179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org//                              ISD Namespace
55179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org//===----------------------------------------------------------------------===//
56179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
57179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// isBuildVectorAllOnes - Return true if the specified node is a
58179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// BUILD_VECTOR where all of the elements are ~0 or undef.
59179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgbool ISD::isBuildVectorAllOnes(const SDNode *N) {
60179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // Look through a bit convert.
61179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if (N->getOpcode() == ISD::BIT_CONVERT)
62179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    N = N->getOperand(0).Val;
63179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
64179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if (N->getOpcode() != ISD::BUILD_VECTOR) return false;
65179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
66179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  unsigned i = 0, e = N->getNumOperands();
67179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
68179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // Skip over all of the undef values.
69179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  while (i != e && N->getOperand(i).getOpcode() == ISD::UNDEF)
70179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    ++i;
71179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
72179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // Do not accept an all-undef vector.
73179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if (i == e) return false;
74179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
75179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // Do not accept build_vectors that aren't all constants or which have non-~0
76179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // elements.
77179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  SDOperand NotZero = N->getOperand(i);
78179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if (isa<ConstantSDNode>(NotZero)) {
79179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    if (!cast<ConstantSDNode>(NotZero)->isAllOnesValue())
80179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      return false;
81179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  } else if (isa<ConstantFPSDNode>(NotZero)) {
82179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    MVT::ValueType VT = NotZero.getValueType();
83179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    if (VT== MVT::f64) {
84179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      if (DoubleToBits(cast<ConstantFPSDNode>(NotZero)->getValue()) !=
85179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org          (uint64_t)-1)
86179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org        return false;
871511be6edb54b6ade2bfad94256f76bc191e92ecdgrogan@chromium.org    } else {
881511be6edb54b6ade2bfad94256f76bc191e92ecdgrogan@chromium.org      if (FloatToBits(cast<ConstantFPSDNode>(NotZero)->getValue()) !=
89179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org          (uint32_t)-1)
90179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org        return false;
91179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    }
9299a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com  } else
93179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    return false;
94179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
95179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // Okay, we have at least one ~0 value, check to see if the rest match or are
9699a7585544fc162a5f8dd39a6add00776a981efesanjay@google.com  // undefs.
9711042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.org  for (++i; i != e; ++i)
9811042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.org    if (N->getOperand(i) != NotZero &&
9911042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.org        N->getOperand(i).getOpcode() != ISD::UNDEF)
100179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      return false;
101179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  return true;
102179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
103179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
104f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com
105179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// isBuildVectorAllZeros - Return true if the specified node is a
106179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// BUILD_VECTOR where all of the elements are 0 or undef.
107f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.combool ISD::isBuildVectorAllZeros(const SDNode *N) {
108179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // Look through a bit convert.
109179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if (N->getOpcode() == ISD::BIT_CONVERT)
11095e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org    N = N->getOperand(0).Val;
11195e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org
11295e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  if (N->getOpcode() != ISD::BUILD_VECTOR) return false;
113179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
114179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  unsigned i = 0, e = N->getNumOperands();
115179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
11608595b9e51ded54851b7664bd38affad63a67838dgrogan@chromium.org  // Skip over all of the undef values.
11708595b9e51ded54851b7664bd38affad63a67838dgrogan@chromium.org  while (i != e && N->getOperand(i).getOpcode() == ISD::UNDEF)
11808595b9e51ded54851b7664bd38affad63a67838dgrogan@chromium.org    ++i;
11908595b9e51ded54851b7664bd38affad63a67838dgrogan@chromium.org
12008595b9e51ded54851b7664bd38affad63a67838dgrogan@chromium.org  // Do not accept an all-undef vector.
12108595b9e51ded54851b7664bd38affad63a67838dgrogan@chromium.org  if (i == e) return false;
12208595b9e51ded54851b7664bd38affad63a67838dgrogan@chromium.org
12308595b9e51ded54851b7664bd38affad63a67838dgrogan@chromium.org  // Do not accept build_vectors that aren't all constants or which have non-~0
124179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // elements.
125179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  SDOperand Zero = N->getOperand(i);
126179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if (isa<ConstantSDNode>(Zero)) {
127179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    if (!cast<ConstantSDNode>(Zero)->isNullValue())
128179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      return false;
12995e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  } else if (isa<ConstantFPSDNode>(Zero)) {
130179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    if (!cast<ConstantFPSDNode>(Zero)->isExactlyValue(0.0))
1318cd4ab8303620197cf24282ae8639060efbb326egabor@google.com      return false;
132179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  } else
13308595b9e51ded54851b7664bd38affad63a67838dgrogan@chromium.org    return false;
13413daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com
135179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // Okay, we have at least one ~0 value, check to see if the rest match or are
13611042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.org  // undefs.
13711042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.org  for (++i; i != e; ++i)
138a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org    if (N->getOperand(i) != Zero &&
13995e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org        N->getOperand(i).getOpcode() != ISD::UNDEF)
14095e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org      return false;
141179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  return true;
14208595b9e51ded54851b7664bd38affad63a67838dgrogan@chromium.org}
143179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
144179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// getSetCCSwappedOperands - Return the operation corresponding to (Y op X)
145179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// when given the operation for (X op Y).
146179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgISD::CondCode ISD::getSetCCSwappedOperands(ISD::CondCode Operation) {
147179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // To perform this operation, we just need to swap the L and G bits of the
148179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // operation.
149179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  unsigned OldL = (Operation >> 2) & 1;
150179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  unsigned OldG = (Operation >> 1) & 1;
151179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  return ISD::CondCode((Operation & ~6) |  // Keep the N, U, E bits
152179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org                       (OldL << 1) |       // New G bit
1536635e49a8999ab5e411d5227146a3db17fac2944hans@chromium.org                       (OldG << 2));        // New L bit.
1546635e49a8999ab5e411d5227146a3db17fac2944hans@chromium.org}
155179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
156179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// getSetCCInverse - Return the operation corresponding to !(X op Y), where
157179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// 'op' is a valid SetCC operation.
158179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgISD::CondCode ISD::getSetCCInverse(ISD::CondCode Op, bool isInteger) {
159179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  unsigned Operation = Op;
160179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if (isInteger)
161179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    Operation ^= 7;   // Flip L, G, E bits, but not U.
162179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  else
163a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org    Operation ^= 15;  // Flip all of the condition bits.
164a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  if (Operation > ISD::SETTRUE2)
16513daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com    Operation &= ~8;     // Don't let N and U bits get set.
166179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  return ISD::CondCode(Operation);
167179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
168179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
169179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
170179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// isSignedOp - For an integer comparison, return 1 if the comparison is a
171179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// signed operation and 2 if the result is an unsigned comparison.  Return zero
172179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// if the operation does not depend on the sign of the input (setne and seteq).
17395e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.orgstatic int isSignedOp(ISD::CondCode Opcode) {
17495e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  switch (Opcode) {
17595e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  default: assert(0 && "Illegal integer setcc operation!");
176179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::SETEQ:
177179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::SETNE: return 0;
178179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::SETLT:
179179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::SETLE:
180179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::SETGT:
18195e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  case ISD::SETGE: return 1;
182179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::SETULT:
183179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::SETULE:
184179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::SETUGT:
185179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::SETUGE: return 2;
186179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
187179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
188179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
189179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// getSetCCOrOperation - Return the result of a logical OR between different
190179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// comparisons of identical values: ((X op1 Y) | (X op2 Y)).  This function
191179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// returns SETCC_INVALID if it is not possible to represent the resultant
192179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// comparison.
193179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgISD::CondCode ISD::getSetCCOrOperation(ISD::CondCode Op1, ISD::CondCode Op2,
194179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org                                       bool isInteger) {
195179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if (isInteger && (isSignedOp(Op1) | isSignedOp(Op2)) == 3)
196179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    // Cannot fold a signed integer setcc with an unsigned integer setcc.
197179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    return ISD::SETCC_INVALID;
198179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
199179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  unsigned Op = Op1 | Op2;  // Combine all of the condition bits.
200179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
201179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // If the N and U bits get set then the resultant comparison DOES suddenly
202179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // care about orderedness, and is true when ordered.
203179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if (Op > ISD::SETTRUE2)
204179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    Op &= ~16;     // Clear the U bit if the N bit is set.
205179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
206179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // Canonicalize illegal integer setcc's.
207179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if (isInteger && Op == ISD::SETUNE)  // e.g. SETUGT | SETULT
208179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    Op = ISD::SETNE;
209179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
210179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  return ISD::CondCode(Op);
211179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
212179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
213179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// getSetCCAndOperation - Return the result of a logical AND between different
214f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com/// comparisons of identical values: ((X op1 Y) & (X op2 Y)).  This
215179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// function returns zero if it is not possible to represent the resultant
216179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// comparison.
217179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgISD::CondCode ISD::getSetCCAndOperation(ISD::CondCode Op1, ISD::CondCode Op2,
218179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org                                        bool isInteger) {
219179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if (isInteger && (isSignedOp(Op1) | isSignedOp(Op2)) == 3)
220179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    // Cannot fold a signed setcc with an unsigned setcc.
221179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    return ISD::SETCC_INVALID;
222179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
223179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // Combine all of the condition bits.
224179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ISD::CondCode Result = ISD::CondCode(Op1 & Op2);
225179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
226179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // Canonicalize illegal integer setcc's.
227179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if (isInteger) {
2281511be6edb54b6ade2bfad94256f76bc191e92ecdgrogan@chromium.org    switch (Result) {
2291511be6edb54b6ade2bfad94256f76bc191e92ecdgrogan@chromium.org    default: break;
230179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    case ISD::SETUO : Result = ISD::SETFALSE; break;  // SETUGT & SETULT
231179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    case ISD::SETUEQ: Result = ISD::SETEQ   ; break;  // SETUGE & SETULE
232179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    case ISD::SETOLT: Result = ISD::SETULT  ; break;  // SETULT & SETNE
2338cd4ab8303620197cf24282ae8639060efbb326egabor@google.com    case ISD::SETOGT: Result = ISD::SETUGT  ; break;  // SETUGT & SETNE
23495e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org    }
235179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
236179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
237179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  return Result;
238179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
239179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
240179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgconst TargetMachine &SelectionDAG::getTarget() const {
241179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  return TLI.getTargetMachine();
242179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
243179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
244179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org//===----------------------------------------------------------------------===//
245179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org//                           SDNode Profile Support
246179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org//===----------------------------------------------------------------------===//
247179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
248179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// AddNodeIDOpcode - Add the node opcode to the NodeID data.
249179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org///
250179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgstatic void AddNodeIDOpcode(FoldingSetNodeID &ID, unsigned OpC)  {
251179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ID.AddInteger(OpC);
252179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
253179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
254179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// AddNodeIDValueTypes - Value type lists are intern'd so we can represent them
255179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// solely with their pointer.
256179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgvoid AddNodeIDValueTypes(FoldingSetNodeID &ID, SDVTList VTList) {
257179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ID.AddPointer(VTList.VTs);
258179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
259179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
260f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com/// AddNodeIDOperand - Add an operands data to the NodeID data.
261179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org///
262179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgstatic void AddNodeIDOperand(FoldingSetNodeID &ID, SDOperand Op) {
263179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ID.AddPointer(Op.Val);
264179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ID.AddInteger(Op.ResNo);
265179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
266179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
267179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// AddNodeIDOperands - Various routines for adding operands to the NodeID data.
268179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org///
269179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgstatic void AddNodeIDOperands(FoldingSetNodeID &ID) {
270179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
271179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgstatic void AddNodeIDOperands(FoldingSetNodeID &ID, SDOperand Op) {
272179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  AddNodeIDOperand(ID, Op);
273179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
274179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgstatic void AddNodeIDOperands(FoldingSetNodeID &ID,
275179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org                             SDOperand Op1, SDOperand Op2) {
276179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  AddNodeIDOperand(ID, Op1);
277179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  AddNodeIDOperand(ID, Op2);
278179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
279179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgstatic void AddNodeIDOperands(FoldingSetNodeID &ID,
280179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org                              SDOperand Op1, SDOperand Op2, SDOperand Op3) {
281179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  AddNodeIDOperand(ID, Op1);
282179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  AddNodeIDOperand(ID, Op2);
283179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  AddNodeIDOperand(ID, Op3);
284179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
285179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgstatic void AddNodeIDOperands(FoldingSetNodeID &ID,
286179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org                              const SDOperand *Ops, unsigned NumOps) {
287179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  for (; NumOps; --NumOps, ++Ops)
288179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    AddNodeIDOperand(ID, *Ops);
289179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
290179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
291179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// AddNodeIDOperands - Various routines for adding node info to the NodeID
292179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// data.
293179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgstatic void AddNodeIDNode(FoldingSetNodeID &ID,
294179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org                          unsigned short OpC, SDVTList VTList) {
295179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  AddNodeIDOpcode(ID, OpC);
296179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  AddNodeIDValueTypes(ID, VTList);
297179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  AddNodeIDOperands(ID);
298179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
29995e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.orgstatic void AddNodeIDNode(FoldingSetNodeID &ID,
300179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org                          unsigned short OpC, SDVTList VTList,
301179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org                          SDOperand Op) {
3028cd4ab8303620197cf24282ae8639060efbb326egabor@google.com  AddNodeIDOpcode(ID, OpC);
3038cd4ab8303620197cf24282ae8639060efbb326egabor@google.com  AddNodeIDValueTypes(ID, VTList);
3048cd4ab8303620197cf24282ae8639060efbb326egabor@google.com  AddNodeIDOperands(ID, Op);
3058cd4ab8303620197cf24282ae8639060efbb326egabor@google.com}
3068cd4ab8303620197cf24282ae8639060efbb326egabor@google.comstatic void AddNodeIDNode(FoldingSetNodeID &ID,
3078cd4ab8303620197cf24282ae8639060efbb326egabor@google.com                          unsigned short OpC, SDVTList VTList,
3088cd4ab8303620197cf24282ae8639060efbb326egabor@google.com                          SDOperand Op1, SDOperand Op2) {
3098cd4ab8303620197cf24282ae8639060efbb326egabor@google.com  AddNodeIDOpcode(ID, OpC);
3108cd4ab8303620197cf24282ae8639060efbb326egabor@google.com  AddNodeIDValueTypes(ID, VTList);
3118cd4ab8303620197cf24282ae8639060efbb326egabor@google.com  AddNodeIDOperands(ID, Op1, Op2);
3128cd4ab8303620197cf24282ae8639060efbb326egabor@google.com}
3138cd4ab8303620197cf24282ae8639060efbb326egabor@google.comstatic void AddNodeIDNode(FoldingSetNodeID &ID,
3148cd4ab8303620197cf24282ae8639060efbb326egabor@google.com                          unsigned short OpC, SDVTList VTList,
3158cd4ab8303620197cf24282ae8639060efbb326egabor@google.com                          SDOperand Op1, SDOperand Op2, SDOperand Op3) {
31695e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  AddNodeIDOpcode(ID, OpC);
317bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org  AddNodeIDValueTypes(ID, VTList);
318bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org  AddNodeIDOperands(ID, Op1, Op2, Op3);
3198cd4ab8303620197cf24282ae8639060efbb326egabor@google.com}
3208cd4ab8303620197cf24282ae8639060efbb326egabor@google.comstatic void AddNodeIDNode(FoldingSetNodeID &ID,
3218cd4ab8303620197cf24282ae8639060efbb326egabor@google.com                          unsigned short OpC, SDVTList VTList,
3228cd4ab8303620197cf24282ae8639060efbb326egabor@google.com                          const SDOperand *OpList, unsigned N) {
323bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org  AddNodeIDOpcode(ID, OpC);
324bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org  AddNodeIDValueTypes(ID, VTList);
325bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org  AddNodeIDOperands(ID, OpList, N);
326bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org}
3278cd4ab8303620197cf24282ae8639060efbb326egabor@google.com
328179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// AddNodeIDNode - Generic routine for adding a nodes info to the NodeID
329bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org/// data.
330bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.orgstatic void AddNodeIDNode(FoldingSetNodeID &ID, SDNode *N) {
331bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org  AddNodeIDOpcode(ID, N->getOpcode());
332bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org  // Add the return value info.
333bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org  AddNodeIDValueTypes(ID, N->getVTList());
334bbb0263070defe02ffee97b35d0dc31d3f6297a3dgrogan@chromium.org  // Add the operand info.
3358cd4ab8303620197cf24282ae8639060efbb326egabor@google.com  AddNodeIDOperands(ID, N->op_begin(), N->getNumOperands());
3368cd4ab8303620197cf24282ae8639060efbb326egabor@google.com
3378cd4ab8303620197cf24282ae8639060efbb326egabor@google.com  // Handle SDNode leafs with special info.
3388cd4ab8303620197cf24282ae8639060efbb326egabor@google.com  if (N->getNumOperands() == 0) {
3398cd4ab8303620197cf24282ae8639060efbb326egabor@google.com    switch (N->getOpcode()) {
340394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com    default: break;  // Normal nodes don't need extra info.
341394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com    case ISD::TargetConstant:
342394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com    case ISD::Constant:
343394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com      ID.AddInteger(cast<ConstantSDNode>(N)->getValue());
344394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com      break;
3458cd4ab8303620197cf24282ae8639060efbb326egabor@google.com    case ISD::TargetConstantFP:
3468cd4ab8303620197cf24282ae8639060efbb326egabor@google.com    case ISD::ConstantFP:
347179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      ID.AddDouble(cast<ConstantFPSDNode>(N)->getValue());
34895e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org      break;
34995e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org    case ISD::TargetGlobalAddress:
35095e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org    case ISD::GlobalAddress: {
351179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(N);
352179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      ID.AddPointer(GA->getGlobal());
353179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      ID.AddInteger(GA->getOffset());
354179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      break;
355179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    }
356179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    case ISD::BasicBlock:
357179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      ID.AddPointer(cast<BasicBlockSDNode>(N)->getBasicBlock());
358179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      break;
359179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    case ISD::Register:
360179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      ID.AddInteger(cast<RegisterSDNode>(N)->getReg());
361179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      break;
362f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com    case ISD::SRCVALUE: {
363179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      SrcValueSDNode *SV = cast<SrcValueSDNode>(N);
364179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      ID.AddPointer(SV->getValue());
365179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      ID.AddInteger(SV->getOffset());
366f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com      break;
367179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    }
368179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    case ISD::FrameIndex:
369179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    case ISD::TargetFrameIndex:
370179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      ID.AddInteger(cast<FrameIndexSDNode>(N)->getIndex());
371179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      break;
372179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    case ISD::JumpTable:
373179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    case ISD::TargetJumpTable:
374179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      ID.AddInteger(cast<JumpTableSDNode>(N)->getIndex());
375179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      break;
376179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    case ISD::ConstantPool:
377179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    case ISD::TargetConstantPool: {
378179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(N);
379179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      ID.AddInteger(CP->getAlignment());
380179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      ID.AddInteger(CP->getOffset());
381179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      if (CP->isMachineConstantPoolEntry())
382179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org        CP->getMachineCPVal()->AddSelectionDAGCSEId(ID);
383179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      else
384179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org        ID.AddPointer(CP->getConstVal());
385179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      break;
386179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    }
387179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    case ISD::LOAD: {
388179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      LoadSDNode *LD = cast<LoadSDNode>(N);
389179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      ID.AddInteger(LD->getAddressingMode());
390179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      ID.AddInteger(LD->getExtensionType());
391179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      ID.AddInteger(LD->getLoadedVT());
392179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      ID.AddPointer(LD->getSrcValue());
393179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      ID.AddInteger(LD->getSrcValueOffset());
394a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org      ID.AddInteger(LD->getAlignment());
395a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org      ID.AddInteger(LD->isVolatile());
396f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com      break;
397179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    }
398179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    case ISD::STORE: {
399179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      StoreSDNode *ST = cast<StoreSDNode>(N);
400179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      ID.AddInteger(ST->getAddressingMode());
401179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      ID.AddInteger(ST->isTruncatingStore());
402179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      ID.AddInteger(ST->getStoredVT());
403179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      ID.AddPointer(ST->getSrcValue());
404179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      ID.AddInteger(ST->getSrcValueOffset());
405179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      ID.AddInteger(ST->getAlignment());
406179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      ID.AddInteger(ST->isVolatile());
407179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      break;
408179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    }
409179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    }
410179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
411179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
412179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
413179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org//===----------------------------------------------------------------------===//
414179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org//                              SelectionDAG Class
415a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org//===----------------------------------------------------------------------===//
416179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
417179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// RemoveDeadNodes - This method deletes all unreachable nodes in the
418179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// SelectionDAG.
419179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgvoid SelectionDAG::RemoveDeadNodes() {
420179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // Create a dummy node (which is not added to allnodes), that adds a reference
421179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // to the root node, preventing it from being deleted.
422179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  HandleSDNode Dummy(getRoot());
423179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
424179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  SmallVector<SDNode*, 128> DeadNodes;
425179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
426179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // Add all obviously-dead nodes to the DeadNodes worklist.
427179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  for (allnodes_iterator I = allnodes_begin(), E = allnodes_end(); I != E; ++I)
428179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    if (I->use_empty())
429179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      DeadNodes.push_back(I);
4308cd4ab8303620197cf24282ae8639060efbb326egabor@google.com
431179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // Process the worklist, deleting the nodes and adding their uses to the
432179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // worklist.
433179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  while (!DeadNodes.empty()) {
434179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    SDNode *N = DeadNodes.back();
435179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    DeadNodes.pop_back();
436a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org
437179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    // Take the node out of the appropriate CSE map.
438179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    RemoveNodeFromCSEMaps(N);
439179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
440179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    // Next, brutally remove the operand list.  This is safe to do, as there are
441179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    // no cycles in the graph.
4428cd4ab8303620197cf24282ae8639060efbb326egabor@google.com    for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) {
443179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      SDNode *Operand = I->Val;
444179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      Operand->removeUser(N);
445179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
446179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      // Now that we removed this operand, see if there are no uses of it left.
447a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org      if (Operand->use_empty())
448179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org        DeadNodes.push_back(Operand);
449179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    }
450179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    delete[] N->OperandList;
451179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    N->OperandList = 0;
4528cd4ab8303620197cf24282ae8639060efbb326egabor@google.com    N->NumOperands = 0;
4538cd4ab8303620197cf24282ae8639060efbb326egabor@google.com
454179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    // Finally, remove N itself.
45595e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org    AllNodes.erase(N);
456179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
457179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
458179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // If the root changed (e.g. it was a dead load, update the root).
459179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  setRoot(Dummy.getValue());
460f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com}
461179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
46295e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.orgvoid SelectionDAG::RemoveDeadNode(SDNode *N, std::vector<SDNode*> &Deleted) {
46395e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  SmallVector<SDNode*, 16> DeadNodes;
46495e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  DeadNodes.push_back(N);
46595e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org
4668cd4ab8303620197cf24282ae8639060efbb326egabor@google.com  // Process the worklist, deleting the nodes and adding their uses to the
46795e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  // worklist.
46895e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  while (!DeadNodes.empty()) {
46995e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org    SDNode *N = DeadNodes.back();
470f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com    DeadNodes.pop_back();
471179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
472179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    // Take the node out of the appropriate CSE map.
473179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    RemoveNodeFromCSEMaps(N);
474179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
475179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    // Next, brutally remove the operand list.  This is safe to do, as there are
47695e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org    // no cycles in the graph.
4778cd4ab8303620197cf24282ae8639060efbb326egabor@google.com    for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) {
4788cd4ab8303620197cf24282ae8639060efbb326egabor@google.com      SDNode *Operand = I->Val;
4798cd4ab8303620197cf24282ae8639060efbb326egabor@google.com      Operand->removeUser(N);
4808cd4ab8303620197cf24282ae8639060efbb326egabor@google.com
4818cd4ab8303620197cf24282ae8639060efbb326egabor@google.com      // Now that we removed this operand, see if there are no uses of it left.
482917b88dd720b6e658c1fd7812bc61c605f315124gabor@google.com      if (Operand->use_empty())
483917b88dd720b6e658c1fd7812bc61c605f315124gabor@google.com        DeadNodes.push_back(Operand);
4845fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com    }
4855fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com    delete[] N->OperandList;
4868cd4ab8303620197cf24282ae8639060efbb326egabor@google.com    N->OperandList = 0;
4878cd4ab8303620197cf24282ae8639060efbb326egabor@google.com    N->NumOperands = 0;
4888cd4ab8303620197cf24282ae8639060efbb326egabor@google.com
4898cd4ab8303620197cf24282ae8639060efbb326egabor@google.com    // Finally, remove N itself.
4908cd4ab8303620197cf24282ae8639060efbb326egabor@google.com    Deleted.push_back(N);
49195e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org    AllNodes.erase(N);
49295e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  }
49395e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org}
4948cd4ab8303620197cf24282ae8639060efbb326egabor@google.com
495179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgvoid SelectionDAG::DeleteNode(SDNode *N) {
496179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  assert(N->use_empty() && "Cannot delete a node that is not dead!");
497179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
498179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // First take this out of the appropriate CSE map.
499179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  RemoveNodeFromCSEMaps(N);
50095e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org
501179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // Finally, remove uses due to operands of this node, remove from the
502179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // AllNodes list, and delete the node.
50395e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  DeleteNodeNotInCSEMaps(N);
5048cd4ab8303620197cf24282ae8639060efbb326egabor@google.com}
5058cd4ab8303620197cf24282ae8639060efbb326egabor@google.com
5068cd4ab8303620197cf24282ae8639060efbb326egabor@google.comvoid SelectionDAG::DeleteNodeNotInCSEMaps(SDNode *N) {
5078cd4ab8303620197cf24282ae8639060efbb326egabor@google.com
5088cd4ab8303620197cf24282ae8639060efbb326egabor@google.com  // Remove it from the AllNodes list.
5098cd4ab8303620197cf24282ae8639060efbb326egabor@google.com  AllNodes.remove(N);
5108cd4ab8303620197cf24282ae8639060efbb326egabor@google.com
5118cd4ab8303620197cf24282ae8639060efbb326egabor@google.com  // Drop all of the operands and decrement used nodes use counts.
512179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I)
51395e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org    I->Val->removeUser(N);
514179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  delete[] N->OperandList;
51595e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  N->OperandList = 0;
5168cd4ab8303620197cf24282ae8639060efbb326egabor@google.com  N->NumOperands = 0;
517394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com
518179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  delete N;
519179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
520179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
521179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// RemoveNodeFromCSEMaps - Take the specified node out of the CSE map that
522a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org/// correspond to it.  This is useful when we're about to delete or repurpose
52395e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org/// the node.  We don't want future request for structurally identical nodes
52495e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org/// to return N anymore.
525179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgvoid SelectionDAG::RemoveNodeFromCSEMaps(SDNode *N) {
526179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  bool Erased = false;
52795e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  switch (N->getOpcode()) {
528179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::HANDLENODE: return;  // noop.
529179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::STRING:
530179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    Erased = StringNodes.erase(cast<StringSDNode>(N)->getValue());
5315fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com    break;
5325fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com  case ISD::CONDCODE:
5335fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com    assert(CondCodeNodes[cast<CondCodeSDNode>(N)->get()] &&
5345fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com           "Cond code doesn't exist!");
5355fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com    Erased = CondCodeNodes[cast<CondCodeSDNode>(N)->get()] != 0;
5365fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com    CondCodeNodes[cast<CondCodeSDNode>(N)->get()] = 0;
5375fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com    break;
5385fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com  case ISD::ExternalSymbol:
5395fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com    Erased = ExternalSymbols.erase(cast<ExternalSymbolSDNode>(N)->getSymbol());
5405fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com    break;
5415fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com  case ISD::TargetExternalSymbol:
5425fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com    Erased =
5435fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com      TargetExternalSymbols.erase(cast<ExternalSymbolSDNode>(N)->getSymbol());
5445fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com    break;
5455fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com  case ISD::VALUETYPE:
5465fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com    Erased = ValueTypeNodes[cast<VTSDNode>(N)->getVT()] != 0;
5475fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com    ValueTypeNodes[cast<VTSDNode>(N)->getVT()] = 0;
5485fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com    break;
5498cd4ab8303620197cf24282ae8639060efbb326egabor@google.com  default:
5508cd4ab8303620197cf24282ae8639060efbb326egabor@google.com    // Remove it from the CSE Map.
5518cd4ab8303620197cf24282ae8639060efbb326egabor@google.com    Erased = CSEMap.RemoveNode(N);
5525fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com    break;
5535fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com  }
5546635e49a8999ab5e411d5227146a3db17fac2944hans@chromium.org#ifndef NDEBUG
5556635e49a8999ab5e411d5227146a3db17fac2944hans@chromium.org  // Verify that the node was actually in one of the CSE maps, unless it has a
5565fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com  // flag result (which cannot be CSE'd) or is one of the special cases that are
5575fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com  // not subject to CSE.
5585fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com  if (!Erased && N->getValueType(N->getNumValues()-1) != MVT::Flag &&
5595fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com      !N->isTargetOpcode()) {
5605fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com    N->dump();
5615fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com    cerr << "\n";
5625fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com    assert(0 && "Node is not in map!");
5635fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com  }
5645fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com#endif
5655fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com}
5665fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com
5675fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com/// AddNonLeafNodeToCSEMaps - Add the specified node back to the CSE maps.  It
5685fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com/// has been taken out and modified in some way.  If the specified node already
5695fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com/// exists in the CSE maps, do not modify the maps, but return the existing node
5705fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com/// instead.  If it doesn't exist, add it and return null.
5715fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com///
5725fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.comSDNode *SelectionDAG::AddNonLeafNodeToCSEMaps(SDNode *N) {
5735fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com  assert(N->getNumOperands() && "This is a leaf node!");
5745fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com  if (N->getOpcode() == ISD::HANDLENODE || N->getValueType(0) == MVT::Flag)
5755fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com    return 0;    // Never add these nodes.
5765fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com
5775fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com  // Check that remaining values produced are not flags.
5785fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com  for (unsigned i = 1, e = N->getNumValues(); i != e; ++i)
5795fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com    if (N->getValueType(i) == MVT::Flag)
5806635e49a8999ab5e411d5227146a3db17fac2944hans@chromium.org      return 0;   // Never CSE anything that produces a flag.
581179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
582179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  SDNode *New = CSEMap.GetOrInsertNode(N);
583179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if (New != N) return New;  // Node already existed.
58413daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com  return 0;
58513daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com}
58695e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org
58795e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org/// FindModifiedNodeSlot - Find a slot for the specified node if its operands
58813daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com/// were replaced with those specified.  If this node is never memoized,
58995e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org/// return null, otherwise return a pointer to the slot it would take.  If a
5906635e49a8999ab5e411d5227146a3db17fac2944hans@chromium.org/// node already exists with these operands, the slot will be non-null.
59195e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.orgSDNode *SelectionDAG::FindModifiedNodeSlot(SDNode *N, SDOperand Op,
59295e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org                                           void *&InsertPos) {
59395e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  if (N->getOpcode() == ISD::HANDLENODE || N->getValueType(0) == MVT::Flag)
59495e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org    return 0;    // Never add these nodes.
59595e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org
59695e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  // Check that remaining values produced are not flags.
597179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  for (unsigned i = 1, e = N->getNumValues(); i != e; ++i)
598179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    if (N->getValueType(i) == MVT::Flag)
599179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      return 0;   // Never CSE anything that produces a flag.
600179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
601179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  FoldingSetNodeID ID;
602179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  AddNodeIDNode(ID, N->getOpcode(), N->getVTList(), Op);
603179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  return CSEMap.FindNodeOrInsertPos(ID, InsertPos);
604179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
6056635e49a8999ab5e411d5227146a3db17fac2944hans@chromium.org
6066635e49a8999ab5e411d5227146a3db17fac2944hans@chromium.org/// FindModifiedNodeSlot - Find a slot for the specified node if its operands
6076635e49a8999ab5e411d5227146a3db17fac2944hans@chromium.org/// were replaced with those specified.  If this node is never memoized,
608179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// return null, otherwise return a pointer to the slot it would take.  If a
609179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// node already exists with these operands, the slot will be non-null.
610179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgSDNode *SelectionDAG::FindModifiedNodeSlot(SDNode *N,
611179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org                                           SDOperand Op1, SDOperand Op2,
612179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org                                           void *&InsertPos) {
613179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if (N->getOpcode() == ISD::HANDLENODE || N->getValueType(0) == MVT::Flag)
614179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    return 0;    // Never add these nodes.
615179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
616179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // Check that remaining values produced are not flags.
617179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  for (unsigned i = 1, e = N->getNumValues(); i != e; ++i)
618179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    if (N->getValueType(i) == MVT::Flag)
619179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      return 0;   // Never CSE anything that produces a flag.
620179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
621179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  FoldingSetNodeID ID;
6226635e49a8999ab5e411d5227146a3db17fac2944hans@chromium.org  AddNodeIDNode(ID, N->getOpcode(), N->getVTList(), Op1, Op2);
623158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com  return CSEMap.FindNodeOrInsertPos(ID, InsertPos);
62429c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org}
62529c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org
62611042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.org
62729c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org/// FindModifiedNodeSlot - Find a slot for the specified node if its operands
62829c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org/// were replaced with those specified.  If this node is never memoized,
62929c68f16466b1704dc7a663cf51bf9c5579830c3dgrogan@chromium.org/// return null, otherwise return a pointer to the slot it would take.  If a
630158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com/// node already exists with these operands, the slot will be non-null.
631158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.comSDNode *SelectionDAG::FindModifiedNodeSlot(SDNode *N,
632158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com                                           const SDOperand *Ops,unsigned NumOps,
633158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com                                           void *&InsertPos) {
634158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com  if (N->getOpcode() == ISD::HANDLENODE || N->getValueType(0) == MVT::Flag)
635158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com    return 0;    // Never add these nodes.
636158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com
637158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com  // Check that remaining values produced are not flags.
63811042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.org  for (unsigned i = 1, e = N->getNumValues(); i != e; ++i)
63911042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.org    if (N->getValueType(i) == MVT::Flag)
64011042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.org      return 0;   // Never CSE anything that produces a flag.
64111042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.org
64211042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.org  FoldingSetNodeID ID;
64311042098fe3e5a16ad70c388bb5914a907ae3faedgrogan@chromium.org  AddNodeIDNode(ID, N->getOpcode(), N->getVTList());
644158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com
645158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com  if (const LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) {
646179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    ID.AddInteger(LD->getAddressingMode());
647158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com    ID.AddInteger(LD->getExtensionType());
648179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    ID.AddInteger(LD->getLoadedVT());
649179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    ID.AddPointer(LD->getSrcValue());
650179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    ID.AddInteger(LD->getSrcValueOffset());
651179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    ID.AddInteger(LD->getAlignment());
652179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    ID.AddInteger(LD->isVolatile());
6536635e49a8999ab5e411d5227146a3db17fac2944hans@chromium.org  } else if (const StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) {
654179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    ID.AddInteger(ST->getAddressingMode());
655179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    ID.AddInteger(ST->isTruncatingStore());
656158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com    ID.AddInteger(ST->getStoredVT());
657179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    ID.AddPointer(ST->getSrcValue());
65895e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org    ID.AddInteger(ST->getSrcValueOffset());
65995e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org    ID.AddInteger(ST->getAlignment());
660158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com    ID.AddInteger(ST->isVolatile());
66195e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  }
66295e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org
6636635e49a8999ab5e411d5227146a3db17fac2944hans@chromium.org  AddNodeIDOperands(ID, Ops, NumOps);
6646635e49a8999ab5e411d5227146a3db17fac2944hans@chromium.org  return CSEMap.FindNodeOrInsertPos(ID, InsertPos);
6655fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com}
6666635e49a8999ab5e411d5227146a3db17fac2944hans@chromium.org
6675fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com
6685fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.comSelectionDAG::~SelectionDAG() {
6695fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com  while (!AllNodes.empty()) {
6705fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com    SDNode *N = AllNodes.begin();
6715fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com    N->SetNextInBucket(0);
6725fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com    delete [] N->OperandList;
6735fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com    N->OperandList = 0;
6745fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com    N->NumOperands = 0;
6756635e49a8999ab5e411d5227146a3db17fac2944hans@chromium.org    AllNodes.pop_front();
6765fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com  }
6775fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com}
6785fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com
6796635e49a8999ab5e411d5227146a3db17fac2944hans@chromium.orgSDOperand SelectionDAG::getZeroExtendInReg(SDOperand Op, MVT::ValueType VT) {
6806635e49a8999ab5e411d5227146a3db17fac2944hans@chromium.org  if (Op.getValueType() == VT) return Op;
681179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  int64_t Imm = ~0ULL >> (64-MVT::getSizeInBits(VT));
682179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  return getNode(ISD::AND, Op.getValueType(), Op,
683179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org                 getConstant(Imm, Op.getValueType()));
6846635e49a8999ab5e411d5227146a3db17fac2944hans@chromium.org}
6856635e49a8999ab5e411d5227146a3db17fac2944hans@chromium.org
6866635e49a8999ab5e411d5227146a3db17fac2944hans@chromium.orgSDOperand SelectionDAG::getString(const std::string &Val) {
687179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  StringSDNode *&N = StringNodes[Val];
688b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org  if (!N) {
689179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    N = new StringSDNode(Val);
690179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    AllNodes.push_back(N);
691179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
692179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  return SDOperand(N, 0);
693394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com}
6946635e49a8999ab5e411d5227146a3db17fac2944hans@chromium.org
695f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.comSDOperand SelectionDAG::getConstant(uint64_t Val, MVT::ValueType VT, bool isT) {
696179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  assert(MVT::isInteger(VT) && "Cannot create FP integer constant!");
697179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  assert(!MVT::isVector(VT) && "Cannot create Vector ConstantSDNodes!");
698179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
6996635e49a8999ab5e411d5227146a3db17fac2944hans@chromium.org  // Mask out any bits that are not valid for this constant.
7006635e49a8999ab5e411d5227146a3db17fac2944hans@chromium.org  Val &= MVT::getIntVTBitMask(VT);
701179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
702179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  unsigned Opc = isT ? ISD::TargetConstant : ISD::Constant;
703179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  FoldingSetNodeID ID;
704179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  AddNodeIDNode(ID, Opc, getVTList(VT));
705e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com  ID.AddInteger(Val);
706e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com  void *IP = 0;
707179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
708179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    return SDOperand(E, 0);
709179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  SDNode *N = new ConstantSDNode(isT, Val, VT);
710179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  CSEMap.InsertNode(N, IP);
711179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  AllNodes.push_back(N);
712179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  return SDOperand(N, 0);
713179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
714179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
715f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com
716179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgSDOperand SelectionDAG::getConstantFP(double Val, MVT::ValueType VT,
717179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org                                      bool isTarget) {
718179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  assert(MVT::isFloatingPoint(VT) && "Cannot create integer FP constant!");
719179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if (VT == MVT::f32)
720179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    Val = (float)Val;  // Mask out extra precision.
7216635e49a8999ab5e411d5227146a3db17fac2944hans@chromium.org
7226635e49a8999ab5e411d5227146a3db17fac2944hans@chromium.org  // Do the map lookup using the actual bit pattern for the floating point
7235fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com  // value, so that we don't have problems with 0.0 comparing equal to -0.0, and
724e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com  // we don't have issues with SNANs.
725e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com  unsigned Opc = isTarget ? ISD::TargetConstantFP : ISD::ConstantFP;
726e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com  FoldingSetNodeID ID;
7275fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com  AddNodeIDNode(ID, Opc, getVTList(VT));
7285fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com  ID.AddDouble(Val);
7295fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com  void *IP = 0;
7305fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
7315fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com    return SDOperand(E, 0);
7325fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com  SDNode *N = new ConstantFPSDNode(isTarget, Val, VT);
7336635e49a8999ab5e411d5227146a3db17fac2944hans@chromium.org  CSEMap.InsertNode(N, IP);
7346635e49a8999ab5e411d5227146a3db17fac2944hans@chromium.org  AllNodes.push_back(N);
735158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com  return SDOperand(N, 0);
736179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
737179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
738179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgSDOperand SelectionDAG::getGlobalAddress(const GlobalValue *GV,
739179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org                                         MVT::ValueType VT, int Offset,
740179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org                                         bool isTargetGA) {
741179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  unsigned Opc = isTargetGA ? ISD::TargetGlobalAddress : ISD::GlobalAddress;
742179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  FoldingSetNodeID ID;
743179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  AddNodeIDNode(ID, Opc, getVTList(VT));
744179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ID.AddPointer(GV);
745179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ID.AddInteger(Offset);
746179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  void *IP = 0;
747179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
7481511be6edb54b6ade2bfad94256f76bc191e92ecdgrogan@chromium.org   return SDOperand(E, 0);
749179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  SDNode *N = new GlobalAddressSDNode(isTargetGA, GV, VT, Offset);
750179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  CSEMap.InsertNode(N, IP);
751179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  AllNodes.push_back(N);
752179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  return SDOperand(N, 0);
753179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
754179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
755179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgSDOperand SelectionDAG::getFrameIndex(int FI, MVT::ValueType VT,
756179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org                                      bool isTarget) {
757179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  unsigned Opc = isTarget ? ISD::TargetFrameIndex : ISD::FrameIndex;
758179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  FoldingSetNodeID ID;
759179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  AddNodeIDNode(ID, Opc, getVTList(VT));
760179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ID.AddInteger(FI);
761179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  void *IP = 0;
762179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
763179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    return SDOperand(E, 0);
764179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  SDNode *N = new FrameIndexSDNode(FI, VT, isTarget);
765179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  CSEMap.InsertNode(N, IP);
766179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  AllNodes.push_back(N);
767179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  return SDOperand(N, 0);
768179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
769179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
770179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgSDOperand SelectionDAG::getJumpTable(int JTI, MVT::ValueType VT, bool isTarget){
771179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  unsigned Opc = isTarget ? ISD::TargetJumpTable : ISD::JumpTable;
772179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  FoldingSetNodeID ID;
773179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  AddNodeIDNode(ID, Opc, getVTList(VT));
774179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ID.AddInteger(JTI);
775179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  void *IP = 0;
776179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
777179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    return SDOperand(E, 0);
778179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  SDNode *N = new JumpTableSDNode(JTI, VT, isTarget);
779179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  CSEMap.InsertNode(N, IP);
780179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  AllNodes.push_back(N);
781179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  return SDOperand(N, 0);
782179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
783179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
784179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgSDOperand SelectionDAG::getConstantPool(Constant *C, MVT::ValueType VT,
785179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org                                        unsigned Alignment, int Offset,
786179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org                                        bool isTarget) {
787179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  unsigned Opc = isTarget ? ISD::TargetConstantPool : ISD::ConstantPool;
788179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  FoldingSetNodeID ID;
789179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  AddNodeIDNode(ID, Opc, getVTList(VT));
790179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ID.AddInteger(Alignment);
791179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ID.AddInteger(Offset);
792179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ID.AddPointer(C);
793179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  void *IP = 0;
794179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
795179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    return SDOperand(E, 0);
796179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  SDNode *N = new ConstantPoolSDNode(isTarget, C, VT, Offset, Alignment);
797179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  CSEMap.InsertNode(N, IP);
798179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  AllNodes.push_back(N);
799179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  return SDOperand(N, 0);
800179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
801179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
802179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
803179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgSDOperand SelectionDAG::getConstantPool(MachineConstantPoolValue *C,
804179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org                                        MVT::ValueType VT,
805179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org                                        unsigned Alignment, int Offset,
806179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org                                        bool isTarget) {
807179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  unsigned Opc = isTarget ? ISD::TargetConstantPool : ISD::ConstantPool;
808179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  FoldingSetNodeID ID;
809179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  AddNodeIDNode(ID, Opc, getVTList(VT));
810179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ID.AddInteger(Alignment);
811179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ID.AddInteger(Offset);
812179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  C->AddSelectionDAGCSEId(ID);
813179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  void *IP = 0;
814179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
815f85ede82f8c27a00c3120f67fbab89b2a89fe987jorlow@chromium.org    return SDOperand(E, 0);
816f85ede82f8c27a00c3120f67fbab89b2a89fe987jorlow@chromium.org  SDNode *N = new ConstantPoolSDNode(isTarget, C, VT, Offset, Alignment);
817f85ede82f8c27a00c3120f67fbab89b2a89fe987jorlow@chromium.org  CSEMap.InsertNode(N, IP);
818179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  AllNodes.push_back(N);
819179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  return SDOperand(N, 0);
820179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
821f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com
822179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
823179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgSDOperand SelectionDAG::getBasicBlock(MachineBasicBlock *MBB) {
824179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  FoldingSetNodeID ID;
825179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  AddNodeIDNode(ID, ISD::BasicBlock, getVTList(MVT::Other));
826179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ID.AddPointer(MBB);
827179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  void *IP = 0;
828179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
829179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    return SDOperand(E, 0);
830179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  SDNode *N = new BasicBlockSDNode(MBB);
831179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  CSEMap.InsertNode(N, IP);
832179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  AllNodes.push_back(N);
833179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  return SDOperand(N, 0);
834f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com}
835179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
836179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgSDOperand SelectionDAG::getValueType(MVT::ValueType VT) {
837179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if ((unsigned)VT >= ValueTypeNodes.size())
838179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    ValueTypeNodes.resize(VT+1);
839179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if (ValueTypeNodes[VT] == 0) {
840179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    ValueTypeNodes[VT] = new VTSDNode(VT);
841179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    AllNodes.push_back(ValueTypeNodes[VT]);
842179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
843179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
8441511be6edb54b6ade2bfad94256f76bc191e92ecdgrogan@chromium.org  return SDOperand(ValueTypeNodes[VT], 0);
845179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
846179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
847179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgSDOperand SelectionDAG::getExternalSymbol(const char *Sym, MVT::ValueType VT) {
848179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  SDNode *&N = ExternalSymbols[Sym];
849179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if (N) return SDOperand(N, 0);
850e05bd5cade19e5de0f763f4f122eef9f35de3d9csanjay@google.com  N = new ExternalSymbolSDNode(false, Sym, VT);
851179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  AllNodes.push_back(N);
852179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  return SDOperand(N, 0);
853179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
85495e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org
85595e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.orgSDOperand SelectionDAG::getTargetExternalSymbol(const char *Sym,
85695e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org                                                MVT::ValueType VT) {
857f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com  SDNode *&N = TargetExternalSymbols[Sym];
858179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if (N) return SDOperand(N, 0);
859179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  N = new ExternalSymbolSDNode(true, Sym, VT);
860179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  AllNodes.push_back(N);
861179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  return SDOperand(N, 0);
862179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
863179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
864179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgSDOperand SelectionDAG::getCondCode(ISD::CondCode Cond) {
865179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if ((unsigned)Cond >= CondCodeNodes.size())
866179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    CondCodeNodes.resize(Cond+1);
86795e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org
868179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if (CondCodeNodes[Cond] == 0) {
869179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    CondCodeNodes[Cond] = new CondCodeSDNode(Cond);
870179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    AllNodes.push_back(CondCodeNodes[Cond]);
871179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
872179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  return SDOperand(CondCodeNodes[Cond], 0);
873179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
874179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
875179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgSDOperand SelectionDAG::getRegister(unsigned RegNo, MVT::ValueType VT) {
876179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  FoldingSetNodeID ID;
877179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  AddNodeIDNode(ID, ISD::Register, getVTList(VT));
878179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ID.AddInteger(RegNo);
879179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  void *IP = 0;
880179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
881179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    return SDOperand(E, 0);
882179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  SDNode *N = new RegisterSDNode(RegNo, VT);
88395e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  CSEMap.InsertNode(N, IP);
88495e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  AllNodes.push_back(N);
88595e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  return SDOperand(N, 0);
88695e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org}
88795e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org
88895e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.orgSDOperand SelectionDAG::getSrcValue(const Value *V, int Offset) {
8896635e49a8999ab5e411d5227146a3db17fac2944hans@chromium.org  assert((!V || isa<PointerType>(V->getType())) &&
89095e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org         "SrcValue is not a pointer?");
89195e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org
89295e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  FoldingSetNodeID ID;
89395e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  AddNodeIDNode(ID, ISD::SRCVALUE, getVTList(MVT::Other));
89495e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  ID.AddPointer(V);
895179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  ID.AddInteger(Offset);
896a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  void *IP = 0;
897b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
898b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org    return SDOperand(E, 0);
899b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org  SDNode *N = new SrcValueSDNode(V, Offset);
900b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org  CSEMap.InsertNode(N, IP);
901b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org  AllNodes.push_back(N);
902b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org  return SDOperand(N, 0);
903b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org}
904b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org
905179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgSDOperand SelectionDAG::FoldSetCC(MVT::ValueType VT, SDOperand N1,
906179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org                                  SDOperand N2, ISD::CondCode Cond) {
907179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // These setcc operations always fold.
908179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  switch (Cond) {
909179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  default: break;
910179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::SETFALSE:
911179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::SETFALSE2: return getConstant(0, VT);
912179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::SETTRUE:
913179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::SETTRUE2:  return getConstant(1, VT);
914179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
915179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::SETOEQ:
916179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::SETOGT:
917179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::SETOGE:
918179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::SETOLT:
919179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::SETOLE:
920179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::SETONE:
921179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::SETO:
922179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::SETUO:
923179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::SETUEQ:
924179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::SETUNE:
925179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    assert(!MVT::isInteger(N1.getValueType()) && "Illegal setcc for integer!");
926179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    break;
927179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
928179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
929179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if (ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2.Val)) {
930179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    uint64_t C2 = N2C->getValue();
931179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    if (ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.Val)) {
932179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      uint64_t C1 = N1C->getValue();
933179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
934179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      // Sign extend the operands if required
935179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      if (ISD::isSignedIntSetCC(Cond)) {
936179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org        C1 = N1C->getSignExtended();
937179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org        C2 = N2C->getSignExtended();
938179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      }
939179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
940f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com      switch (Cond) {
941179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      default: assert(0 && "Unknown integer setcc!");
942179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      case ISD::SETEQ:  return getConstant(C1 == C2, VT);
943179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      case ISD::SETNE:  return getConstant(C1 != C2, VT);
9441511be6edb54b6ade2bfad94256f76bc191e92ecdgrogan@chromium.org      case ISD::SETULT: return getConstant(C1 <  C2, VT);
945179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      case ISD::SETUGT: return getConstant(C1 >  C2, VT);
946179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      case ISD::SETULE: return getConstant(C1 <= C2, VT);
947179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      case ISD::SETUGE: return getConstant(C1 >= C2, VT);
948179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      case ISD::SETLT:  return getConstant((int64_t)C1 <  (int64_t)C2, VT);
949179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      case ISD::SETGT:  return getConstant((int64_t)C1 >  (int64_t)C2, VT);
950179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      case ISD::SETLE:  return getConstant((int64_t)C1 <= (int64_t)C2, VT);
951179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      case ISD::SETGE:  return getConstant((int64_t)C1 >= (int64_t)C2, VT);
952179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      }
953179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    }
954179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
955179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if (ConstantFPSDNode *N1C = dyn_cast<ConstantFPSDNode>(N1.Val))
956179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    if (ConstantFPSDNode *N2C = dyn_cast<ConstantFPSDNode>(N2.Val)) {
957179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      double C1 = N1C->getValue(), C2 = N2C->getValue();
958179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
959179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      switch (Cond) {
960179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      default: break; // FIXME: Implement the rest of these!
9611511be6edb54b6ade2bfad94256f76bc191e92ecdgrogan@chromium.org      case ISD::SETEQ:  return getConstant(C1 == C2, VT);
962179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      case ISD::SETNE:  return getConstant(C1 != C2, VT);
963179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      case ISD::SETLT:  return getConstant(C1 < C2, VT);
964179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      case ISD::SETGT:  return getConstant(C1 > C2, VT);
965179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      case ISD::SETLE:  return getConstant(C1 <= C2, VT);
966179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      case ISD::SETGE:  return getConstant(C1 >= C2, VT);
967179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      }
968179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    } else {
969179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      // Ensure that the constant occurs on the RHS.
970179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      return getSetCC(VT, N2, N1, ISD::getSetCCSwappedOperands(Cond));
971179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    }
972179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
973179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // Could not fold it.
974179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  return SDOperand();
975179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org}
976179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
977179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
978179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org/// getNode - Gets or creates the specified node.
979179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org///
980179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgSDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT) {
981179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  FoldingSetNodeID ID;
982179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  AddNodeIDNode(ID, Opcode, getVTList(VT));
983179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  void *IP = 0;
984179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
985179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    return SDOperand(E, 0);
986179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  SDNode *N = new SDNode(Opcode, VT);
987179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  CSEMap.InsertNode(N, IP);
98895e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org
98995e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  AllNodes.push_back(N);
99095e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  return SDOperand(N, 0);
99195e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org}
99295e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org
99395e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.orgSDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
99495e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org                                SDOperand Operand) {
9951511be6edb54b6ade2bfad94256f76bc191e92ecdgrogan@chromium.org  unsigned Tmp1;
99695e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  // Constant fold unary operations with an integer constant operand.
99795e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Operand.Val)) {
99895e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org    uint64_t Val = C->getValue();
999179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    switch (Opcode) {
100095e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org    default: break;
1001179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    case ISD::SIGN_EXTEND: return getConstant(C->getSignExtended(), VT);
1002179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    case ISD::ANY_EXTEND:
1003179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    case ISD::ZERO_EXTEND: return getConstant(Val, VT);
1004179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    case ISD::TRUNCATE:    return getConstant(Val, VT);
1005a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org    case ISD::SINT_TO_FP:  return getConstantFP(C->getSignExtended(), VT);
1006f65a55c8d0744b95be29a65d06b59b22b012f37bgabor@google.com    case ISD::UINT_TO_FP:  return getConstantFP(C->getValue(), VT);
1007a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org    case ISD::BIT_CONVERT:
1008179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      if (VT == MVT::f32 && C->getValueType(0) == MVT::i32)
1009179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org        return getConstantFP(BitsToFloat(Val), VT);
1010179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      else if (VT == MVT::f64 && C->getValueType(0) == MVT::i64)
1011c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org        return getConstantFP(BitsToDouble(Val), VT);
1012c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org      break;
1013c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org    case ISD::BSWAP:
1014c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org      switch(VT) {
1015c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org      default: assert(0 && "Invalid bswap!"); break;
1016c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org      case MVT::i16: return getConstant(ByteSwap_16((unsigned short)Val), VT);
1017c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org      case MVT::i32: return getConstant(ByteSwap_32((unsigned)Val), VT);
1018c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org      case MVT::i64: return getConstant(ByteSwap_64(Val), VT);
1019c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org      }
1020c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org      break;
1021c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org    case ISD::CTPOP:
1022c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org      switch(VT) {
1023c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org      default: assert(0 && "Invalid ctpop!"); break;
1024c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org      case MVT::i1: return getConstant(Val != 0, VT);
1025c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org      case MVT::i8:
1026c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org        Tmp1 = (unsigned)Val & 0xFF;
1027c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org        return getConstant(CountPopulation_32(Tmp1), VT);
102845b9940be332834440bd5299419f396e38085ebehans@chromium.org      case MVT::i16:
1029c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org        Tmp1 = (unsigned)Val & 0xFFFF;
1030179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org        return getConstant(CountPopulation_32(Tmp1), VT);
103108595b9e51ded54851b7664bd38affad63a67838dgrogan@chromium.org      case MVT::i32:
103208595b9e51ded54851b7664bd38affad63a67838dgrogan@chromium.org        return getConstant(CountPopulation_32((unsigned)Val), VT);
1033c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org      case MVT::i64:
1034179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org        return getConstant(CountPopulation_64(Val), VT);
103595e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org      }
1036179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    case ISD::CTLZ:
1037179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      switch(VT) {
1038179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      default: assert(0 && "Invalid ctlz!"); break;
1039179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      case MVT::i1: return getConstant(Val == 0, VT);
1040c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org      case MVT::i8:
104195e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org        Tmp1 = (unsigned)Val & 0xFF;
104295e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org        return getConstant(CountLeadingZeros_32(Tmp1)-24, VT);
1043c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org      case MVT::i16:
104495e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org        Tmp1 = (unsigned)Val & 0xFFFF;
1045179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org        return getConstant(CountLeadingZeros_32(Tmp1)-16, VT);
1046179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      case MVT::i32:
1047179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org        return getConstant(CountLeadingZeros_32((unsigned)Val), VT);
1048179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      case MVT::i64:
1049c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org        return getConstant(CountLeadingZeros_64(Val), VT);
1050c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org      }
1051c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org    case ISD::CTTZ:
1052c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org      switch(VT) {
1053c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org      default: assert(0 && "Invalid cttz!"); break;
1054c6ac22e779e5135e494ddeb1d8e2b6008e9b619edgrogan@chromium.org      case MVT::i1: return getConstant(Val == 0, VT);
1055179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      case MVT::i8:
105608595b9e51ded54851b7664bd38affad63a67838dgrogan@chromium.org        Tmp1 = (unsigned)Val | 0x100;
1057179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org        return getConstant(CountTrailingZeros_32(Tmp1), VT);
1058179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      case MVT::i16:
1059179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org        Tmp1 = (unsigned)Val | 0x10000;
1060179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org        return getConstant(CountTrailingZeros_32(Tmp1), VT);
1061179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      case MVT::i32:
1062179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org        return getConstant(CountTrailingZeros_32((unsigned)Val), VT);
106308595b9e51ded54851b7664bd38affad63a67838dgrogan@chromium.org      case MVT::i64:
106408595b9e51ded54851b7664bd38affad63a67838dgrogan@chromium.org        return getConstant(CountTrailingZeros_64(Val), VT);
1065179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      }
1066179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    }
106707f3bcfb9764be2a339cc02cf0a0d6edb151defbjorlow@chromium.org  }
1068b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org
1069b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org  // Constant fold unary operations with an floating point constant operand.
1070b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org  if (ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(Operand.Val))
1071b887f640bae906abfb77fdf418be63350b4c5e1fjorlow@chromium.org    switch (Opcode) {
1072179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    case ISD::FNEG:
1073179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      return getConstantFP(-C->getValue(), VT);
1074179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    case ISD::FABS:
10758cd4ab8303620197cf24282ae8639060efbb326egabor@google.com      return getConstantFP(fabs(C->getValue()), VT);
10768cd4ab8303620197cf24282ae8639060efbb326egabor@google.com    case ISD::FP_ROUND:
10778cd4ab8303620197cf24282ae8639060efbb326egabor@google.com    case ISD::FP_EXTEND:
10788cd4ab8303620197cf24282ae8639060efbb326egabor@google.com      return getConstantFP(C->getValue(), VT);
10798cd4ab8303620197cf24282ae8639060efbb326egabor@google.com    case ISD::FP_TO_SINT:
10808cd4ab8303620197cf24282ae8639060efbb326egabor@google.com      return getConstant((int64_t)C->getValue(), VT);
10818cd4ab8303620197cf24282ae8639060efbb326egabor@google.com    case ISD::FP_TO_UINT:
1082179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      return getConstant((uint64_t)C->getValue(), VT);
10838cd4ab8303620197cf24282ae8639060efbb326egabor@google.com    case ISD::BIT_CONVERT:
1084d36ce84e66c7d3cee978fbeb52721c30dfb842a5gabor@google.com      if (VT == MVT::i32 && C->getValueType(0) == MVT::f32)
1085d36ce84e66c7d3cee978fbeb52721c30dfb842a5gabor@google.com        return getConstant(FloatToBits(C->getValue()), VT);
10868cd4ab8303620197cf24282ae8639060efbb326egabor@google.com      else if (VT == MVT::i64 && C->getValueType(0) == MVT::f64)
1087d36ce84e66c7d3cee978fbeb52721c30dfb842a5gabor@google.com        return getConstant(DoubleToBits(C->getValue()), VT);
1088d36ce84e66c7d3cee978fbeb52721c30dfb842a5gabor@google.com      break;
10898cd4ab8303620197cf24282ae8639060efbb326egabor@google.com    }
1090d36ce84e66c7d3cee978fbeb52721c30dfb842a5gabor@google.com
1091d36ce84e66c7d3cee978fbeb52721c30dfb842a5gabor@google.com  unsigned OpOpcode = Operand.Val->getOpcode();
10928cd4ab8303620197cf24282ae8639060efbb326egabor@google.com  switch (Opcode) {
1093d36ce84e66c7d3cee978fbeb52721c30dfb842a5gabor@google.com  case ISD::TokenFactor:
1094d36ce84e66c7d3cee978fbeb52721c30dfb842a5gabor@google.com    return Operand;         // Factor of one node?  No factor.
1095d36ce84e66c7d3cee978fbeb52721c30dfb842a5gabor@google.com  case ISD::SIGN_EXTEND:
10968cd4ab8303620197cf24282ae8639060efbb326egabor@google.com    if (Operand.getValueType() == VT) return Operand;   // noop extension
1097d36ce84e66c7d3cee978fbeb52721c30dfb842a5gabor@google.com    assert(Operand.getValueType() < VT && "Invalid sext node, dst < src!");
1098d36ce84e66c7d3cee978fbeb52721c30dfb842a5gabor@google.com    if (OpOpcode == ISD::SIGN_EXTEND || OpOpcode == ISD::ZERO_EXTEND)
1099394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com      return getNode(OpOpcode, VT, Operand.Val->getOperand(0));
1100d36ce84e66c7d3cee978fbeb52721c30dfb842a5gabor@google.com    break;
1101394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com  case ISD::ZERO_EXTEND:
1102d36ce84e66c7d3cee978fbeb52721c30dfb842a5gabor@google.com    if (Operand.getValueType() == VT) return Operand;   // noop extension
1103d36ce84e66c7d3cee978fbeb52721c30dfb842a5gabor@google.com    assert(Operand.getValueType() < VT && "Invalid zext node, dst < src!");
1104d36ce84e66c7d3cee978fbeb52721c30dfb842a5gabor@google.com    if (OpOpcode == ISD::ZERO_EXTEND)   // (zext (zext x)) -> (zext x)
1105d36ce84e66c7d3cee978fbeb52721c30dfb842a5gabor@google.com      return getNode(ISD::ZERO_EXTEND, VT, Operand.Val->getOperand(0));
1106d36ce84e66c7d3cee978fbeb52721c30dfb842a5gabor@google.com    break;
11078cd4ab8303620197cf24282ae8639060efbb326egabor@google.com  case ISD::ANY_EXTEND:
11088cd4ab8303620197cf24282ae8639060efbb326egabor@google.com    if (Operand.getValueType() == VT) return Operand;   // noop extension
1109d36ce84e66c7d3cee978fbeb52721c30dfb842a5gabor@google.com    assert(Operand.getValueType() < VT && "Invalid anyext node, dst < src!");
1110d36ce84e66c7d3cee978fbeb52721c30dfb842a5gabor@google.com    if (OpOpcode == ISD::ZERO_EXTEND || OpOpcode == ISD::SIGN_EXTEND)
11118cd4ab8303620197cf24282ae8639060efbb326egabor@google.com      // (ext (zext x)) -> (zext x)  and  (ext (sext x)) -> (sext x)
11128cd4ab8303620197cf24282ae8639060efbb326egabor@google.com      return getNode(OpOpcode, VT, Operand.Val->getOperand(0));
1113d36ce84e66c7d3cee978fbeb52721c30dfb842a5gabor@google.com    break;
1114d36ce84e66c7d3cee978fbeb52721c30dfb842a5gabor@google.com  case ISD::TRUNCATE:
11158cd4ab8303620197cf24282ae8639060efbb326egabor@google.com    if (Operand.getValueType() == VT) return Operand;   // noop truncate
11168cd4ab8303620197cf24282ae8639060efbb326egabor@google.com    assert(Operand.getValueType() > VT && "Invalid truncate node, src < dst!");
1117179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    if (OpOpcode == ISD::TRUNCATE)
1118179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      return getNode(ISD::TRUNCATE, VT, Operand.Val->getOperand(0));
1119179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    else if (OpOpcode == ISD::ZERO_EXTEND || OpOpcode == ISD::SIGN_EXTEND ||
1120179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org             OpOpcode == ISD::ANY_EXTEND) {
112108595b9e51ded54851b7664bd38affad63a67838dgrogan@chromium.org      // If the source is smaller than the dest, we still need an extend.
112208595b9e51ded54851b7664bd38affad63a67838dgrogan@chromium.org      if (Operand.Val->getOperand(0).getValueType() < VT)
1123a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org        return getNode(OpOpcode, VT, Operand.Val->getOperand(0));
112408595b9e51ded54851b7664bd38affad63a67838dgrogan@chromium.org      else if (Operand.Val->getOperand(0).getValueType() > VT)
1125a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org        return getNode(ISD::TRUNCATE, VT, Operand.Val->getOperand(0));
1126a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org      else
112708595b9e51ded54851b7664bd38affad63a67838dgrogan@chromium.org        return Operand.Val->getOperand(0);
112808595b9e51ded54851b7664bd38affad63a67838dgrogan@chromium.org    }
112908595b9e51ded54851b7664bd38affad63a67838dgrogan@chromium.org    break;
113008595b9e51ded54851b7664bd38affad63a67838dgrogan@chromium.org  case ISD::BIT_CONVERT:
113108595b9e51ded54851b7664bd38affad63a67838dgrogan@chromium.org    // Basic sanity checking.
113208595b9e51ded54851b7664bd38affad63a67838dgrogan@chromium.org    assert(MVT::getSizeInBits(VT) == MVT::getSizeInBits(Operand.getValueType())
113308595b9e51ded54851b7664bd38affad63a67838dgrogan@chromium.org           && "Cannot BIT_CONVERT between types of different sizes!");
113408595b9e51ded54851b7664bd38affad63a67838dgrogan@chromium.org    if (VT == Operand.getValueType()) return Operand;  // noop conversion.
113508595b9e51ded54851b7664bd38affad63a67838dgrogan@chromium.org    if (OpOpcode == ISD::BIT_CONVERT)  // bitconv(bitconv(x)) -> bitconv(x)
1136179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      return getNode(ISD::BIT_CONVERT, VT, Operand.getOperand(0));
1137179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    if (OpOpcode == ISD::UNDEF)
1138179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      return getNode(ISD::UNDEF, VT);
1139179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    break;
114095e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  case ISD::SCALAR_TO_VECTOR:
1141179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    assert(MVT::isVector(VT) && !MVT::isVector(Operand.getValueType()) &&
1142179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org           MVT::getVectorBaseType(VT) == Operand.getValueType() &&
1143179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org           "Illegal SCALAR_TO_VECTOR node!");
1144179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    break;
1145a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  case ISD::FNEG:
1146179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    if (OpOpcode == ISD::FSUB)   // -(X-Y) -> (Y-X)
1147179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      return getNode(ISD::FSUB, VT, Operand.Val->getOperand(1),
1148179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org                     Operand.Val->getOperand(0));
1149179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    if (OpOpcode == ISD::FNEG)  // --X -> X
1150179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      return Operand.Val->getOperand(0);
1151179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    break;
1152179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::FABS:
1153179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    if (OpOpcode == ISD::FNEG)  // abs(-X) -> abs(X)
1154179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      return getNode(ISD::FABS, VT, Operand.Val->getOperand(0));
1155179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    break;
1156179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
115713daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com
115813daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com  SDNode *N;
115913daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com  SDVTList VTs = getVTList(VT);
116013daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com  if (VT != MVT::Flag) { // Don't CSE flag producing nodes
116113daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com    FoldingSetNodeID ID;
1162394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com    AddNodeIDNode(ID, Opcode, VTs, Operand);
11631511be6edb54b6ade2bfad94256f76bc191e92ecdgrogan@chromium.org    void *IP = 0;
116413daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com    if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
116513daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com      return SDOperand(E, 0);
116613daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com    N = new SDNode(Opcode, Operand);
116713daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com    N->setValueTypes(VTs);
116813daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com    CSEMap.InsertNode(N, IP);
116913daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com  } else {
117013daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com    N = new SDNode(Opcode, Operand);
117113daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com    N->setValueTypes(VTs);
117213daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com  }
117313daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com  AllNodes.push_back(N);
11741511be6edb54b6ade2bfad94256f76bc191e92ecdgrogan@chromium.org  return SDOperand(N, 0);
117513daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com}
117613daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com
117713daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com
11781511be6edb54b6ade2bfad94256f76bc191e92ecdgrogan@chromium.org
11791511be6edb54b6ade2bfad94256f76bc191e92ecdgrogan@chromium.orgSDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
11801511be6edb54b6ade2bfad94256f76bc191e92ecdgrogan@chromium.org                                SDOperand N1, SDOperand N2) {
118113daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com#ifndef NDEBUG
118213daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com  switch (Opcode) {
118313daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com  case ISD::TokenFactor:
118413daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com    assert(VT == MVT::Other && N1.getValueType() == MVT::Other &&
1185394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com           N2.getValueType() == MVT::Other && "Invalid token factor!");
1186394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com    break;
1187394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com  case ISD::AND:
1188394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com  case ISD::OR:
1189394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com  case ISD::XOR:
1190394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com  case ISD::UDIV:
1191394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com  case ISD::UREM:
1192394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com  case ISD::MULHU:
1193394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com  case ISD::MULHS:
1194394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com    assert(MVT::isInteger(VT) && "This operator does not apply to FP types!");
1195179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    // fall through
119613daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com  case ISD::ADD:
1197394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com  case ISD::SUB:
1198394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com  case ISD::MUL:
1199179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::SDIV:
120013daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com  case ISD::SREM:
120113daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com    assert(MVT::isInteger(N1.getValueType()) && "Should use F* for FP ops");
120213daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com    // fall through.
120313daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com  case ISD::FADD:
120413daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com  case ISD::FSUB:
120513daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com  case ISD::FMUL:
120613daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com  case ISD::FDIV:
120713daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com  case ISD::FREM:
120813daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com    assert(N1.getValueType() == N2.getValueType() &&
120913daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com           N1.getValueType() == VT && "Binary operator types must match!");
121013daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com    break;
121113daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com  case ISD::FCOPYSIGN:   // N1 and result must match.  N1/N2 need not match.
121213daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com    assert(N1.getValueType() == VT &&
121313daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com           MVT::isFloatingPoint(N1.getValueType()) &&
121413daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com           MVT::isFloatingPoint(N2.getValueType()) &&
121513daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com           "Invalid FCOPYSIGN!");
121613daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com    break;
1217179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::SHL:
1218179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::SRA:
1219179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::SRL:
122013daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com  case ISD::ROTL:
122113daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com  case ISD::ROTR:
122213daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com    assert(VT == N1.getValueType() &&
122313daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com           "Shift operators return type must be the same as their first arg");
122413daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com    assert(MVT::isInteger(VT) && MVT::isInteger(N2.getValueType()) &&
122513daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com           VT != MVT::i1 && "Shifts only work on integers");
122613daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com    break;
122713daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com  case ISD::FP_ROUND_INREG: {
122813daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com    MVT::ValueType EVT = cast<VTSDNode>(N2)->getVT();
122913daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com    assert(VT == N1.getValueType() && "Not an inreg round!");
123013daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com    assert(MVT::isFloatingPoint(VT) && MVT::isFloatingPoint(EVT) &&
123113daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com           "Cannot FP_ROUND_INREG integer types");
123213daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com    assert(EVT <= VT && "Not rounding down!");
123313daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com    break;
123413daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com  }
123513daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com  case ISD::AssertSext:
123613daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com  case ISD::AssertZext:
123713daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com  case ISD::SIGN_EXTEND_INREG: {
123813daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com    MVT::ValueType EVT = cast<VTSDNode>(N2)->getVT();
123913daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com    assert(VT == N1.getValueType() && "Not an inreg extend!");
124013daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com    assert(MVT::isInteger(VT) && MVT::isInteger(EVT) &&
124113daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com           "Cannot *_EXTEND_INREG FP types");
124213daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com    assert(EVT <= VT && "Not extending!");
124313daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com  }
124413daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com
124513daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com  default: break;
124613daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com  }
124713daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com#endif
124813daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com
124913daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com  ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.Val);
125013daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com  ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2.Val);
125113daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com  if (N1C) {
125213daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com    if (Opcode == ISD::SIGN_EXTEND_INREG) {
125313daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com      int64_t Val = N1C->getValue();
125413daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com      unsigned FromBits = MVT::getSizeInBits(cast<VTSDNode>(N2)->getVT());
125513daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com      Val <<= 64-FromBits;
125613daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com      Val >>= 64-FromBits;
125713daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com      return getConstant(Val, VT);
125813daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com    }
125913daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com
126013daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com    if (N2C) {
126113daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com      uint64_t C1 = N1C->getValue(), C2 = N2C->getValue();
126213daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com      switch (Opcode) {
126313daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com      case ISD::ADD: return getConstant(C1 + C2, VT);
126413daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com      case ISD::SUB: return getConstant(C1 - C2, VT);
126513daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com      case ISD::MUL: return getConstant(C1 * C2, VT);
126613daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com      case ISD::UDIV:
126713daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com        if (C2) return getConstant(C1 / C2, VT);
126813daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com        break;
1269394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com      case ISD::UREM :
127013daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com        if (C2) return getConstant(C1 % C2, VT);
127195e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org        break;
127295e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org      case ISD::SDIV :
127313daa9f29c999ee40a257ee0775abee2c78a0ad9sanjay@google.com        if (C2) return getConstant(N1C->getSignExtended() /
1274a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org                                   N2C->getSignExtended(), VT);
127595e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org        break;
127695e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org      case ISD::SREM :
127795e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org        if (C2) return getConstant(N1C->getSignExtended() %
127895e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org                                   N2C->getSignExtended(), VT);
127995e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org        break;
128095e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org      case ISD::AND  : return getConstant(C1 & C2, VT);
1281a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org      case ISD::OR   : return getConstant(C1 | C2, VT);
1282a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org      case ISD::XOR  : return getConstant(C1 ^ C2, VT);
1283a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org      case ISD::SHL  : return getConstant(C1 << C2, VT);
1284a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org      case ISD::SRL  : return getConstant(C1 >> C2, VT);
1285a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org      case ISD::SRA  : return getConstant(N1C->getSignExtended() >>(int)C2, VT);
1286a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org      case ISD::ROTL :
1287a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org        return getConstant((C1 << C2) | (C1 >> (MVT::getSizeInBits(VT) - C2)),
1288a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org                           VT);
1289a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org      case ISD::ROTR :
1290a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org        return getConstant((C1 >> C2) | (C1 << (MVT::getSizeInBits(VT) - C2)),
1291a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org                           VT);
1292a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org      default: break;
1293a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org      }
129495e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org    } else {      // Cannonicalize constant to RHS if commutative
129595e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org      if (isCommutativeBinOp(Opcode)) {
129695e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org        std::swap(N1C, N2C);
129795e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org        std::swap(N1, N2);
129895e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org      }
129995e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org    }
130095e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  }
1301bd534e2d9ba35e6ada9afe854ad0dbcef3f27c4fdgrogan@chromium.org
13026635e49a8999ab5e411d5227146a3db17fac2944hans@chromium.org  ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N1.Val);
1303a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  ConstantFPSDNode *N2CFP = dyn_cast<ConstantFPSDNode>(N2.Val);
1304a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org  if (N1CFP) {
1305bd534e2d9ba35e6ada9afe854ad0dbcef3f27c4fdgrogan@chromium.org    if (N2CFP) {
13066635e49a8999ab5e411d5227146a3db17fac2944hans@chromium.org      double C1 = N1CFP->getValue(), C2 = N2CFP->getValue();
130795e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org      switch (Opcode) {
130895e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org      case ISD::FADD: return getConstantFP(C1 + C2, VT);
130995e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org      case ISD::FSUB: return getConstantFP(C1 - C2, VT);
131095e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org      case ISD::FMUL: return getConstantFP(C1 * C2, VT);
131195e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org      case ISD::FDIV:
131295e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org        if (C2) return getConstantFP(C1 / C2, VT);
131395e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org        break;
1314158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com      case ISD::FREM :
1315158f767acaed4c39cbb3ee8128fe896e155ec40csanjay@google.com        if (C2) return getConstantFP(fmod(C1, C2), VT);
131695e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org        break;
131795e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org      case ISD::FCOPYSIGN: {
131895e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org        union {
131995e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org          double   F;
132095e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org          uint64_t I;
13218cd4ab8303620197cf24282ae8639060efbb326egabor@google.com        } u1;
132295e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org        union {
132395e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org          double  F;
132495e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org          int64_t I;
132595e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org        } u2;
1326a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org        u1.F = C1;
132795e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org        u2.F = C2;
132895e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org        if (u2.I < 0)  // Sign bit of RHS set?
132995e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org          u1.I |= 1ULL << 63;      // Set the sign bit of the LHS.
133095e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org        else
133195e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org          u1.I &= (1ULL << 63)-1;  // Clear the sign bit of the LHS.
133295e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org        return getConstantFP(u1.F, VT);
133395e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org      }
133495e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org      default: break;
133595e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org      }
133695e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org    } else {      // Cannonicalize constant to RHS if commutative
1337179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      if (isCommutativeBinOp(Opcode)) {
1338179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org        std::swap(N1CFP, N2CFP);
1339179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org        std::swap(N1, N2);
1340179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      }
1341179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    }
1342179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
1343179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
1344179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // Canonicalize an UNDEF to the RHS, even over a constant.
1345179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if (N1.getOpcode() == ISD::UNDEF) {
1346179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    if (isCommutativeBinOp(Opcode)) {
1347fbe4e3af3f4e368e0779b6d75cd6005d67469aa2dgrogan@chromium.org      std::swap(N1, N2);
1348179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    } else {
1349179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      switch (Opcode) {
135095e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org      case ISD::FP_ROUND_INREG:
13511511be6edb54b6ade2bfad94256f76bc191e92ecdgrogan@chromium.org      case ISD::SIGN_EXTEND_INREG:
13521511be6edb54b6ade2bfad94256f76bc191e92ecdgrogan@chromium.org      case ISD::SUB:
135395e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org      case ISD::FSUB:
1354179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      case ISD::FDIV:
1355179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      case ISD::FREM:
135695e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org      case ISD::SRA:
135795e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org        return N1;     // fold op(undef, arg2) -> undef
135895e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org      case ISD::UDIV:
135995e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org      case ISD::SDIV:
136095e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org      case ISD::UREM:
136195e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org      case ISD::SREM:
136295e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org      case ISD::SRL:
136395e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org      case ISD::SHL:
136495e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org        return getConstant(0, VT);    // fold op(undef, arg2) -> 0
136595e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org      }
136695e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org    }
136795e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  }
136895e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org
136995e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  // Fold a bunch of operators when the RHS is undef.
137095e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  if (N2.getOpcode() == ISD::UNDEF) {
137195e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org    switch (Opcode) {
137295e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org    case ISD::ADD:
137395e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org    case ISD::SUB:
137495e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org    case ISD::FADD:
137595e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org    case ISD::FSUB:
137695e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org    case ISD::FMUL:
137795e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org    case ISD::FDIV:
137895e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org    case ISD::FREM:
137995e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org    case ISD::UDIV:
13805fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com    case ISD::SDIV:
13815fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com    case ISD::UREM:
13825fb21ed7ac9e91010d473ac77e132ae68f348d6agabor@google.com    case ISD::SREM:
1383179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    case ISD::XOR:
138495e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org      return N2;       // fold op(arg1, undef) -> undef
1385179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    case ISD::MUL:
1386179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    case ISD::AND:
1387179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    case ISD::SRL:
1388179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    case ISD::SHL:
1389179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      return getConstant(0, VT);  // fold op(arg1, undef) -> 0
1390179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    case ISD::OR:
1391179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      return getConstant(MVT::getIntVTBitMask(VT), VT);
1392179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    case ISD::SRA:
1393179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      return N1;
1394179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    }
1395179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
1396179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
1397179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // Fold operations.
1398179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  switch (Opcode) {
1399179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::AND:
1400179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    // (X & 0) -> 0.  This commonly occurs when legalizing i64 values, so it's
1401179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    // worth handling here.
1402179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    if (N2C && N2C->getValue() == 0)
1403179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      return N2;
1404179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    break;
1405179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::OR:
1406179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::XOR:
1407179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    // (X ^| 0) -> X.  This commonly occurs when legalizing i64 values, so it's
1408179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    // worth handling here.
1409179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    if (N2C && N2C->getValue() == 0)
1410179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      return N1;
1411179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    break;
1412179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::FP_ROUND_INREG:
1413179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    if (cast<VTSDNode>(N2)->getVT() == VT) return N1;  // Not actually rounding.
1414179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    break;
1415179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::SIGN_EXTEND_INREG: {
1416179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    MVT::ValueType EVT = cast<VTSDNode>(N2)->getVT();
1417179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    if (EVT == VT) return N1;  // Not actually extending
1418179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    break;
1419179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
1420179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::EXTRACT_ELEMENT:
1421179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    assert(N2C && (unsigned)N2C->getValue() < 2 && "Bad EXTRACT_ELEMENT!");
1422179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
1423179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    // EXTRACT_ELEMENT of BUILD_PAIR is often formed while legalize is expanding
1424179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    // 64-bit integers into 32-bit parts.  Instead of building the extract of
1425179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    // the BUILD_PAIR, only to have legalize rip it apart, just do it now.
1426179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    if (N1.getOpcode() == ISD::BUILD_PAIR)
1427179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      return N1.getOperand(N2C->getValue());
1428179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
1429179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    // EXTRACT_ELEMENT of a constant int is also very common.
1430179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N1)) {
1431179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      unsigned Shift = MVT::getSizeInBits(VT) * N2C->getValue();
1432179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      return getConstant(C->getValue() >> Shift, VT);
1433179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    }
1434179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    break;
1435179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
1436179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // FIXME: figure out how to safely handle things like
1437179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // int foo(int x) { return 1 << (x & 255); }
1438179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // int bar() { return foo(256); }
143995e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org#if 0
1440179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::SHL:
144195e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org  case ISD::SRL:
1442179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::SRA:
1443179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    if (N2.getOpcode() == ISD::SIGN_EXTEND_INREG &&
144495e21f32367748825123e382172ecbfd492ddb23dgrogan@chromium.org        cast<VTSDNode>(N2.getOperand(1))->getVT() != MVT::i1)
1445179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      return getNode(Opcode, VT, N1, N2.getOperand(0));
14468cd4ab8303620197cf24282ae8639060efbb326egabor@google.com    else if (N2.getOpcode() == ISD::AND)
1447179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      if (ConstantSDNode *AndRHS = dyn_cast<ConstantSDNode>(N2.getOperand(1))) {
1448394a4b425a6a8aca3244fc26ec77c101a11a632cgabor@google.com        // If the and is only masking out bits that cannot effect the shift,
1449179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org        // eliminate the and.
1450179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org        unsigned NumBits = MVT::getSizeInBits(VT);
1451179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org        if ((AndRHS->getValue() & (NumBits-1)) == NumBits-1)
1452a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org          return getNode(Opcode, VT, N1, N2.getOperand(0));
1453179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      }
1454179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    break;
1455179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#endif
1456179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
1457179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
1458179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // Memoize this node if possible.
1459179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  SDNode *N;
1460179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  SDVTList VTs = getVTList(VT);
1461179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  if (VT != MVT::Flag) {
1462179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    FoldingSetNodeID ID;
1463179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    AddNodeIDNode(ID, Opcode, VTs, N1, N2);
1464a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org    void *IP = 0;
1465a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org    if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
1466a5b4129c0a8c01158cde2244a5811f15b9d45ec0dgrogan@chromium.org      return SDOperand(E, 0);
1467179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    N = new SDNode(Opcode, N1, N2);
1468179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    N->setValueTypes(VTs);
1469179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    CSEMap.InsertNode(N, IP);
1470179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  } else {
1471179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    N = new SDNode(Opcode, N1, N2);
1472179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    N->setValueTypes(VTs);
1473179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
1474179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
1475179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  AllNodes.push_back(N);
1476179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  return SDOperand(N, 0);
1477917b88dd720b6e658c1fd7812bc61c605f315124gabor@google.com}
1478917b88dd720b6e658c1fd7812bc61c605f315124gabor@google.com
1479179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgSDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
1480179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org                                SDOperand N1, SDOperand N2, SDOperand N3) {
1481179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  // Perform various simplifications.
14821511be6edb54b6ade2bfad94256f76bc191e92ecdgrogan@chromium.org  ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.Val);
1483917b88dd720b6e658c1fd7812bc61c605f315124gabor@google.com  ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2.Val);
1484f168d0177b095ac7a608f6aafb9efc96976b6b3csanjay@google.com  switch (Opcode) {
1485179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::SETCC: {
1486179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    // Use FoldSetCC to simplify SETCC's.
1487179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    SDOperand Simp = FoldSetCC(VT, N1, N2, cast<CondCodeSDNode>(N3)->get());
1488179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    if (Simp.Val) return Simp;
1489179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    break;
1490179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  }
1491179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  case ISD::SELECT:
1492917b88dd720b6e658c1fd7812bc61c605f315124gabor@google.com    if (N1C)
1493179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      if (N1C->getValue())
1494179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org        return N2;             // select true, X, Y -> X
1495179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      else
1496179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org        return N3;             // select false, X, Y -> Y
1497179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
149845b9940be332834440bd5299419f396e38085ebehans@chromium.org    if (N2 == N3) return N2;   // select C, X, X -> X
1499    break;
1500  case ISD::BRCOND:
1501    if (N2C)
1502      if (N2C->getValue()) // Unconditional branch
1503        return getNode(ISD::BR, MVT::Other, N1, N3);
1504      else
1505        return N1;         // Never-taken branch
1506    break;
1507  case ISD::VECTOR_SHUFFLE:
1508    assert(VT == N1.getValueType() && VT == N2.getValueType() &&
1509           MVT::isVector(VT) && MVT::isVector(N3.getValueType()) &&
1510           N3.getOpcode() == ISD::BUILD_VECTOR &&
1511           MVT::getVectorNumElements(VT) == N3.getNumOperands() &&
1512           "Illegal VECTOR_SHUFFLE node!");
1513    break;
1514  }
1515
1516  // Memoize node if it doesn't produce a flag.
1517  SDNode *N;
1518  SDVTList VTs = getVTList(VT);
1519  if (VT != MVT::Flag) {
1520    FoldingSetNodeID ID;
1521    AddNodeIDNode(ID, Opcode, VTs, N1, N2, N3);
1522    void *IP = 0;
1523    if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
1524      return SDOperand(E, 0);
1525    N = new SDNode(Opcode, N1, N2, N3);
1526    N->setValueTypes(VTs);
1527    CSEMap.InsertNode(N, IP);
1528  } else {
1529    N = new SDNode(Opcode, N1, N2, N3);
1530    N->setValueTypes(VTs);
1531  }
1532  AllNodes.push_back(N);
1533  return SDOperand(N, 0);
1534}
1535
1536SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
1537                                SDOperand N1, SDOperand N2, SDOperand N3,
1538                                SDOperand N4) {
1539  SDOperand Ops[] = { N1, N2, N3, N4 };
1540  return getNode(Opcode, VT, Ops, 4);
1541}
1542
1543SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
1544                                SDOperand N1, SDOperand N2, SDOperand N3,
1545                                SDOperand N4, SDOperand N5) {
1546  SDOperand Ops[] = { N1, N2, N3, N4, N5 };
1547  return getNode(Opcode, VT, Ops, 5);
1548}
1549
1550SDOperand SelectionDAG::getLoad(MVT::ValueType VT,
1551                                SDOperand Chain, SDOperand Ptr,
1552                                const Value *SV, int SVOffset,
1553                                bool isVolatile) {
1554  // FIXME: Alignment == 1 for now.
1555  unsigned Alignment = 1;
1556  SDVTList VTs = getVTList(VT, MVT::Other);
1557  SDOperand Undef = getNode(ISD::UNDEF, Ptr.getValueType());
1558  FoldingSetNodeID ID;
1559  AddNodeIDNode(ID, ISD::LOAD, VTs, Chain, Ptr, Undef);
1560  ID.AddInteger(ISD::UNINDEXED);
1561  ID.AddInteger(ISD::NON_EXTLOAD);
1562  ID.AddInteger(VT);
1563  ID.AddPointer(SV);
1564  ID.AddInteger(SVOffset);
1565  ID.AddInteger(Alignment);
1566  ID.AddInteger(isVolatile);
1567  void *IP = 0;
1568  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
1569    return SDOperand(E, 0);
1570  SDNode *N = new LoadSDNode(Chain, Ptr, Undef, ISD::UNINDEXED,
1571                             ISD::NON_EXTLOAD, VT, SV, SVOffset, Alignment,
1572                             isVolatile);
1573  N->setValueTypes(VTs);
1574  CSEMap.InsertNode(N, IP);
1575  AllNodes.push_back(N);
1576  return SDOperand(N, 0);
1577}
1578
1579SDOperand SelectionDAG::getExtLoad(ISD::LoadExtType ExtType, MVT::ValueType VT,
1580                                   SDOperand Chain, SDOperand Ptr, const Value *SV,
1581                                   int SVOffset, MVT::ValueType EVT,
1582                                   bool isVolatile) {
1583  // If they are asking for an extending load from/to the same thing, return a
1584  // normal load.
1585  if (VT == EVT)
1586    ExtType = ISD::NON_EXTLOAD;
1587
1588  if (MVT::isVector(VT))
1589    assert(EVT == MVT::getVectorBaseType(VT) && "Invalid vector extload!");
1590  else
1591    assert(EVT < VT && "Should only be an extending load, not truncating!");
1592  assert((ExtType == ISD::EXTLOAD || MVT::isInteger(VT)) &&
1593         "Cannot sign/zero extend a FP/Vector load!");
1594  assert(MVT::isInteger(VT) == MVT::isInteger(EVT) &&
1595         "Cannot convert from FP to Int or Int -> FP!");
1596
1597  // FIXME: Alignment == 1 for now.
1598  unsigned Alignment = 1;
1599  SDVTList VTs = getVTList(VT, MVT::Other);
1600  SDOperand Undef = getNode(ISD::UNDEF, Ptr.getValueType());
1601  FoldingSetNodeID ID;
1602  AddNodeIDNode(ID, ISD::LOAD, VTs, Chain, Ptr, Undef);
1603  ID.AddInteger(ISD::UNINDEXED);
1604  ID.AddInteger(ExtType);
1605  ID.AddInteger(EVT);
1606  ID.AddPointer(SV);
1607  ID.AddInteger(SVOffset);
1608  ID.AddInteger(Alignment);
1609  ID.AddInteger(isVolatile);
1610  void *IP = 0;
1611  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
1612    return SDOperand(E, 0);
1613  SDNode *N = new LoadSDNode(Chain, Ptr, Undef, ISD::UNINDEXED, ExtType, EVT,
1614                             SV, SVOffset, Alignment, isVolatile);
1615  N->setValueTypes(VTs);
1616  CSEMap.InsertNode(N, IP);
1617  AllNodes.push_back(N);
1618  return SDOperand(N, 0);
1619}
1620
1621SDOperand
1622SelectionDAG::getIndexedLoad(SDOperand OrigLoad, SDOperand Base,
1623                             SDOperand Offset, ISD::MemIndexedMode AM) {
1624  LoadSDNode *LD = cast<LoadSDNode>(OrigLoad);
1625  assert(LD->getOffset().getOpcode() == ISD::UNDEF &&
1626         "Load is already a indexed load!");
1627  MVT::ValueType VT = OrigLoad.getValueType();
1628  SDVTList VTs = getVTList(VT, Base.getValueType(), MVT::Other);
1629  FoldingSetNodeID ID;
1630  AddNodeIDNode(ID, ISD::LOAD, VTs, LD->getChain(), Base, Offset);
1631  ID.AddInteger(AM);
1632  ID.AddInteger(LD->getExtensionType());
1633  ID.AddInteger(LD->getLoadedVT());
1634  ID.AddPointer(LD->getSrcValue());
1635  ID.AddInteger(LD->getSrcValueOffset());
1636  ID.AddInteger(LD->getAlignment());
1637  ID.AddInteger(LD->isVolatile());
1638  void *IP = 0;
1639  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
1640    return SDOperand(E, 0);
1641  SDNode *N = new LoadSDNode(LD->getChain(), Base, Offset, AM,
1642                             LD->getExtensionType(), LD->getLoadedVT(),
1643                             LD->getSrcValue(), LD->getSrcValueOffset(),
1644                             LD->getAlignment(), LD->isVolatile());
1645  N->setValueTypes(VTs);
1646  CSEMap.InsertNode(N, IP);
1647  AllNodes.push_back(N);
1648  return SDOperand(N, 0);
1649}
1650
1651SDOperand SelectionDAG::getVecLoad(unsigned Count, MVT::ValueType EVT,
1652                                   SDOperand Chain, SDOperand Ptr,
1653                                   SDOperand SV) {
1654  SDOperand Ops[] = { Chain, Ptr, SV, getConstant(Count, MVT::i32),
1655                      getValueType(EVT) };
1656  return getNode(ISD::VLOAD, getVTList(MVT::Vector, MVT::Other), Ops, 5);
1657}
1658
1659SDOperand SelectionDAG::getStore(SDOperand Chain, SDOperand Val,
1660                                 SDOperand Ptr, const Value *SV, int SVOffset,
1661                                 bool isVolatile) {
1662  MVT::ValueType VT = Val.getValueType();
1663
1664  // FIXME: Alignment == 1 for now.
1665  unsigned Alignment = 1;
1666  SDVTList VTs = getVTList(MVT::Other);
1667  SDOperand Undef = getNode(ISD::UNDEF, Ptr.getValueType());
1668  SDOperand Ops[] = { Chain, Val, Ptr, Undef };
1669  FoldingSetNodeID ID;
1670  AddNodeIDNode(ID, ISD::STORE, VTs, Ops, 4);
1671  ID.AddInteger(ISD::UNINDEXED);
1672  ID.AddInteger(false);
1673  ID.AddInteger(VT);
1674  ID.AddPointer(SV);
1675  ID.AddInteger(SVOffset);
1676  ID.AddInteger(Alignment);
1677  ID.AddInteger(isVolatile);
1678  void *IP = 0;
1679  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
1680    return SDOperand(E, 0);
1681  SDNode *N = new StoreSDNode(Chain, Val, Ptr, Undef, ISD::UNINDEXED, false,
1682                              VT, SV, SVOffset, Alignment, isVolatile);
1683  N->setValueTypes(VTs);
1684  CSEMap.InsertNode(N, IP);
1685  AllNodes.push_back(N);
1686  return SDOperand(N, 0);
1687}
1688
1689SDOperand SelectionDAG::getTruncStore(SDOperand Chain, SDOperand Val,
1690                                      SDOperand Ptr, const Value *SV,
1691                                      int SVOffset, MVT::ValueType SVT,
1692                                      bool isVolatile) {
1693  MVT::ValueType VT = Val.getValueType();
1694  bool isTrunc = VT != SVT;
1695
1696  assert(VT > SVT && "Not a truncation?");
1697  assert(MVT::isInteger(VT) == MVT::isInteger(SVT) &&
1698         "Can't do FP-INT conversion!");
1699
1700  // FIXME: Alignment == 1 for now.
1701  unsigned Alignment = 1;
1702  SDVTList VTs = getVTList(MVT::Other);
1703  SDOperand Undef = getNode(ISD::UNDEF, Ptr.getValueType());
1704  SDOperand Ops[] = { Chain, Val, Ptr, Undef };
1705  FoldingSetNodeID ID;
1706  AddNodeIDNode(ID, ISD::STORE, VTs, Ops, 4);
1707  ID.AddInteger(ISD::UNINDEXED);
1708  ID.AddInteger(isTrunc);
1709  ID.AddInteger(SVT);
1710  ID.AddPointer(SV);
1711  ID.AddInteger(SVOffset);
1712  ID.AddInteger(Alignment);
1713  ID.AddInteger(isVolatile);
1714  void *IP = 0;
1715  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
1716    return SDOperand(E, 0);
1717  SDNode *N = new StoreSDNode(Chain, Val, Ptr, Undef, ISD::UNINDEXED, isTrunc,
1718                              SVT, SV, SVOffset, Alignment, isVolatile);
1719  N->setValueTypes(VTs);
1720  CSEMap.InsertNode(N, IP);
1721  AllNodes.push_back(N);
1722  return SDOperand(N, 0);
1723}
1724
1725SDOperand
1726SelectionDAG::getIndexedStore(SDOperand OrigStore, SDOperand Base,
1727                              SDOperand Offset, ISD::MemIndexedMode AM) {
1728  StoreSDNode *ST = cast<StoreSDNode>(OrigStore);
1729  assert(ST->getOffset().getOpcode() == ISD::UNDEF &&
1730         "Store is already a indexed store!");
1731  SDVTList VTs = getVTList(Base.getValueType(), MVT::Other);
1732  SDOperand Ops[] = { ST->getChain(), ST->getValue(), Base, Offset };
1733  FoldingSetNodeID ID;
1734  AddNodeIDNode(ID, ISD::STORE, VTs, Ops, 4);
1735  ID.AddInteger(AM);
1736  ID.AddInteger(ST->isTruncatingStore());
1737  ID.AddInteger(ST->getStoredVT());
1738  ID.AddPointer(ST->getSrcValue());
1739  ID.AddInteger(ST->getSrcValueOffset());
1740  ID.AddInteger(ST->getAlignment());
1741  ID.AddInteger(ST->isVolatile());
1742  void *IP = 0;
1743  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
1744    return SDOperand(E, 0);
1745  SDNode *N = new StoreSDNode(ST->getChain(), ST->getValue(),
1746                              Base, Offset, AM,
1747                              ST->isTruncatingStore(), ST->getStoredVT(),
1748                              ST->getSrcValue(), ST->getSrcValueOffset(),
1749                              ST->getAlignment(), ST->isVolatile());
1750  N->setValueTypes(VTs);
1751  CSEMap.InsertNode(N, IP);
1752  AllNodes.push_back(N);
1753  return SDOperand(N, 0);
1754}
1755
1756SDOperand SelectionDAG::getVAArg(MVT::ValueType VT,
1757                                 SDOperand Chain, SDOperand Ptr,
1758                                 SDOperand SV) {
1759  SDOperand Ops[] = { Chain, Ptr, SV };
1760  return getNode(ISD::VAARG, getVTList(VT, MVT::Other), Ops, 3);
1761}
1762
1763SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
1764                                const SDOperand *Ops, unsigned NumOps) {
1765  switch (NumOps) {
1766  case 0: return getNode(Opcode, VT);
1767  case 1: return getNode(Opcode, VT, Ops[0]);
1768  case 2: return getNode(Opcode, VT, Ops[0], Ops[1]);
1769  case 3: return getNode(Opcode, VT, Ops[0], Ops[1], Ops[2]);
1770  default: break;
1771  }
1772
1773  switch (Opcode) {
1774  default: break;
1775  case ISD::SELECT_CC: {
1776    assert(NumOps == 5 && "SELECT_CC takes 5 operands!");
1777    assert(Ops[0].getValueType() == Ops[1].getValueType() &&
1778           "LHS and RHS of condition must have same type!");
1779    assert(Ops[2].getValueType() == Ops[3].getValueType() &&
1780           "True and False arms of SelectCC must have same type!");
1781    assert(Ops[2].getValueType() == VT &&
1782           "select_cc node must be of same type as true and false value!");
1783    break;
1784  }
1785  case ISD::BR_CC: {
1786    assert(NumOps == 5 && "BR_CC takes 5 operands!");
1787    assert(Ops[2].getValueType() == Ops[3].getValueType() &&
1788           "LHS/RHS of comparison should match types!");
1789    break;
1790  }
1791  }
1792
1793  // Memoize nodes.
1794  SDNode *N;
1795  SDVTList VTs = getVTList(VT);
1796  if (VT != MVT::Flag) {
1797    FoldingSetNodeID ID;
1798    AddNodeIDNode(ID, Opcode, VTs, Ops, NumOps);
1799    void *IP = 0;
1800    if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
1801      return SDOperand(E, 0);
1802    N = new SDNode(Opcode, Ops, NumOps);
1803    N->setValueTypes(VTs);
1804    CSEMap.InsertNode(N, IP);
1805  } else {
1806    N = new SDNode(Opcode, Ops, NumOps);
1807    N->setValueTypes(VTs);
1808  }
1809  AllNodes.push_back(N);
1810  return SDOperand(N, 0);
1811}
1812
1813SDOperand SelectionDAG::getNode(unsigned Opcode,
1814                                std::vector<MVT::ValueType> &ResultTys,
1815                                const SDOperand *Ops, unsigned NumOps) {
1816  return getNode(Opcode, getNodeValueTypes(ResultTys), ResultTys.size(),
1817                 Ops, NumOps);
1818}
1819
1820SDOperand SelectionDAG::getNode(unsigned Opcode,
1821                                const MVT::ValueType *VTs, unsigned NumVTs,
1822                                const SDOperand *Ops, unsigned NumOps) {
1823  if (NumVTs == 1)
1824    return getNode(Opcode, VTs[0], Ops, NumOps);
1825  return getNode(Opcode, makeVTList(VTs, NumVTs), Ops, NumOps);
1826}
1827
1828SDOperand SelectionDAG::getNode(unsigned Opcode, SDVTList VTList,
1829                                const SDOperand *Ops, unsigned NumOps) {
1830  if (VTList.NumVTs == 1)
1831    return getNode(Opcode, VTList.VTs[0], Ops, NumOps);
1832
1833  switch (Opcode) {
1834  // FIXME: figure out how to safely handle things like
1835  // int foo(int x) { return 1 << (x & 255); }
1836  // int bar() { return foo(256); }
1837#if 0
1838  case ISD::SRA_PARTS:
1839  case ISD::SRL_PARTS:
1840  case ISD::SHL_PARTS:
1841    if (N3.getOpcode() == ISD::SIGN_EXTEND_INREG &&
1842        cast<VTSDNode>(N3.getOperand(1))->getVT() != MVT::i1)
1843      return getNode(Opcode, VT, N1, N2, N3.getOperand(0));
1844    else if (N3.getOpcode() == ISD::AND)
1845      if (ConstantSDNode *AndRHS = dyn_cast<ConstantSDNode>(N3.getOperand(1))) {
1846        // If the and is only masking out bits that cannot effect the shift,
1847        // eliminate the and.
1848        unsigned NumBits = MVT::getSizeInBits(VT)*2;
1849        if ((AndRHS->getValue() & (NumBits-1)) == NumBits-1)
1850          return getNode(Opcode, VT, N1, N2, N3.getOperand(0));
1851      }
1852    break;
1853#endif
1854  }
1855
1856  // Memoize the node unless it returns a flag.
1857  SDNode *N;
1858  if (VTList.VTs[VTList.NumVTs-1] != MVT::Flag) {
1859    FoldingSetNodeID ID;
1860    AddNodeIDNode(ID, Opcode, VTList, Ops, NumOps);
1861    void *IP = 0;
1862    if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
1863      return SDOperand(E, 0);
1864    N = new SDNode(Opcode, Ops, NumOps);
1865    N->setValueTypes(VTList);
1866    CSEMap.InsertNode(N, IP);
1867  } else {
1868    N = new SDNode(Opcode, Ops, NumOps);
1869    N->setValueTypes(VTList);
1870  }
1871  AllNodes.push_back(N);
1872  return SDOperand(N, 0);
1873}
1874
1875SDVTList SelectionDAG::getVTList(MVT::ValueType VT) {
1876  return makeVTList(SDNode::getValueTypeList(VT), 1);
1877}
1878
1879SDVTList SelectionDAG::getVTList(MVT::ValueType VT1, MVT::ValueType VT2) {
1880  for (std::list<std::vector<MVT::ValueType> >::iterator I = VTList.begin(),
1881       E = VTList.end(); I != E; ++I) {
1882    if (I->size() == 2 && (*I)[0] == VT1 && (*I)[1] == VT2)
1883      return makeVTList(&(*I)[0], 2);
1884  }
1885  std::vector<MVT::ValueType> V;
1886  V.push_back(VT1);
1887  V.push_back(VT2);
1888  VTList.push_front(V);
1889  return makeVTList(&(*VTList.begin())[0], 2);
1890}
1891SDVTList SelectionDAG::getVTList(MVT::ValueType VT1, MVT::ValueType VT2,
1892                                 MVT::ValueType VT3) {
1893  for (std::list<std::vector<MVT::ValueType> >::iterator I = VTList.begin(),
1894       E = VTList.end(); I != E; ++I) {
1895    if (I->size() == 3 && (*I)[0] == VT1 && (*I)[1] == VT2 &&
1896        (*I)[2] == VT3)
1897      return makeVTList(&(*I)[0], 3);
1898  }
1899  std::vector<MVT::ValueType> V;
1900  V.push_back(VT1);
1901  V.push_back(VT2);
1902  V.push_back(VT3);
1903  VTList.push_front(V);
1904  return makeVTList(&(*VTList.begin())[0], 3);
1905}
1906
1907SDVTList SelectionDAG::getVTList(const MVT::ValueType *VTs, unsigned NumVTs) {
1908  switch (NumVTs) {
1909    case 0: assert(0 && "Cannot have nodes without results!");
1910    case 1: return makeVTList(SDNode::getValueTypeList(VTs[0]), 1);
1911    case 2: return getVTList(VTs[0], VTs[1]);
1912    case 3: return getVTList(VTs[0], VTs[1], VTs[2]);
1913    default: break;
1914  }
1915
1916  for (std::list<std::vector<MVT::ValueType> >::iterator I = VTList.begin(),
1917       E = VTList.end(); I != E; ++I) {
1918    if (I->size() != NumVTs || VTs[0] != (*I)[0] || VTs[1] != (*I)[1]) continue;
1919
1920    bool NoMatch = false;
1921    for (unsigned i = 2; i != NumVTs; ++i)
1922      if (VTs[i] != (*I)[i]) {
1923        NoMatch = true;
1924        break;
1925      }
1926    if (!NoMatch)
1927      return makeVTList(&*I->begin(), NumVTs);
1928  }
1929
1930  VTList.push_front(std::vector<MVT::ValueType>(VTs, VTs+NumVTs));
1931  return makeVTList(&*VTList.begin()->begin(), NumVTs);
1932}
1933
1934
1935/// UpdateNodeOperands - *Mutate* the specified node in-place to have the
1936/// specified operands.  If the resultant node already exists in the DAG,
1937/// this does not modify the specified node, instead it returns the node that
1938/// already exists.  If the resultant node does not exist in the DAG, the
1939/// input node is returned.  As a degenerate case, if you specify the same
1940/// input operands as the node already has, the input node is returned.
1941SDOperand SelectionDAG::
1942UpdateNodeOperands(SDOperand InN, SDOperand Op) {
1943  SDNode *N = InN.Val;
1944  assert(N->getNumOperands() == 1 && "Update with wrong number of operands");
1945
1946  // Check to see if there is no change.
1947  if (Op == N->getOperand(0)) return InN;
1948
1949  // See if the modified node already exists.
1950  void *InsertPos = 0;
1951  if (SDNode *Existing = FindModifiedNodeSlot(N, Op, InsertPos))
1952    return SDOperand(Existing, InN.ResNo);
1953
1954  // Nope it doesn't.  Remove the node from it's current place in the maps.
1955  if (InsertPos)
1956    RemoveNodeFromCSEMaps(N);
1957
1958  // Now we update the operands.
1959  N->OperandList[0].Val->removeUser(N);
1960  Op.Val->addUser(N);
1961  N->OperandList[0] = Op;
1962
1963  // If this gets put into a CSE map, add it.
1964  if (InsertPos) CSEMap.InsertNode(N, InsertPos);
1965  return InN;
1966}
1967
1968SDOperand SelectionDAG::
1969UpdateNodeOperands(SDOperand InN, SDOperand Op1, SDOperand Op2) {
1970  SDNode *N = InN.Val;
1971  assert(N->getNumOperands() == 2 && "Update with wrong number of operands");
1972
1973  // Check to see if there is no change.
1974  if (Op1 == N->getOperand(0) && Op2 == N->getOperand(1))
1975    return InN;   // No operands changed, just return the input node.
1976
1977  // See if the modified node already exists.
1978  void *InsertPos = 0;
1979  if (SDNode *Existing = FindModifiedNodeSlot(N, Op1, Op2, InsertPos))
1980    return SDOperand(Existing, InN.ResNo);
1981
1982  // Nope it doesn't.  Remove the node from it's current place in the maps.
1983  if (InsertPos)
1984    RemoveNodeFromCSEMaps(N);
1985
1986  // Now we update the operands.
1987  if (N->OperandList[0] != Op1) {
1988    N->OperandList[0].Val->removeUser(N);
1989    Op1.Val->addUser(N);
1990    N->OperandList[0] = Op1;
1991  }
1992  if (N->OperandList[1] != Op2) {
1993    N->OperandList[1].Val->removeUser(N);
1994    Op2.Val->addUser(N);
1995    N->OperandList[1] = Op2;
1996  }
1997
1998  // If this gets put into a CSE map, add it.
1999  if (InsertPos) CSEMap.InsertNode(N, InsertPos);
2000  return InN;
2001}
2002
2003SDOperand SelectionDAG::
2004UpdateNodeOperands(SDOperand N, SDOperand Op1, SDOperand Op2, SDOperand Op3) {
2005  SDOperand Ops[] = { Op1, Op2, Op3 };
2006  return UpdateNodeOperands(N, Ops, 3);
2007}
2008
2009SDOperand SelectionDAG::
2010UpdateNodeOperands(SDOperand N, SDOperand Op1, SDOperand Op2,
2011                   SDOperand Op3, SDOperand Op4) {
2012  SDOperand Ops[] = { Op1, Op2, Op3, Op4 };
2013  return UpdateNodeOperands(N, Ops, 4);
2014}
2015
2016SDOperand SelectionDAG::
2017UpdateNodeOperands(SDOperand N, SDOperand Op1, SDOperand Op2,
2018                   SDOperand Op3, SDOperand Op4, SDOperand Op5) {
2019  SDOperand Ops[] = { Op1, Op2, Op3, Op4, Op5 };
2020  return UpdateNodeOperands(N, Ops, 5);
2021}
2022
2023
2024SDOperand SelectionDAG::
2025UpdateNodeOperands(SDOperand InN, SDOperand *Ops, unsigned NumOps) {
2026  SDNode *N = InN.Val;
2027  assert(N->getNumOperands() == NumOps &&
2028         "Update with wrong number of operands");
2029
2030  // Check to see if there is no change.
2031  bool AnyChange = false;
2032  for (unsigned i = 0; i != NumOps; ++i) {
2033    if (Ops[i] != N->getOperand(i)) {
2034      AnyChange = true;
2035      break;
2036    }
2037  }
2038
2039  // No operands changed, just return the input node.
2040  if (!AnyChange) return InN;
2041
2042  // See if the modified node already exists.
2043  void *InsertPos = 0;
2044  if (SDNode *Existing = FindModifiedNodeSlot(N, Ops, NumOps, InsertPos))
2045    return SDOperand(Existing, InN.ResNo);
2046
2047  // Nope it doesn't.  Remove the node from it's current place in the maps.
2048  if (InsertPos)
2049    RemoveNodeFromCSEMaps(N);
2050
2051  // Now we update the operands.
2052  for (unsigned i = 0; i != NumOps; ++i) {
2053    if (N->OperandList[i] != Ops[i]) {
2054      N->OperandList[i].Val->removeUser(N);
2055      Ops[i].Val->addUser(N);
2056      N->OperandList[i] = Ops[i];
2057    }
2058  }
2059
2060  // If this gets put into a CSE map, add it.
2061  if (InsertPos) CSEMap.InsertNode(N, InsertPos);
2062  return InN;
2063}
2064
2065
2066
2067
2068/// SelectNodeTo - These are used for target selectors to *mutate* the
2069/// specified node to have the specified return type, Target opcode, and
2070/// operands.  Note that target opcodes are stored as
2071/// ISD::BUILTIN_OP_END+TargetOpcode in the node opcode field.
2072///
2073/// Note that SelectNodeTo returns the resultant node.  If there is already a
2074/// node of the specified opcode and operands, it returns that node instead of
2075/// the current one.
2076SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc,
2077                                   MVT::ValueType VT) {
2078  SDVTList VTs = getVTList(VT);
2079  FoldingSetNodeID ID;
2080  AddNodeIDNode(ID, ISD::BUILTIN_OP_END+TargetOpc, VTs);
2081  void *IP = 0;
2082  if (SDNode *ON = CSEMap.FindNodeOrInsertPos(ID, IP))
2083    return ON;
2084
2085  RemoveNodeFromCSEMaps(N);
2086
2087  N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc);
2088  N->setValueTypes(VTs);
2089
2090  CSEMap.InsertNode(N, IP);
2091  return N;
2092}
2093
2094SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc,
2095                                   MVT::ValueType VT, SDOperand Op1) {
2096  // If an identical node already exists, use it.
2097  SDVTList VTs = getVTList(VT);
2098  FoldingSetNodeID ID;
2099  AddNodeIDNode(ID, ISD::BUILTIN_OP_END+TargetOpc, VTs, Op1);
2100  void *IP = 0;
2101  if (SDNode *ON = CSEMap.FindNodeOrInsertPos(ID, IP))
2102    return ON;
2103
2104  RemoveNodeFromCSEMaps(N);
2105  N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc);
2106  N->setValueTypes(VTs);
2107  N->setOperands(Op1);
2108  CSEMap.InsertNode(N, IP);
2109  return N;
2110}
2111
2112SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc,
2113                                   MVT::ValueType VT, SDOperand Op1,
2114                                   SDOperand Op2) {
2115  // If an identical node already exists, use it.
2116  SDVTList VTs = getVTList(VT);
2117  FoldingSetNodeID ID;
2118  AddNodeIDNode(ID, ISD::BUILTIN_OP_END+TargetOpc, VTs,  Op1, Op2);
2119  void *IP = 0;
2120  if (SDNode *ON = CSEMap.FindNodeOrInsertPos(ID, IP))
2121    return ON;
2122
2123  RemoveNodeFromCSEMaps(N);
2124  N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc);
2125  N->setValueTypes(VTs);
2126  N->setOperands(Op1, Op2);
2127
2128  CSEMap.InsertNode(N, IP);   // Memoize the new node.
2129  return N;
2130}
2131
2132SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc,
2133                                   MVT::ValueType VT, SDOperand Op1,
2134                                   SDOperand Op2, SDOperand Op3) {
2135  // If an identical node already exists, use it.
2136  SDVTList VTs = getVTList(VT);
2137  FoldingSetNodeID ID;
2138  AddNodeIDNode(ID, ISD::BUILTIN_OP_END+TargetOpc, VTs,  Op1, Op2, Op3);
2139  void *IP = 0;
2140  if (SDNode *ON = CSEMap.FindNodeOrInsertPos(ID, IP))
2141    return ON;
2142
2143  RemoveNodeFromCSEMaps(N);
2144  N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc);
2145  N->setValueTypes(VTs);
2146  N->setOperands(Op1, Op2, Op3);
2147
2148  CSEMap.InsertNode(N, IP);   // Memoize the new node.
2149  return N;
2150}
2151
2152SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc,
2153                                   MVT::ValueType VT, const SDOperand *Ops,
2154                                   unsigned NumOps) {
2155  // If an identical node already exists, use it.
2156  SDVTList VTs = getVTList(VT);
2157  FoldingSetNodeID ID;
2158  AddNodeIDNode(ID, ISD::BUILTIN_OP_END+TargetOpc, VTs, Ops, NumOps);
2159  void *IP = 0;
2160  if (SDNode *ON = CSEMap.FindNodeOrInsertPos(ID, IP))
2161    return ON;
2162
2163  RemoveNodeFromCSEMaps(N);
2164  N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc);
2165  N->setValueTypes(VTs);
2166  N->setOperands(Ops, NumOps);
2167
2168  CSEMap.InsertNode(N, IP);   // Memoize the new node.
2169  return N;
2170}
2171
2172SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc,
2173                                   MVT::ValueType VT1, MVT::ValueType VT2,
2174                                   SDOperand Op1, SDOperand Op2) {
2175  SDVTList VTs = getVTList(VT1, VT2);
2176  FoldingSetNodeID ID;
2177  AddNodeIDNode(ID, ISD::BUILTIN_OP_END+TargetOpc, VTs, Op1, Op2);
2178  void *IP = 0;
2179  if (SDNode *ON = CSEMap.FindNodeOrInsertPos(ID, IP))
2180    return ON;
2181
2182  RemoveNodeFromCSEMaps(N);
2183  N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc);
2184  N->setValueTypes(VTs);
2185  N->setOperands(Op1, Op2);
2186
2187  CSEMap.InsertNode(N, IP);   // Memoize the new node.
2188  return N;
2189}
2190
2191SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc,
2192                                   MVT::ValueType VT1, MVT::ValueType VT2,
2193                                   SDOperand Op1, SDOperand Op2,
2194                                   SDOperand Op3) {
2195  // If an identical node already exists, use it.
2196  SDVTList VTs = getVTList(VT1, VT2);
2197  FoldingSetNodeID ID;
2198  AddNodeIDNode(ID, ISD::BUILTIN_OP_END+TargetOpc, VTs, Op1, Op2, Op3);
2199  void *IP = 0;
2200  if (SDNode *ON = CSEMap.FindNodeOrInsertPos(ID, IP))
2201    return ON;
2202
2203  RemoveNodeFromCSEMaps(N);
2204  N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc);
2205  N->setValueTypes(VTs);
2206  N->setOperands(Op1, Op2, Op3);
2207
2208  CSEMap.InsertNode(N, IP);   // Memoize the new node.
2209  return N;
2210}
2211
2212
2213/// getTargetNode - These are used for target selectors to create a new node
2214/// with specified return type(s), target opcode, and operands.
2215///
2216/// Note that getTargetNode returns the resultant node.  If there is already a
2217/// node of the specified opcode and operands, it returns that node instead of
2218/// the current one.
2219SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT::ValueType VT) {
2220  return getNode(ISD::BUILTIN_OP_END+Opcode, VT).Val;
2221}
2222SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT::ValueType VT,
2223                                    SDOperand Op1) {
2224  return getNode(ISD::BUILTIN_OP_END+Opcode, VT, Op1).Val;
2225}
2226SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT::ValueType VT,
2227                                    SDOperand Op1, SDOperand Op2) {
2228  return getNode(ISD::BUILTIN_OP_END+Opcode, VT, Op1, Op2).Val;
2229}
2230SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT::ValueType VT,
2231                                    SDOperand Op1, SDOperand Op2, SDOperand Op3) {
2232  return getNode(ISD::BUILTIN_OP_END+Opcode, VT, Op1, Op2, Op3).Val;
2233}
2234SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT::ValueType VT,
2235                                    const SDOperand *Ops, unsigned NumOps) {
2236  return getNode(ISD::BUILTIN_OP_END+Opcode, VT, Ops, NumOps).Val;
2237}
2238SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT::ValueType VT1,
2239                                    MVT::ValueType VT2, SDOperand Op1) {
2240  const MVT::ValueType *VTs = getNodeValueTypes(VT1, VT2);
2241  return getNode(ISD::BUILTIN_OP_END+Opcode, VTs, 2, &Op1, 1).Val;
2242}
2243SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT::ValueType VT1,
2244                                    MVT::ValueType VT2, SDOperand Op1,
2245                                    SDOperand Op2) {
2246  const MVT::ValueType *VTs = getNodeValueTypes(VT1, VT2);
2247  SDOperand Ops[] = { Op1, Op2 };
2248  return getNode(ISD::BUILTIN_OP_END+Opcode, VTs, 2, Ops, 2).Val;
2249}
2250SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT::ValueType VT1,
2251                                    MVT::ValueType VT2, SDOperand Op1,
2252                                    SDOperand Op2, SDOperand Op3) {
2253  const MVT::ValueType *VTs = getNodeValueTypes(VT1, VT2);
2254  SDOperand Ops[] = { Op1, Op2, Op3 };
2255  return getNode(ISD::BUILTIN_OP_END+Opcode, VTs, 2, Ops, 3).Val;
2256}
2257SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT::ValueType VT1,
2258                                    MVT::ValueType VT2,
2259                                    const SDOperand *Ops, unsigned NumOps) {
2260  const MVT::ValueType *VTs = getNodeValueTypes(VT1, VT2);
2261  return getNode(ISD::BUILTIN_OP_END+Opcode, VTs, 2, Ops, NumOps).Val;
2262}
2263SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT::ValueType VT1,
2264                                    MVT::ValueType VT2, MVT::ValueType VT3,
2265                                    SDOperand Op1, SDOperand Op2) {
2266  const MVT::ValueType *VTs = getNodeValueTypes(VT1, VT2, VT3);
2267  SDOperand Ops[] = { Op1, Op2 };
2268  return getNode(ISD::BUILTIN_OP_END+Opcode, VTs, 3, Ops, 2).Val;
2269}
2270SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT::ValueType VT1,
2271                                    MVT::ValueType VT2, MVT::ValueType VT3,
2272                                    const SDOperand *Ops, unsigned NumOps) {
2273  const MVT::ValueType *VTs = getNodeValueTypes(VT1, VT2, VT3);
2274  return getNode(ISD::BUILTIN_OP_END+Opcode, VTs, 3, Ops, NumOps).Val;
2275}
2276
2277/// ReplaceAllUsesWith - Modify anything using 'From' to use 'To' instead.
2278/// This can cause recursive merging of nodes in the DAG.
2279///
2280/// This version assumes From/To have a single result value.
2281///
2282void SelectionDAG::ReplaceAllUsesWith(SDOperand FromN, SDOperand ToN,
2283                                      std::vector<SDNode*> *Deleted) {
2284  SDNode *From = FromN.Val, *To = ToN.Val;
2285  assert(From->getNumValues() == 1 && To->getNumValues() == 1 &&
2286         "Cannot replace with this method!");
2287  assert(From != To && "Cannot replace uses of with self");
2288
2289  while (!From->use_empty()) {
2290    // Process users until they are all gone.
2291    SDNode *U = *From->use_begin();
2292
2293    // This node is about to morph, remove its old self from the CSE maps.
2294    RemoveNodeFromCSEMaps(U);
2295
2296    for (SDOperand *I = U->OperandList, *E = U->OperandList+U->NumOperands;
2297         I != E; ++I)
2298      if (I->Val == From) {
2299        From->removeUser(U);
2300        I->Val = To;
2301        To->addUser(U);
2302      }
2303
2304    // Now that we have modified U, add it back to the CSE maps.  If it already
2305    // exists there, recursively merge the results together.
2306    if (SDNode *Existing = AddNonLeafNodeToCSEMaps(U)) {
2307      ReplaceAllUsesWith(U, Existing, Deleted);
2308      // U is now dead.
2309      if (Deleted) Deleted->push_back(U);
2310      DeleteNodeNotInCSEMaps(U);
2311    }
2312  }
2313}
2314
2315/// ReplaceAllUsesWith - Modify anything using 'From' to use 'To' instead.
2316/// This can cause recursive merging of nodes in the DAG.
2317///
2318/// This version assumes From/To have matching types and numbers of result
2319/// values.
2320///
2321void SelectionDAG::ReplaceAllUsesWith(SDNode *From, SDNode *To,
2322                                      std::vector<SDNode*> *Deleted) {
2323  assert(From != To && "Cannot replace uses of with self");
2324  assert(From->getNumValues() == To->getNumValues() &&
2325         "Cannot use this version of ReplaceAllUsesWith!");
2326  if (From->getNumValues() == 1) {  // If possible, use the faster version.
2327    ReplaceAllUsesWith(SDOperand(From, 0), SDOperand(To, 0), Deleted);
2328    return;
2329  }
2330
2331  while (!From->use_empty()) {
2332    // Process users until they are all gone.
2333    SDNode *U = *From->use_begin();
2334
2335    // This node is about to morph, remove its old self from the CSE maps.
2336    RemoveNodeFromCSEMaps(U);
2337
2338    for (SDOperand *I = U->OperandList, *E = U->OperandList+U->NumOperands;
2339         I != E; ++I)
2340      if (I->Val == From) {
2341        From->removeUser(U);
2342        I->Val = To;
2343        To->addUser(U);
2344      }
2345
2346    // Now that we have modified U, add it back to the CSE maps.  If it already
2347    // exists there, recursively merge the results together.
2348    if (SDNode *Existing = AddNonLeafNodeToCSEMaps(U)) {
2349      ReplaceAllUsesWith(U, Existing, Deleted);
2350      // U is now dead.
2351      if (Deleted) Deleted->push_back(U);
2352      DeleteNodeNotInCSEMaps(U);
2353    }
2354  }
2355}
2356
2357/// ReplaceAllUsesWith - Modify anything using 'From' to use 'To' instead.
2358/// This can cause recursive merging of nodes in the DAG.
2359///
2360/// This version can replace From with any result values.  To must match the
2361/// number and types of values returned by From.
2362void SelectionDAG::ReplaceAllUsesWith(SDNode *From,
2363                                      const SDOperand *To,
2364                                      std::vector<SDNode*> *Deleted) {
2365  if (From->getNumValues() == 1 && To[0].Val->getNumValues() == 1) {
2366    // Degenerate case handled above.
2367    ReplaceAllUsesWith(SDOperand(From, 0), To[0], Deleted);
2368    return;
2369  }
2370
2371  while (!From->use_empty()) {
2372    // Process users until they are all gone.
2373    SDNode *U = *From->use_begin();
2374
2375    // This node is about to morph, remove its old self from the CSE maps.
2376    RemoveNodeFromCSEMaps(U);
2377
2378    for (SDOperand *I = U->OperandList, *E = U->OperandList+U->NumOperands;
2379         I != E; ++I)
2380      if (I->Val == From) {
2381        const SDOperand &ToOp = To[I->ResNo];
2382        From->removeUser(U);
2383        *I = ToOp;
2384        ToOp.Val->addUser(U);
2385      }
2386
2387    // Now that we have modified U, add it back to the CSE maps.  If it already
2388    // exists there, recursively merge the results together.
2389    if (SDNode *Existing = AddNonLeafNodeToCSEMaps(U)) {
2390      ReplaceAllUsesWith(U, Existing, Deleted);
2391      // U is now dead.
2392      if (Deleted) Deleted->push_back(U);
2393      DeleteNodeNotInCSEMaps(U);
2394    }
2395  }
2396}
2397
2398/// ReplaceAllUsesOfValueWith - Replace any uses of From with To, leaving
2399/// uses of other values produced by From.Val alone.  The Deleted vector is
2400/// handled the same was as for ReplaceAllUsesWith.
2401void SelectionDAG::ReplaceAllUsesOfValueWith(SDOperand From, SDOperand To,
2402                                             std::vector<SDNode*> &Deleted) {
2403  assert(From != To && "Cannot replace a value with itself");
2404  // Handle the simple, trivial, case efficiently.
2405  if (From.Val->getNumValues() == 1 && To.Val->getNumValues() == 1) {
2406    ReplaceAllUsesWith(From, To, &Deleted);
2407    return;
2408  }
2409
2410  // Get all of the users in a nice, deterministically ordered, uniqued set.
2411  SetVector<SDNode*> Users(From.Val->use_begin(), From.Val->use_end());
2412
2413  while (!Users.empty()) {
2414    // We know that this user uses some value of From.  If it is the right
2415    // value, update it.
2416    SDNode *User = Users.back();
2417    Users.pop_back();
2418
2419    for (SDOperand *Op = User->OperandList,
2420         *E = User->OperandList+User->NumOperands; Op != E; ++Op) {
2421      if (*Op == From) {
2422        // Okay, we know this user needs to be updated.  Remove its old self
2423        // from the CSE maps.
2424        RemoveNodeFromCSEMaps(User);
2425
2426        // Update all operands that match "From".
2427        for (; Op != E; ++Op) {
2428          if (*Op == From) {
2429            From.Val->removeUser(User);
2430            *Op = To;
2431            To.Val->addUser(User);
2432          }
2433        }
2434
2435        // Now that we have modified User, add it back to the CSE maps.  If it
2436        // already exists there, recursively merge the results together.
2437        if (SDNode *Existing = AddNonLeafNodeToCSEMaps(User)) {
2438          unsigned NumDeleted = Deleted.size();
2439          ReplaceAllUsesWith(User, Existing, &Deleted);
2440
2441          // User is now dead.
2442          Deleted.push_back(User);
2443          DeleteNodeNotInCSEMaps(User);
2444
2445          // We have to be careful here, because ReplaceAllUsesWith could have
2446          // deleted a user of From, which means there may be dangling pointers
2447          // in the "Users" setvector.  Scan over the deleted node pointers and
2448          // remove them from the setvector.
2449          for (unsigned i = NumDeleted, e = Deleted.size(); i != e; ++i)
2450            Users.remove(Deleted[i]);
2451        }
2452        break;   // Exit the operand scanning loop.
2453      }
2454    }
2455  }
2456}
2457
2458
2459/// AssignNodeIds - Assign a unique node id for each node in the DAG based on
2460/// their allnodes order. It returns the maximum id.
2461unsigned SelectionDAG::AssignNodeIds() {
2462  unsigned Id = 0;
2463  for (allnodes_iterator I = allnodes_begin(), E = allnodes_end(); I != E; ++I){
2464    SDNode *N = I;
2465    N->setNodeId(Id++);
2466  }
2467  return Id;
2468}
2469
2470/// AssignTopologicalOrder - Assign a unique node id for each node in the DAG
2471/// based on their topological order. It returns the maximum id and a vector
2472/// of the SDNodes* in assigned order by reference.
2473unsigned SelectionDAG::AssignTopologicalOrder(std::vector<SDNode*> &TopOrder) {
2474  unsigned DAGSize = AllNodes.size();
2475  std::vector<unsigned> InDegree(DAGSize);
2476  std::vector<SDNode*> Sources;
2477
2478  // Use a two pass approach to avoid using a std::map which is slow.
2479  unsigned Id = 0;
2480  for (allnodes_iterator I = allnodes_begin(),E = allnodes_end(); I != E; ++I){
2481    SDNode *N = I;
2482    N->setNodeId(Id++);
2483    unsigned Degree = N->use_size();
2484    InDegree[N->getNodeId()] = Degree;
2485    if (Degree == 0)
2486      Sources.push_back(N);
2487  }
2488
2489  TopOrder.clear();
2490  while (!Sources.empty()) {
2491    SDNode *N = Sources.back();
2492    Sources.pop_back();
2493    TopOrder.push_back(N);
2494    for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) {
2495      SDNode *P = I->Val;
2496      unsigned Degree = --InDegree[P->getNodeId()];
2497      if (Degree == 0)
2498        Sources.push_back(P);
2499    }
2500  }
2501
2502  // Second pass, assign the actual topological order as node ids.
2503  Id = 0;
2504  for (std::vector<SDNode*>::iterator TI = TopOrder.begin(),TE = TopOrder.end();
2505       TI != TE; ++TI)
2506    (*TI)->setNodeId(Id++);
2507
2508  return Id;
2509}
2510
2511
2512
2513//===----------------------------------------------------------------------===//
2514//                              SDNode Class
2515//===----------------------------------------------------------------------===//
2516
2517// Out-of-line virtual method to give class a home.
2518void SDNode::ANCHOR() {
2519}
2520
2521/// Profile - Gather unique data for the node.
2522///
2523void SDNode::Profile(FoldingSetNodeID &ID) {
2524  AddNodeIDNode(ID, this);
2525}
2526
2527/// getValueTypeList - Return a pointer to the specified value type.
2528///
2529MVT::ValueType *SDNode::getValueTypeList(MVT::ValueType VT) {
2530  static MVT::ValueType VTs[MVT::LAST_VALUETYPE];
2531  VTs[VT] = VT;
2532  return &VTs[VT];
2533}
2534
2535/// hasNUsesOfValue - Return true if there are exactly NUSES uses of the
2536/// indicated value.  This method ignores uses of other values defined by this
2537/// operation.
2538bool SDNode::hasNUsesOfValue(unsigned NUses, unsigned Value) const {
2539  assert(Value < getNumValues() && "Bad value!");
2540
2541  // If there is only one value, this is easy.
2542  if (getNumValues() == 1)
2543    return use_size() == NUses;
2544  if (Uses.size() < NUses) return false;
2545
2546  SDOperand TheValue(const_cast<SDNode *>(this), Value);
2547
2548  std::set<SDNode*> UsersHandled;
2549
2550  for (SDNode::use_iterator UI = Uses.begin(), E = Uses.end(); UI != E; ++UI) {
2551    SDNode *User = *UI;
2552    if (User->getNumOperands() == 1 ||
2553        UsersHandled.insert(User).second)     // First time we've seen this?
2554      for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i)
2555        if (User->getOperand(i) == TheValue) {
2556          if (NUses == 0)
2557            return false;   // too many uses
2558          --NUses;
2559        }
2560  }
2561
2562  // Found exactly the right number of uses?
2563  return NUses == 0;
2564}
2565
2566
2567/// isOnlyUse - Return true if this node is the only use of N.
2568///
2569bool SDNode::isOnlyUse(SDNode *N) const {
2570  bool Seen = false;
2571  for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) {
2572    SDNode *User = *I;
2573    if (User == this)
2574      Seen = true;
2575    else
2576      return false;
2577  }
2578
2579  return Seen;
2580}
2581
2582/// isOperand - Return true if this node is an operand of N.
2583///
2584bool SDOperand::isOperand(SDNode *N) const {
2585  for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
2586    if (*this == N->getOperand(i))
2587      return true;
2588  return false;
2589}
2590
2591bool SDNode::isOperand(SDNode *N) const {
2592  for (unsigned i = 0, e = N->NumOperands; i != e; ++i)
2593    if (this == N->OperandList[i].Val)
2594      return true;
2595  return false;
2596}
2597
2598static void findPredecessor(SDNode *N, const SDNode *P, bool &found,
2599                            std::set<SDNode *> &Visited) {
2600  if (found || !Visited.insert(N).second)
2601    return;
2602
2603  for (unsigned i = 0, e = N->getNumOperands(); !found && i != e; ++i) {
2604    SDNode *Op = N->getOperand(i).Val;
2605    if (Op == P) {
2606      found = true;
2607      return;
2608    }
2609    findPredecessor(Op, P, found, Visited);
2610  }
2611}
2612
2613/// isPredecessor - Return true if this node is a predecessor of N. This node
2614/// is either an operand of N or it can be reached by recursively traversing
2615/// up the operands.
2616/// NOTE: this is an expensive method. Use it carefully.
2617bool SDNode::isPredecessor(SDNode *N) const {
2618  std::set<SDNode *> Visited;
2619  bool found = false;
2620  findPredecessor(N, this, found, Visited);
2621  return found;
2622}
2623
2624uint64_t SDNode::getConstantOperandVal(unsigned Num) const {
2625  assert(Num < NumOperands && "Invalid child # of SDNode!");
2626  return cast<ConstantSDNode>(OperandList[Num])->getValue();
2627}
2628
2629const char *SDNode::getOperationName(const SelectionDAG *G) const {
2630  switch (getOpcode()) {
2631  default:
2632    if (getOpcode() < ISD::BUILTIN_OP_END)
2633      return "<<Unknown DAG Node>>";
2634    else {
2635      if (G) {
2636        if (const TargetInstrInfo *TII = G->getTarget().getInstrInfo())
2637          if (getOpcode()-ISD::BUILTIN_OP_END < TII->getNumOpcodes())
2638            return TII->getName(getOpcode()-ISD::BUILTIN_OP_END);
2639
2640        TargetLowering &TLI = G->getTargetLoweringInfo();
2641        const char *Name =
2642          TLI.getTargetNodeName(getOpcode());
2643        if (Name) return Name;
2644      }
2645
2646      return "<<Unknown Target Node>>";
2647    }
2648
2649  case ISD::PCMARKER:      return "PCMarker";
2650  case ISD::READCYCLECOUNTER: return "ReadCycleCounter";
2651  case ISD::SRCVALUE:      return "SrcValue";
2652  case ISD::EntryToken:    return "EntryToken";
2653  case ISD::TokenFactor:   return "TokenFactor";
2654  case ISD::AssertSext:    return "AssertSext";
2655  case ISD::AssertZext:    return "AssertZext";
2656
2657  case ISD::STRING:        return "String";
2658  case ISD::BasicBlock:    return "BasicBlock";
2659  case ISD::VALUETYPE:     return "ValueType";
2660  case ISD::Register:      return "Register";
2661
2662  case ISD::Constant:      return "Constant";
2663  case ISD::ConstantFP:    return "ConstantFP";
2664  case ISD::GlobalAddress: return "GlobalAddress";
2665  case ISD::FrameIndex:    return "FrameIndex";
2666  case ISD::JumpTable:     return "JumpTable";
2667  case ISD::GLOBAL_OFFSET_TABLE: return "GLOBAL_OFFSET_TABLE";
2668  case ISD::ConstantPool:  return "ConstantPool";
2669  case ISD::ExternalSymbol: return "ExternalSymbol";
2670  case ISD::INTRINSIC_WO_CHAIN: {
2671    unsigned IID = cast<ConstantSDNode>(getOperand(0))->getValue();
2672    return Intrinsic::getName((Intrinsic::ID)IID);
2673  }
2674  case ISD::INTRINSIC_VOID:
2675  case ISD::INTRINSIC_W_CHAIN: {
2676    unsigned IID = cast<ConstantSDNode>(getOperand(1))->getValue();
2677    return Intrinsic::getName((Intrinsic::ID)IID);
2678  }
2679
2680  case ISD::BUILD_VECTOR:   return "BUILD_VECTOR";
2681  case ISD::TargetConstant: return "TargetConstant";
2682  case ISD::TargetConstantFP:return "TargetConstantFP";
2683  case ISD::TargetGlobalAddress: return "TargetGlobalAddress";
2684  case ISD::TargetFrameIndex: return "TargetFrameIndex";
2685  case ISD::TargetJumpTable:  return "TargetJumpTable";
2686  case ISD::TargetConstantPool:  return "TargetConstantPool";
2687  case ISD::TargetExternalSymbol: return "TargetExternalSymbol";
2688
2689  case ISD::CopyToReg:     return "CopyToReg";
2690  case ISD::CopyFromReg:   return "CopyFromReg";
2691  case ISD::UNDEF:         return "undef";
2692  case ISD::MERGE_VALUES:  return "mergevalues";
2693  case ISD::INLINEASM:     return "inlineasm";
2694  case ISD::HANDLENODE:    return "handlenode";
2695  case ISD::FORMAL_ARGUMENTS: return "formal_arguments";
2696  case ISD::CALL:          return "call";
2697
2698  // Unary operators
2699  case ISD::FABS:   return "fabs";
2700  case ISD::FNEG:   return "fneg";
2701  case ISD::FSQRT:  return "fsqrt";
2702  case ISD::FSIN:   return "fsin";
2703  case ISD::FCOS:   return "fcos";
2704  case ISD::FPOWI:  return "fpowi";
2705
2706  // Binary operators
2707  case ISD::ADD:    return "add";
2708  case ISD::SUB:    return "sub";
2709  case ISD::MUL:    return "mul";
2710  case ISD::MULHU:  return "mulhu";
2711  case ISD::MULHS:  return "mulhs";
2712  case ISD::SDIV:   return "sdiv";
2713  case ISD::UDIV:   return "udiv";
2714  case ISD::SREM:   return "srem";
2715  case ISD::UREM:   return "urem";
2716  case ISD::AND:    return "and";
2717  case ISD::OR:     return "or";
2718  case ISD::XOR:    return "xor";
2719  case ISD::SHL:    return "shl";
2720  case ISD::SRA:    return "sra";
2721  case ISD::SRL:    return "srl";
2722  case ISD::ROTL:   return "rotl";
2723  case ISD::ROTR:   return "rotr";
2724  case ISD::FADD:   return "fadd";
2725  case ISD::FSUB:   return "fsub";
2726  case ISD::FMUL:   return "fmul";
2727  case ISD::FDIV:   return "fdiv";
2728  case ISD::FREM:   return "frem";
2729  case ISD::FCOPYSIGN: return "fcopysign";
2730  case ISD::VADD:   return "vadd";
2731  case ISD::VSUB:   return "vsub";
2732  case ISD::VMUL:   return "vmul";
2733  case ISD::VSDIV:  return "vsdiv";
2734  case ISD::VUDIV:  return "vudiv";
2735  case ISD::VAND:   return "vand";
2736  case ISD::VOR:    return "vor";
2737  case ISD::VXOR:   return "vxor";
2738
2739  case ISD::SETCC:       return "setcc";
2740  case ISD::SELECT:      return "select";
2741  case ISD::SELECT_CC:   return "select_cc";
2742  case ISD::VSELECT:     return "vselect";
2743  case ISD::INSERT_VECTOR_ELT:   return "insert_vector_elt";
2744  case ISD::VINSERT_VECTOR_ELT:  return "vinsert_vector_elt";
2745  case ISD::EXTRACT_VECTOR_ELT:  return "extract_vector_elt";
2746  case ISD::VEXTRACT_VECTOR_ELT: return "vextract_vector_elt";
2747  case ISD::SCALAR_TO_VECTOR:    return "scalar_to_vector";
2748  case ISD::VBUILD_VECTOR:       return "vbuild_vector";
2749  case ISD::VECTOR_SHUFFLE:      return "vector_shuffle";
2750  case ISD::VVECTOR_SHUFFLE:     return "vvector_shuffle";
2751  case ISD::VBIT_CONVERT:        return "vbit_convert";
2752  case ISD::ADDC:        return "addc";
2753  case ISD::ADDE:        return "adde";
2754  case ISD::SUBC:        return "subc";
2755  case ISD::SUBE:        return "sube";
2756  case ISD::SHL_PARTS:   return "shl_parts";
2757  case ISD::SRA_PARTS:   return "sra_parts";
2758  case ISD::SRL_PARTS:   return "srl_parts";
2759
2760  // Conversion operators.
2761  case ISD::SIGN_EXTEND: return "sign_extend";
2762  case ISD::ZERO_EXTEND: return "zero_extend";
2763  case ISD::ANY_EXTEND:  return "any_extend";
2764  case ISD::SIGN_EXTEND_INREG: return "sign_extend_inreg";
2765  case ISD::TRUNCATE:    return "truncate";
2766  case ISD::FP_ROUND:    return "fp_round";
2767  case ISD::FP_ROUND_INREG: return "fp_round_inreg";
2768  case ISD::FP_EXTEND:   return "fp_extend";
2769
2770  case ISD::SINT_TO_FP:  return "sint_to_fp";
2771  case ISD::UINT_TO_FP:  return "uint_to_fp";
2772  case ISD::FP_TO_SINT:  return "fp_to_sint";
2773  case ISD::FP_TO_UINT:  return "fp_to_uint";
2774  case ISD::BIT_CONVERT: return "bit_convert";
2775
2776    // Control flow instructions
2777  case ISD::BR:      return "br";
2778  case ISD::BRIND:   return "brind";
2779  case ISD::BR_JT:   return "br_jt";
2780  case ISD::BRCOND:  return "brcond";
2781  case ISD::BR_CC:   return "br_cc";
2782  case ISD::RET:     return "ret";
2783  case ISD::CALLSEQ_START:  return "callseq_start";
2784  case ISD::CALLSEQ_END:    return "callseq_end";
2785
2786    // Other operators
2787  case ISD::LOAD:               return "load";
2788  case ISD::STORE:              return "store";
2789  case ISD::VLOAD:              return "vload";
2790  case ISD::VAARG:              return "vaarg";
2791  case ISD::VACOPY:             return "vacopy";
2792  case ISD::VAEND:              return "vaend";
2793  case ISD::VASTART:            return "vastart";
2794  case ISD::DYNAMIC_STACKALLOC: return "dynamic_stackalloc";
2795  case ISD::EXTRACT_ELEMENT:    return "extract_element";
2796  case ISD::BUILD_PAIR:         return "build_pair";
2797  case ISD::STACKSAVE:          return "stacksave";
2798  case ISD::STACKRESTORE:       return "stackrestore";
2799
2800  // Block memory operations.
2801  case ISD::MEMSET:  return "memset";
2802  case ISD::MEMCPY:  return "memcpy";
2803  case ISD::MEMMOVE: return "memmove";
2804
2805  // Bit manipulation
2806  case ISD::BSWAP:   return "bswap";
2807  case ISD::CTPOP:   return "ctpop";
2808  case ISD::CTTZ:    return "cttz";
2809  case ISD::CTLZ:    return "ctlz";
2810
2811  // Debug info
2812  case ISD::LOCATION: return "location";
2813  case ISD::DEBUG_LOC: return "debug_loc";
2814  case ISD::DEBUG_LABEL: return "debug_label";
2815
2816  case ISD::CONDCODE:
2817    switch (cast<CondCodeSDNode>(this)->get()) {
2818    default: assert(0 && "Unknown setcc condition!");
2819    case ISD::SETOEQ:  return "setoeq";
2820    case ISD::SETOGT:  return "setogt";
2821    case ISD::SETOGE:  return "setoge";
2822    case ISD::SETOLT:  return "setolt";
2823    case ISD::SETOLE:  return "setole";
2824    case ISD::SETONE:  return "setone";
2825
2826    case ISD::SETO:    return "seto";
2827    case ISD::SETUO:   return "setuo";
2828    case ISD::SETUEQ:  return "setue";
2829    case ISD::SETUGT:  return "setugt";
2830    case ISD::SETUGE:  return "setuge";
2831    case ISD::SETULT:  return "setult";
2832    case ISD::SETULE:  return "setule";
2833    case ISD::SETUNE:  return "setune";
2834
2835    case ISD::SETEQ:   return "seteq";
2836    case ISD::SETGT:   return "setgt";
2837    case ISD::SETGE:   return "setge";
2838    case ISD::SETLT:   return "setlt";
2839    case ISD::SETLE:   return "setle";
2840    case ISD::SETNE:   return "setne";
2841    }
2842  }
2843}
2844
2845const char *SDNode::getIndexedModeName(ISD::MemIndexedMode AM) {
2846  switch (AM) {
2847  default:
2848    return "";
2849  case ISD::PRE_INC:
2850    return "<pre-inc>";
2851  case ISD::PRE_DEC:
2852    return "<pre-dec>";
2853  case ISD::POST_INC:
2854    return "<post-inc>";
2855  case ISD::POST_DEC:
2856    return "<post-dec>";
2857  }
2858}
2859
2860void SDNode::dump() const { dump(0); }
2861void SDNode::dump(const SelectionDAG *G) const {
2862  cerr << (void*)this << ": ";
2863
2864  for (unsigned i = 0, e = getNumValues(); i != e; ++i) {
2865    if (i) cerr << ",";
2866    if (getValueType(i) == MVT::Other)
2867      cerr << "ch";
2868    else
2869      cerr << MVT::getValueTypeString(getValueType(i));
2870  }
2871  cerr << " = " << getOperationName(G);
2872
2873  cerr << " ";
2874  for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
2875    if (i) cerr << ", ";
2876    cerr << (void*)getOperand(i).Val;
2877    if (unsigned RN = getOperand(i).ResNo)
2878      cerr << ":" << RN;
2879  }
2880
2881  if (const ConstantSDNode *CSDN = dyn_cast<ConstantSDNode>(this)) {
2882    cerr << "<" << CSDN->getValue() << ">";
2883  } else if (const ConstantFPSDNode *CSDN = dyn_cast<ConstantFPSDNode>(this)) {
2884    cerr << "<" << CSDN->getValue() << ">";
2885  } else if (const GlobalAddressSDNode *GADN =
2886             dyn_cast<GlobalAddressSDNode>(this)) {
2887    int offset = GADN->getOffset();
2888    cerr << "<";
2889    WriteAsOperand(*cerr.stream(), GADN->getGlobal()) << ">";
2890    if (offset > 0)
2891      cerr << " + " << offset;
2892    else
2893      cerr << " " << offset;
2894  } else if (const FrameIndexSDNode *FIDN = dyn_cast<FrameIndexSDNode>(this)) {
2895    cerr << "<" << FIDN->getIndex() << ">";
2896  } else if (const JumpTableSDNode *JTDN = dyn_cast<JumpTableSDNode>(this)) {
2897    cerr << "<" << JTDN->getIndex() << ">";
2898  } else if (const ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(this)){
2899    int offset = CP->getOffset();
2900    if (CP->isMachineConstantPoolEntry())
2901      cerr << "<" << *CP->getMachineCPVal() << ">";
2902    else
2903      cerr << "<" << *CP->getConstVal() << ">";
2904    if (offset > 0)
2905      cerr << " + " << offset;
2906    else
2907      cerr << " " << offset;
2908  } else if (const BasicBlockSDNode *BBDN = dyn_cast<BasicBlockSDNode>(this)) {
2909    cerr << "<";
2910    const Value *LBB = (const Value*)BBDN->getBasicBlock()->getBasicBlock();
2911    if (LBB)
2912      cerr << LBB->getName() << " ";
2913    cerr << (const void*)BBDN->getBasicBlock() << ">";
2914  } else if (const RegisterSDNode *R = dyn_cast<RegisterSDNode>(this)) {
2915    if (G && R->getReg() && MRegisterInfo::isPhysicalRegister(R->getReg())) {
2916      cerr << " " <<G->getTarget().getRegisterInfo()->getName(R->getReg());
2917    } else {
2918      cerr << " #" << R->getReg();
2919    }
2920  } else if (const ExternalSymbolSDNode *ES =
2921             dyn_cast<ExternalSymbolSDNode>(this)) {
2922    cerr << "'" << ES->getSymbol() << "'";
2923  } else if (const SrcValueSDNode *M = dyn_cast<SrcValueSDNode>(this)) {
2924    if (M->getValue())
2925      cerr << "<" << M->getValue() << ":" << M->getOffset() << ">";
2926    else
2927      cerr << "<null:" << M->getOffset() << ">";
2928  } else if (const VTSDNode *N = dyn_cast<VTSDNode>(this)) {
2929    cerr << ":" << getValueTypeString(N->getVT());
2930  } else if (const LoadSDNode *LD = dyn_cast<LoadSDNode>(this)) {
2931    bool doExt = true;
2932    switch (LD->getExtensionType()) {
2933    default: doExt = false; break;
2934    case ISD::EXTLOAD:
2935      cerr << " <anyext ";
2936      break;
2937    case ISD::SEXTLOAD:
2938      cerr << " <sext ";
2939      break;
2940    case ISD::ZEXTLOAD:
2941      cerr << " <zext ";
2942      break;
2943    }
2944    if (doExt)
2945      cerr << MVT::getValueTypeString(LD->getLoadedVT()) << ">";
2946
2947    const char *AM = getIndexedModeName(LD->getAddressingMode());
2948    if (AM != "")
2949      cerr << " " << AM;
2950  } else if (const StoreSDNode *ST = dyn_cast<StoreSDNode>(this)) {
2951    if (ST->isTruncatingStore())
2952      cerr << " <trunc "
2953           << MVT::getValueTypeString(ST->getStoredVT()) << ">";
2954
2955    const char *AM = getIndexedModeName(ST->getAddressingMode());
2956    if (AM != "")
2957      cerr << " " << AM;
2958  }
2959}
2960
2961static void DumpNodes(const SDNode *N, unsigned indent, const SelectionDAG *G) {
2962  for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
2963    if (N->getOperand(i).Val->hasOneUse())
2964      DumpNodes(N->getOperand(i).Val, indent+2, G);
2965    else
2966      cerr << "\n" << std::string(indent+2, ' ')
2967           << (void*)N->getOperand(i).Val << ": <multiple use>";
2968
2969
2970  cerr << "\n" << std::string(indent, ' ');
2971  N->dump(G);
2972}
2973
2974void SelectionDAG::dump() const {
2975  cerr << "SelectionDAG has " << AllNodes.size() << " nodes:";
2976  std::vector<const SDNode*> Nodes;
2977  for (allnodes_const_iterator I = allnodes_begin(), E = allnodes_end();
2978       I != E; ++I)
2979    Nodes.push_back(I);
2980
2981  std::sort(Nodes.begin(), Nodes.end());
2982
2983  for (unsigned i = 0, e = Nodes.size(); i != e; ++i) {
2984    if (!Nodes[i]->hasOneUse() && Nodes[i] != getRoot().Val)
2985      DumpNodes(Nodes[i], 2, this);
2986  }
2987
2988  if (getRoot().Val) DumpNodes(getRoot().Val, 2, this);
2989
2990  cerr << "\n\n";
2991}
2992
2993const Type *ConstantPoolSDNode::getType() const {
2994  if (isMachineConstantPoolEntry())
2995    return Val.MachineCPVal->getType();
2996  return Val.ConstVal->getType();
2997}
2998