| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 1 | //===-- SelectionDAG.cpp - Implement the SelectionDAG data structures -----===// | 
| Misha Brukman | edf128a | 2005-04-21 22:36:52 +0000 | [diff] [blame] | 2 | // | 
| John Criswell | b576c94 | 2003-10-20 19:43:21 +0000 | [diff] [blame] | 3 | //                     The LLVM Compiler Infrastructure | 
 | 4 | // | 
 | 5 | // This file was developed by the LLVM research group and is distributed under | 
 | 6 | // the University of Illinois Open Source License. See LICENSE.TXT for details. | 
| Misha Brukman | edf128a | 2005-04-21 22:36:52 +0000 | [diff] [blame] | 7 | // | 
| John Criswell | b576c94 | 2003-10-20 19:43:21 +0000 | [diff] [blame] | 8 | //===----------------------------------------------------------------------===// | 
| Chris Lattner | 78ec311 | 2003-08-11 14:57:33 +0000 | [diff] [blame] | 9 | // | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 10 | // This implements the SelectionDAG class. | 
| Chris Lattner | 78ec311 | 2003-08-11 14:57:33 +0000 | [diff] [blame] | 11 | // | 
 | 12 | //===----------------------------------------------------------------------===// | 
 | 13 |  | 
 | 14 | #include "llvm/CodeGen/SelectionDAG.h" | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 15 | #include "llvm/Constants.h" | 
 | 16 | #include "llvm/GlobalValue.h" | 
 | 17 | #include "llvm/Assembly/Writer.h" | 
 | 18 | #include "llvm/CodeGen/MachineBasicBlock.h" | 
| Chris Lattner | 0561b3f | 2005-08-02 19:26:06 +0000 | [diff] [blame] | 19 | #include "llvm/Support/MathExtras.h" | 
| Chris Lattner | fa164b6 | 2005-08-19 21:34:13 +0000 | [diff] [blame] | 20 | #include "llvm/Target/MRegisterInfo.h" | 
| Chris Lattner | b48da39 | 2005-01-23 04:39:44 +0000 | [diff] [blame] | 21 | #include "llvm/Target/TargetLowering.h" | 
| Chris Lattner | f3e133a | 2005-08-16 18:33:07 +0000 | [diff] [blame] | 22 | #include "llvm/Target/TargetInstrInfo.h" | 
 | 23 | #include "llvm/Target/TargetMachine.h" | 
| Evan Cheng | 115c036 | 2005-12-19 23:11:49 +0000 | [diff] [blame] | 24 | #include "llvm/ADT/StringExtras.h" | 
| Reid Spencer | 954da37 | 2004-07-04 12:19:56 +0000 | [diff] [blame] | 25 | #include <iostream> | 
| Chris Lattner | 0e12e6e | 2005-01-07 21:09:16 +0000 | [diff] [blame] | 26 | #include <set> | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 27 | #include <cmath> | 
| Jeff Cohen | fd161e9 | 2005-01-09 20:41:56 +0000 | [diff] [blame] | 28 | #include <algorithm> | 
| Chris Lattner | e25738c | 2004-06-02 04:28:06 +0000 | [diff] [blame] | 29 | using namespace llvm; | 
| Brian Gaeke | d0fde30 | 2003-11-11 22:41:34 +0000 | [diff] [blame] | 30 |  | 
| Chris Lattner | 5cdcc58 | 2005-01-09 20:52:51 +0000 | [diff] [blame] | 31 | static bool isCommutativeBinOp(unsigned Opcode) { | 
 | 32 |   switch (Opcode) { | 
 | 33 |   case ISD::ADD: | 
 | 34 |   case ISD::MUL: | 
| Nate Begeman | 1b5db7a | 2006-01-16 08:07:10 +0000 | [diff] [blame] | 35 |   case ISD::MULHU: | 
 | 36 |   case ISD::MULHS: | 
| Chris Lattner | 01b3d73 | 2005-09-28 22:28:18 +0000 | [diff] [blame] | 37 |   case ISD::FADD: | 
 | 38 |   case ISD::FMUL: | 
| Chris Lattner | 5cdcc58 | 2005-01-09 20:52:51 +0000 | [diff] [blame] | 39 |   case ISD::AND: | 
 | 40 |   case ISD::OR: | 
 | 41 |   case ISD::XOR: return true; | 
 | 42 |   default: return false; // FIXME: Need commutative info for user ops! | 
 | 43 |   } | 
 | 44 | } | 
 | 45 |  | 
 | 46 | static bool isAssociativeBinOp(unsigned Opcode) { | 
 | 47 |   switch (Opcode) { | 
 | 48 |   case ISD::ADD: | 
 | 49 |   case ISD::MUL: | 
 | 50 |   case ISD::AND: | 
 | 51 |   case ISD::OR: | 
 | 52 |   case ISD::XOR: return true; | 
 | 53 |   default: return false; // FIXME: Need associative info for user ops! | 
 | 54 |   } | 
 | 55 | } | 
 | 56 |  | 
| Chris Lattner | 5cdcc58 | 2005-01-09 20:52:51 +0000 | [diff] [blame] | 57 | // isInvertibleForFree - Return true if there is no cost to emitting the logical | 
 | 58 | // inverse of this node. | 
 | 59 | static bool isInvertibleForFree(SDOperand N) { | 
 | 60 |   if (isa<ConstantSDNode>(N.Val)) return true; | 
| Chris Lattner | 7cf7e3f | 2005-08-09 20:20:18 +0000 | [diff] [blame] | 61 |   if (N.Val->getOpcode() == ISD::SETCC && N.Val->hasOneUse()) | 
| Chris Lattner | 5cdcc58 | 2005-01-09 20:52:51 +0000 | [diff] [blame] | 62 |     return true; | 
| Misha Brukman | edf128a | 2005-04-21 22:36:52 +0000 | [diff] [blame] | 63 |   return false; | 
| Chris Lattner | 5cdcc58 | 2005-01-09 20:52:51 +0000 | [diff] [blame] | 64 | } | 
 | 65 |  | 
| Jim Laskey | 58b968b | 2005-08-17 20:08:02 +0000 | [diff] [blame] | 66 | //===----------------------------------------------------------------------===// | 
 | 67 | //                              ConstantFPSDNode Class | 
 | 68 | //===----------------------------------------------------------------------===// | 
 | 69 |  | 
 | 70 | /// isExactlyValue - We don't rely on operator== working on double values, as | 
 | 71 | /// it returns true for things that are clearly not equal, like -0.0 and 0.0. | 
 | 72 | /// As such, this method can be used to do an exact bit-for-bit comparison of | 
 | 73 | /// two floating point values. | 
 | 74 | bool ConstantFPSDNode::isExactlyValue(double V) const { | 
 | 75 |   return DoubleToBits(V) == DoubleToBits(Value); | 
 | 76 | } | 
 | 77 |  | 
 | 78 | //===----------------------------------------------------------------------===// | 
 | 79 | //                              ISD Class | 
 | 80 | //===----------------------------------------------------------------------===// | 
| Chris Lattner | 5cdcc58 | 2005-01-09 20:52:51 +0000 | [diff] [blame] | 81 |  | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 82 | /// getSetCCSwappedOperands - Return the operation corresponding to (Y op X) | 
 | 83 | /// when given the operation for (X op Y). | 
 | 84 | ISD::CondCode ISD::getSetCCSwappedOperands(ISD::CondCode Operation) { | 
 | 85 |   // To perform this operation, we just need to swap the L and G bits of the | 
 | 86 |   // operation. | 
 | 87 |   unsigned OldL = (Operation >> 2) & 1; | 
 | 88 |   unsigned OldG = (Operation >> 1) & 1; | 
 | 89 |   return ISD::CondCode((Operation & ~6) |  // Keep the N, U, E bits | 
 | 90 |                        (OldL << 1) |       // New G bit | 
 | 91 |                        (OldG << 2));        // New L bit. | 
 | 92 | } | 
 | 93 |  | 
 | 94 | /// getSetCCInverse - Return the operation corresponding to !(X op Y), where | 
 | 95 | /// 'op' is a valid SetCC operation. | 
 | 96 | ISD::CondCode ISD::getSetCCInverse(ISD::CondCode Op, bool isInteger) { | 
 | 97 |   unsigned Operation = Op; | 
 | 98 |   if (isInteger) | 
 | 99 |     Operation ^= 7;   // Flip L, G, E bits, but not U. | 
 | 100 |   else | 
 | 101 |     Operation ^= 15;  // Flip all of the condition bits. | 
 | 102 |   if (Operation > ISD::SETTRUE2) | 
 | 103 |     Operation &= ~8;     // Don't let N and U bits get set. | 
 | 104 |   return ISD::CondCode(Operation); | 
 | 105 | } | 
 | 106 |  | 
 | 107 |  | 
 | 108 | /// isSignedOp - For an integer comparison, return 1 if the comparison is a | 
 | 109 | /// signed operation and 2 if the result is an unsigned comparison.  Return zero | 
 | 110 | /// if the operation does not depend on the sign of the input (setne and seteq). | 
 | 111 | static int isSignedOp(ISD::CondCode Opcode) { | 
 | 112 |   switch (Opcode) { | 
 | 113 |   default: assert(0 && "Illegal integer setcc operation!"); | 
 | 114 |   case ISD::SETEQ: | 
 | 115 |   case ISD::SETNE: return 0; | 
 | 116 |   case ISD::SETLT: | 
 | 117 |   case ISD::SETLE: | 
 | 118 |   case ISD::SETGT: | 
 | 119 |   case ISD::SETGE: return 1; | 
 | 120 |   case ISD::SETULT: | 
 | 121 |   case ISD::SETULE: | 
 | 122 |   case ISD::SETUGT: | 
 | 123 |   case ISD::SETUGE: return 2; | 
 | 124 |   } | 
 | 125 | } | 
 | 126 |  | 
 | 127 | /// getSetCCOrOperation - Return the result of a logical OR between different | 
 | 128 | /// comparisons of identical values: ((X op1 Y) | (X op2 Y)).  This function | 
 | 129 | /// returns SETCC_INVALID if it is not possible to represent the resultant | 
 | 130 | /// comparison. | 
 | 131 | ISD::CondCode ISD::getSetCCOrOperation(ISD::CondCode Op1, ISD::CondCode Op2, | 
 | 132 |                                        bool isInteger) { | 
 | 133 |   if (isInteger && (isSignedOp(Op1) | isSignedOp(Op2)) == 3) | 
 | 134 |     // Cannot fold a signed integer setcc with an unsigned integer setcc. | 
 | 135 |     return ISD::SETCC_INVALID; | 
| Misha Brukman | edf128a | 2005-04-21 22:36:52 +0000 | [diff] [blame] | 136 |  | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 137 |   unsigned Op = Op1 | Op2;  // Combine all of the condition bits. | 
| Misha Brukman | edf128a | 2005-04-21 22:36:52 +0000 | [diff] [blame] | 138 |  | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 139 |   // If the N and U bits get set then the resultant comparison DOES suddenly | 
 | 140 |   // care about orderedness, and is true when ordered. | 
 | 141 |   if (Op > ISD::SETTRUE2) | 
 | 142 |     Op &= ~16;     // Clear the N bit. | 
 | 143 |   return ISD::CondCode(Op); | 
 | 144 | } | 
 | 145 |  | 
 | 146 | /// getSetCCAndOperation - Return the result of a logical AND between different | 
 | 147 | /// comparisons of identical values: ((X op1 Y) & (X op2 Y)).  This | 
 | 148 | /// function returns zero if it is not possible to represent the resultant | 
 | 149 | /// comparison. | 
 | 150 | ISD::CondCode ISD::getSetCCAndOperation(ISD::CondCode Op1, ISD::CondCode Op2, | 
 | 151 |                                         bool isInteger) { | 
 | 152 |   if (isInteger && (isSignedOp(Op1) | isSignedOp(Op2)) == 3) | 
 | 153 |     // Cannot fold a signed setcc with an unsigned setcc. | 
| Misha Brukman | edf128a | 2005-04-21 22:36:52 +0000 | [diff] [blame] | 154 |     return ISD::SETCC_INVALID; | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 155 |  | 
 | 156 |   // Combine all of the condition bits. | 
 | 157 |   return ISD::CondCode(Op1 & Op2); | 
 | 158 | } | 
 | 159 |  | 
| Chris Lattner | b48da39 | 2005-01-23 04:39:44 +0000 | [diff] [blame] | 160 | const TargetMachine &SelectionDAG::getTarget() const { | 
 | 161 |   return TLI.getTargetMachine(); | 
 | 162 | } | 
 | 163 |  | 
| Jim Laskey | 58b968b | 2005-08-17 20:08:02 +0000 | [diff] [blame] | 164 | //===----------------------------------------------------------------------===// | 
 | 165 | //                              SelectionDAG Class | 
 | 166 | //===----------------------------------------------------------------------===// | 
| Chris Lattner | b48da39 | 2005-01-23 04:39:44 +0000 | [diff] [blame] | 167 |  | 
| Chris Lattner | 0e12e6e | 2005-01-07 21:09:16 +0000 | [diff] [blame] | 168 | /// RemoveDeadNodes - This method deletes all unreachable nodes in the | 
 | 169 | /// SelectionDAG, including nodes (like loads) that have uses of their token | 
 | 170 | /// chain but no other uses and no side effect.  If a node is passed in as an | 
 | 171 | /// argument, it is used as the seed for node deletion. | 
 | 172 | void SelectionDAG::RemoveDeadNodes(SDNode *N) { | 
| Chris Lattner | 0e12e6e | 2005-01-07 21:09:16 +0000 | [diff] [blame] | 173 |   // Create a dummy node (which is not added to allnodes), that adds a reference | 
 | 174 |   // to the root node, preventing it from being deleted. | 
| Chris Lattner | 9503859 | 2005-10-05 06:35:28 +0000 | [diff] [blame] | 175 |   HandleSDNode Dummy(getRoot()); | 
| Chris Lattner | 0e12e6e | 2005-01-07 21:09:16 +0000 | [diff] [blame] | 176 |  | 
| Chris Lattner | f469cb6 | 2005-11-08 18:52:27 +0000 | [diff] [blame] | 177 |   bool MadeChange = false; | 
 | 178 |    | 
| Chris Lattner | 8b8749f | 2005-08-17 19:00:20 +0000 | [diff] [blame] | 179 |   // If we have a hint to start from, use it. | 
| Chris Lattner | f469cb6 | 2005-11-08 18:52:27 +0000 | [diff] [blame] | 180 |   if (N && N->use_empty()) { | 
 | 181 |     DestroyDeadNode(N); | 
 | 182 |     MadeChange = true; | 
| Chris Lattner | 0e12e6e | 2005-01-07 21:09:16 +0000 | [diff] [blame] | 183 |   } | 
 | 184 |  | 
| Chris Lattner | de202b3 | 2005-11-09 23:47:37 +0000 | [diff] [blame] | 185 |   for (allnodes_iterator I = allnodes_begin(), E = allnodes_end(); I != E; ++I) | 
 | 186 |     if (I->use_empty() && I->getOpcode() != 65535) { | 
 | 187 |       // Node is dead, recursively delete newly dead uses. | 
 | 188 |       DestroyDeadNode(I); | 
| Chris Lattner | f469cb6 | 2005-11-08 18:52:27 +0000 | [diff] [blame] | 189 |       MadeChange = true; | 
 | 190 |     } | 
| Chris Lattner | f469cb6 | 2005-11-08 18:52:27 +0000 | [diff] [blame] | 191 |    | 
 | 192 |   // Walk the nodes list, removing the nodes we've marked as dead. | 
 | 193 |   if (MadeChange) { | 
| Chris Lattner | de202b3 | 2005-11-09 23:47:37 +0000 | [diff] [blame] | 194 |     for (allnodes_iterator I = allnodes_begin(), E = allnodes_end(); I != E; ) { | 
 | 195 |       SDNode *N = I++; | 
 | 196 |       if (N->use_empty()) | 
 | 197 |         AllNodes.erase(N); | 
 | 198 |     } | 
| Chris Lattner | f469cb6 | 2005-11-08 18:52:27 +0000 | [diff] [blame] | 199 |   } | 
 | 200 |    | 
| Chris Lattner | 0e12e6e | 2005-01-07 21:09:16 +0000 | [diff] [blame] | 201 |   // If the root changed (e.g. it was a dead load, update the root). | 
| Chris Lattner | 9503859 | 2005-10-05 06:35:28 +0000 | [diff] [blame] | 202 |   setRoot(Dummy.getValue()); | 
| Chris Lattner | 0e12e6e | 2005-01-07 21:09:16 +0000 | [diff] [blame] | 203 | } | 
 | 204 |  | 
| Chris Lattner | f469cb6 | 2005-11-08 18:52:27 +0000 | [diff] [blame] | 205 | /// DestroyDeadNode - We know that N is dead.  Nuke it from the CSE maps for the | 
 | 206 | /// graph.  If it is the last user of any of its operands, recursively process | 
 | 207 | /// them the same way. | 
 | 208 | ///  | 
 | 209 | void SelectionDAG::DestroyDeadNode(SDNode *N) { | 
| Chris Lattner | 0e12e6e | 2005-01-07 21:09:16 +0000 | [diff] [blame] | 210 |   // Okay, we really are going to delete this node.  First take this out of the | 
 | 211 |   // appropriate CSE map. | 
| Chris Lattner | 149c58c | 2005-08-16 18:17:10 +0000 | [diff] [blame] | 212 |   RemoveNodeFromCSEMaps(N); | 
 | 213 |    | 
 | 214 |   // Next, brutally remove the operand list.  This is safe to do, as there are | 
 | 215 |   // no cycles in the graph. | 
| Chris Lattner | 65113b2 | 2005-11-08 22:07:03 +0000 | [diff] [blame] | 216 |   for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) { | 
 | 217 |     SDNode *O = I->Val; | 
| Chris Lattner | 149c58c | 2005-08-16 18:17:10 +0000 | [diff] [blame] | 218 |     O->removeUser(N); | 
 | 219 |      | 
 | 220 |     // Now that we removed this operand, see if there are no uses of it left. | 
| Chris Lattner | f469cb6 | 2005-11-08 18:52:27 +0000 | [diff] [blame] | 221 |     if (O->use_empty()) | 
 | 222 |       DestroyDeadNode(O); | 
| Chris Lattner | 149c58c | 2005-08-16 18:17:10 +0000 | [diff] [blame] | 223 |   } | 
| Chris Lattner | 65113b2 | 2005-11-08 22:07:03 +0000 | [diff] [blame] | 224 |   delete[] N->OperandList; | 
 | 225 |   N->OperandList = 0; | 
 | 226 |   N->NumOperands = 0; | 
| Chris Lattner | f469cb6 | 2005-11-08 18:52:27 +0000 | [diff] [blame] | 227 |  | 
 | 228 |   // Mark the node as dead. | 
 | 229 |   N->MorphNodeTo(65535); | 
| Chris Lattner | 149c58c | 2005-08-16 18:17:10 +0000 | [diff] [blame] | 230 | } | 
 | 231 |  | 
| Chris Lattner | c26aefa | 2005-08-29 21:59:31 +0000 | [diff] [blame] | 232 | void SelectionDAG::DeleteNode(SDNode *N) { | 
 | 233 |   assert(N->use_empty() && "Cannot delete a node that is not dead!"); | 
 | 234 |  | 
 | 235 |   // First take this out of the appropriate CSE map. | 
 | 236 |   RemoveNodeFromCSEMaps(N); | 
 | 237 |  | 
| Chris Lattner | 1e111c7 | 2005-09-07 05:37:01 +0000 | [diff] [blame] | 238 |   // Finally, remove uses due to operands of this node, remove from the  | 
 | 239 |   // AllNodes list, and delete the node. | 
 | 240 |   DeleteNodeNotInCSEMaps(N); | 
 | 241 | } | 
 | 242 |  | 
 | 243 | void SelectionDAG::DeleteNodeNotInCSEMaps(SDNode *N) { | 
 | 244 |  | 
| Chris Lattner | c26aefa | 2005-08-29 21:59:31 +0000 | [diff] [blame] | 245 |   // Remove it from the AllNodes list. | 
| Chris Lattner | de202b3 | 2005-11-09 23:47:37 +0000 | [diff] [blame] | 246 |   AllNodes.remove(N); | 
| Chris Lattner | c26aefa | 2005-08-29 21:59:31 +0000 | [diff] [blame] | 247 |      | 
 | 248 |   // Drop all of the operands and decrement used nodes use counts. | 
| Chris Lattner | 65113b2 | 2005-11-08 22:07:03 +0000 | [diff] [blame] | 249 |   for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) | 
 | 250 |     I->Val->removeUser(N); | 
 | 251 |   delete[] N->OperandList; | 
 | 252 |   N->OperandList = 0; | 
 | 253 |   N->NumOperands = 0; | 
| Chris Lattner | c26aefa | 2005-08-29 21:59:31 +0000 | [diff] [blame] | 254 |    | 
 | 255 |   delete N; | 
 | 256 | } | 
 | 257 |  | 
| Chris Lattner | 149c58c | 2005-08-16 18:17:10 +0000 | [diff] [blame] | 258 | /// RemoveNodeFromCSEMaps - Take the specified node out of the CSE map that | 
 | 259 | /// correspond to it.  This is useful when we're about to delete or repurpose | 
 | 260 | /// the node.  We don't want future request for structurally identical nodes | 
 | 261 | /// to return N anymore. | 
 | 262 | void SelectionDAG::RemoveNodeFromCSEMaps(SDNode *N) { | 
| Chris Lattner | 6621e3b | 2005-09-02 19:15:44 +0000 | [diff] [blame] | 263 |   bool Erased = false; | 
| Chris Lattner | 0e12e6e | 2005-01-07 21:09:16 +0000 | [diff] [blame] | 264 |   switch (N->getOpcode()) { | 
| Chris Lattner | 9503859 | 2005-10-05 06:35:28 +0000 | [diff] [blame] | 265 |   case ISD::HANDLENODE: return;  // noop. | 
| Chris Lattner | 0e12e6e | 2005-01-07 21:09:16 +0000 | [diff] [blame] | 266 |   case ISD::Constant: | 
| Chris Lattner | 6621e3b | 2005-09-02 19:15:44 +0000 | [diff] [blame] | 267 |     Erased = Constants.erase(std::make_pair(cast<ConstantSDNode>(N)->getValue(), | 
 | 268 |                                             N->getValueType(0))); | 
| Chris Lattner | 0e12e6e | 2005-01-07 21:09:16 +0000 | [diff] [blame] | 269 |     break; | 
| Chris Lattner | 37bfbb4 | 2005-08-17 00:34:06 +0000 | [diff] [blame] | 270 |   case ISD::TargetConstant: | 
| Chris Lattner | 6621e3b | 2005-09-02 19:15:44 +0000 | [diff] [blame] | 271 |     Erased = TargetConstants.erase(std::make_pair( | 
 | 272 |                                     cast<ConstantSDNode>(N)->getValue(), | 
 | 273 |                                                   N->getValueType(0))); | 
| Chris Lattner | 37bfbb4 | 2005-08-17 00:34:06 +0000 | [diff] [blame] | 274 |     break; | 
| Chris Lattner | d865861 | 2005-02-17 20:17:32 +0000 | [diff] [blame] | 275 |   case ISD::ConstantFP: { | 
| Jim Laskey | cb6682f | 2005-08-17 19:34:49 +0000 | [diff] [blame] | 276 |     uint64_t V = DoubleToBits(cast<ConstantFPSDNode>(N)->getValue()); | 
| Chris Lattner | 6621e3b | 2005-09-02 19:15:44 +0000 | [diff] [blame] | 277 |     Erased = ConstantFPs.erase(std::make_pair(V, N->getValueType(0))); | 
| Chris Lattner | 0e12e6e | 2005-01-07 21:09:16 +0000 | [diff] [blame] | 278 |     break; | 
| Chris Lattner | d865861 | 2005-02-17 20:17:32 +0000 | [diff] [blame] | 279 |   } | 
| Chris Lattner | 36ce691 | 2005-11-29 06:21:05 +0000 | [diff] [blame] | 280 |   case ISD::STRING: | 
 | 281 |     Erased = StringNodes.erase(cast<StringSDNode>(N)->getValue()); | 
 | 282 |     break; | 
| Chris Lattner | 7cf7e3f | 2005-08-09 20:20:18 +0000 | [diff] [blame] | 283 |   case ISD::CONDCODE: | 
 | 284 |     assert(CondCodeNodes[cast<CondCodeSDNode>(N)->get()] && | 
 | 285 |            "Cond code doesn't exist!"); | 
| Chris Lattner | 6621e3b | 2005-09-02 19:15:44 +0000 | [diff] [blame] | 286 |     Erased = CondCodeNodes[cast<CondCodeSDNode>(N)->get()] != 0; | 
| Chris Lattner | 7cf7e3f | 2005-08-09 20:20:18 +0000 | [diff] [blame] | 287 |     CondCodeNodes[cast<CondCodeSDNode>(N)->get()] = 0; | 
 | 288 |     break; | 
| Evan Cheng | 14229bb | 2005-11-30 02:49:21 +0000 | [diff] [blame] | 289 |   case ISD::GlobalAddress: { | 
 | 290 |     GlobalAddressSDNode *GN = cast<GlobalAddressSDNode>(N); | 
 | 291 |     Erased = GlobalValues.erase(std::make_pair(GN->getGlobal(), | 
 | 292 |                                                GN->getOffset())); | 
| Chris Lattner | 0e12e6e | 2005-01-07 21:09:16 +0000 | [diff] [blame] | 293 |     break; | 
| Evan Cheng | 14229bb | 2005-11-30 02:49:21 +0000 | [diff] [blame] | 294 |   } | 
 | 295 |   case ISD::TargetGlobalAddress: { | 
 | 296 |     GlobalAddressSDNode *GN = cast<GlobalAddressSDNode>(N); | 
 | 297 |     Erased =TargetGlobalValues.erase(std::make_pair(GN->getGlobal(), | 
 | 298 |                                                     GN->getOffset())); | 
| Chris Lattner | aaaa0b6 | 2005-08-19 22:31:04 +0000 | [diff] [blame] | 299 |     break; | 
| Evan Cheng | 14229bb | 2005-11-30 02:49:21 +0000 | [diff] [blame] | 300 |   } | 
| Chris Lattner | 0e12e6e | 2005-01-07 21:09:16 +0000 | [diff] [blame] | 301 |   case ISD::FrameIndex: | 
| Chris Lattner | 6621e3b | 2005-09-02 19:15:44 +0000 | [diff] [blame] | 302 |     Erased = FrameIndices.erase(cast<FrameIndexSDNode>(N)->getIndex()); | 
| Chris Lattner | 0e12e6e | 2005-01-07 21:09:16 +0000 | [diff] [blame] | 303 |     break; | 
| Chris Lattner | afb2dd4 | 2005-08-25 00:43:01 +0000 | [diff] [blame] | 304 |   case ISD::TargetFrameIndex: | 
| Chris Lattner | 6621e3b | 2005-09-02 19:15:44 +0000 | [diff] [blame] | 305 |     Erased = TargetFrameIndices.erase(cast<FrameIndexSDNode>(N)->getIndex()); | 
| Chris Lattner | afb2dd4 | 2005-08-25 00:43:01 +0000 | [diff] [blame] | 306 |     break; | 
| Chris Lattner | 0e12e6e | 2005-01-07 21:09:16 +0000 | [diff] [blame] | 307 |   case ISD::ConstantPool: | 
| Chris Lattner | 6621e3b | 2005-09-02 19:15:44 +0000 | [diff] [blame] | 308 |     Erased = ConstantPoolIndices.erase(cast<ConstantPoolSDNode>(N)->get()); | 
| Chris Lattner | 0e12e6e | 2005-01-07 21:09:16 +0000 | [diff] [blame] | 309 |     break; | 
| Chris Lattner | 4025a9c | 2005-08-25 05:03:06 +0000 | [diff] [blame] | 310 |   case ISD::TargetConstantPool: | 
| Chris Lattner | 6621e3b | 2005-09-02 19:15:44 +0000 | [diff] [blame] | 311 |     Erased =TargetConstantPoolIndices.erase(cast<ConstantPoolSDNode>(N)->get()); | 
| Chris Lattner | 4025a9c | 2005-08-25 05:03:06 +0000 | [diff] [blame] | 312 |     break; | 
| Chris Lattner | 0e12e6e | 2005-01-07 21:09:16 +0000 | [diff] [blame] | 313 |   case ISD::BasicBlock: | 
| Chris Lattner | 6621e3b | 2005-09-02 19:15:44 +0000 | [diff] [blame] | 314 |     Erased = BBNodes.erase(cast<BasicBlockSDNode>(N)->getBasicBlock()); | 
| Chris Lattner | 0e12e6e | 2005-01-07 21:09:16 +0000 | [diff] [blame] | 315 |     break; | 
 | 316 |   case ISD::ExternalSymbol: | 
| Chris Lattner | 6621e3b | 2005-09-02 19:15:44 +0000 | [diff] [blame] | 317 |     Erased = ExternalSymbols.erase(cast<ExternalSymbolSDNode>(N)->getSymbol()); | 
| Chris Lattner | 0e12e6e | 2005-01-07 21:09:16 +0000 | [diff] [blame] | 318 |     break; | 
| Andrew Lenharth | 2a2de66 | 2005-10-23 03:40:17 +0000 | [diff] [blame] | 319 |   case ISD::TargetExternalSymbol: | 
| Chris Lattner | 809ec11 | 2006-01-28 10:09:25 +0000 | [diff] [blame] | 320 |     Erased = | 
 | 321 |       TargetExternalSymbols.erase(cast<ExternalSymbolSDNode>(N)->getSymbol()); | 
| Andrew Lenharth | 2a2de66 | 2005-10-23 03:40:17 +0000 | [diff] [blame] | 322 |     break; | 
| Chris Lattner | 15e4b01 | 2005-07-10 00:07:11 +0000 | [diff] [blame] | 323 |   case ISD::VALUETYPE: | 
| Chris Lattner | 6621e3b | 2005-09-02 19:15:44 +0000 | [diff] [blame] | 324 |     Erased = ValueTypeNodes[cast<VTSDNode>(N)->getVT()] != 0; | 
| Chris Lattner | 15e4b01 | 2005-07-10 00:07:11 +0000 | [diff] [blame] | 325 |     ValueTypeNodes[cast<VTSDNode>(N)->getVT()] = 0; | 
 | 326 |     break; | 
| Chris Lattner | d5d0f9b | 2005-08-16 21:55:35 +0000 | [diff] [blame] | 327 |   case ISD::Register: | 
| Chris Lattner | 6621e3b | 2005-09-02 19:15:44 +0000 | [diff] [blame] | 328 |     Erased = RegNodes.erase(std::make_pair(cast<RegisterSDNode>(N)->getReg(), | 
 | 329 |                                            N->getValueType(0))); | 
| Chris Lattner | d5d0f9b | 2005-08-16 21:55:35 +0000 | [diff] [blame] | 330 |     break; | 
| Chris Lattner | c534395 | 2005-08-05 16:55:31 +0000 | [diff] [blame] | 331 |   case ISD::SRCVALUE: { | 
 | 332 |     SrcValueSDNode *SVN = cast<SrcValueSDNode>(N); | 
| Chris Lattner | 6621e3b | 2005-09-02 19:15:44 +0000 | [diff] [blame] | 333 |     Erased =ValueNodes.erase(std::make_pair(SVN->getValue(), SVN->getOffset())); | 
| Chris Lattner | c534395 | 2005-08-05 16:55:31 +0000 | [diff] [blame] | 334 |     break; | 
 | 335 |   }     | 
| Chris Lattner | 0e12e6e | 2005-01-07 21:09:16 +0000 | [diff] [blame] | 336 |   case ISD::LOAD: | 
| Chris Lattner | 6621e3b | 2005-09-02 19:15:44 +0000 | [diff] [blame] | 337 |     Erased = Loads.erase(std::make_pair(N->getOperand(1), | 
 | 338 |                                         std::make_pair(N->getOperand(0), | 
 | 339 |                                                        N->getValueType(0)))); | 
| Chris Lattner | 0e12e6e | 2005-01-07 21:09:16 +0000 | [diff] [blame] | 340 |     break; | 
| Chris Lattner | 0e12e6e | 2005-01-07 21:09:16 +0000 | [diff] [blame] | 341 |   default: | 
| Chris Lattner | 6621e3b | 2005-09-02 19:15:44 +0000 | [diff] [blame] | 342 |     if (N->getNumValues() == 1) { | 
| Chris Lattner | 70b9b10 | 2005-09-02 19:36:17 +0000 | [diff] [blame] | 343 |       if (N->getNumOperands() == 0) { | 
 | 344 |         Erased = NullaryOps.erase(std::make_pair(N->getOpcode(), | 
 | 345 |                                                  N->getValueType(0))); | 
 | 346 |       } else if (N->getNumOperands() == 1) { | 
| Chris Lattner | 6621e3b | 2005-09-02 19:15:44 +0000 | [diff] [blame] | 347 |         Erased =  | 
 | 348 |           UnaryOps.erase(std::make_pair(N->getOpcode(), | 
 | 349 |                                         std::make_pair(N->getOperand(0), | 
 | 350 |                                                        N->getValueType(0)))); | 
 | 351 |       } else if (N->getNumOperands() == 2) { | 
 | 352 |         Erased =  | 
 | 353 |           BinaryOps.erase(std::make_pair(N->getOpcode(), | 
 | 354 |                                          std::make_pair(N->getOperand(0), | 
 | 355 |                                                         N->getOperand(1)))); | 
 | 356 |       } else {  | 
 | 357 |         std::vector<SDOperand> Ops(N->op_begin(), N->op_end()); | 
 | 358 |         Erased =  | 
 | 359 |           OneResultNodes.erase(std::make_pair(N->getOpcode(), | 
 | 360 |                                               std::make_pair(N->getValueType(0), | 
 | 361 |                                                              Ops))); | 
 | 362 |       } | 
| Chris Lattner | 385328c | 2005-05-14 07:42:29 +0000 | [diff] [blame] | 363 |     } else { | 
| Chris Lattner | 89c3463 | 2005-05-14 06:20:26 +0000 | [diff] [blame] | 364 |       // Remove the node from the ArbitraryNodes map. | 
 | 365 |       std::vector<MVT::ValueType> RV(N->value_begin(), N->value_end()); | 
 | 366 |       std::vector<SDOperand>     Ops(N->op_begin(), N->op_end()); | 
| Chris Lattner | 6621e3b | 2005-09-02 19:15:44 +0000 | [diff] [blame] | 367 |       Erased = | 
 | 368 |         ArbitraryNodes.erase(std::make_pair(N->getOpcode(), | 
 | 369 |                                             std::make_pair(RV, Ops))); | 
| Chris Lattner | 89c3463 | 2005-05-14 06:20:26 +0000 | [diff] [blame] | 370 |     } | 
| Chris Lattner | 0e12e6e | 2005-01-07 21:09:16 +0000 | [diff] [blame] | 371 |     break; | 
 | 372 |   } | 
| Chris Lattner | 6621e3b | 2005-09-02 19:15:44 +0000 | [diff] [blame] | 373 | #ifndef NDEBUG | 
 | 374 |   // Verify that the node was actually in one of the CSE maps, unless it has a  | 
 | 375 |   // flag result (which cannot be CSE'd) or is one of the special cases that are | 
 | 376 |   // not subject to CSE. | 
 | 377 |   if (!Erased && N->getValueType(N->getNumValues()-1) != MVT::Flag && | 
| Chris Lattner | 0ff5c27 | 2006-01-28 00:18:58 +0000 | [diff] [blame] | 378 |       N->getOpcode() != ISD::CALLSEQ_START && | 
| Chris Lattner | 6a8a21c | 2005-09-03 01:04:40 +0000 | [diff] [blame] | 379 |       N->getOpcode() != ISD::CALLSEQ_END && !N->isTargetOpcode()) { | 
| Chris Lattner | 6621e3b | 2005-09-02 19:15:44 +0000 | [diff] [blame] | 380 |      | 
 | 381 |     N->dump(); | 
 | 382 |     assert(0 && "Node is not in map!"); | 
 | 383 |   } | 
 | 384 | #endif | 
| Chris Lattner | 0e12e6e | 2005-01-07 21:09:16 +0000 | [diff] [blame] | 385 | } | 
 | 386 |  | 
| Chris Lattner | 8b8749f | 2005-08-17 19:00:20 +0000 | [diff] [blame] | 387 | /// AddNonLeafNodeToCSEMaps - Add the specified node back to the CSE maps.  It | 
 | 388 | /// has been taken out and modified in some way.  If the specified node already | 
 | 389 | /// exists in the CSE maps, do not modify the maps, but return the existing node | 
 | 390 | /// instead.  If it doesn't exist, add it and return null. | 
 | 391 | /// | 
 | 392 | SDNode *SelectionDAG::AddNonLeafNodeToCSEMaps(SDNode *N) { | 
 | 393 |   assert(N->getNumOperands() && "This is a leaf node!"); | 
| Chris Lattner | c85a9f3 | 2005-11-30 18:20:52 +0000 | [diff] [blame] | 394 |   if (N->getOpcode() == ISD::CALLSEQ_START ||  | 
| Chris Lattner | fe14b34 | 2005-12-01 23:14:50 +0000 | [diff] [blame] | 395 |       N->getOpcode() == ISD::CALLSEQ_END || | 
| Chris Lattner | 9f8cc69 | 2005-12-19 22:21:21 +0000 | [diff] [blame] | 396 |       N->getOpcode() == ISD::HANDLENODE || N->getValueType(0) == MVT::Flag) | 
| Chris Lattner | fe14b34 | 2005-12-01 23:14:50 +0000 | [diff] [blame] | 397 |     return 0;    // Never add these nodes. | 
| Chris Lattner | c85a9f3 | 2005-11-30 18:20:52 +0000 | [diff] [blame] | 398 |    | 
| Chris Lattner | 9f8cc69 | 2005-12-19 22:21:21 +0000 | [diff] [blame] | 399 |   // Check that remaining values produced are not flags. | 
 | 400 |   for (unsigned i = 1, e = N->getNumValues(); i != e; ++i) | 
 | 401 |     if (N->getValueType(i) == MVT::Flag) | 
 | 402 |       return 0;   // Never CSE anything that produces a flag. | 
 | 403 |    | 
| Chris Lattner | fe14b34 | 2005-12-01 23:14:50 +0000 | [diff] [blame] | 404 |   if (N->getNumValues() == 1) { | 
 | 405 |     if (N->getNumOperands() == 1) { | 
 | 406 |       SDNode *&U = UnaryOps[std::make_pair(N->getOpcode(), | 
 | 407 |                                            std::make_pair(N->getOperand(0), | 
 | 408 |                                                           N->getValueType(0)))]; | 
 | 409 |       if (U) return U; | 
 | 410 |       U = N; | 
 | 411 |     } else if (N->getNumOperands() == 2) { | 
 | 412 |       SDNode *&B = BinaryOps[std::make_pair(N->getOpcode(), | 
 | 413 |                                             std::make_pair(N->getOperand(0), | 
 | 414 |                                                            N->getOperand(1)))]; | 
 | 415 |       if (B) return B; | 
 | 416 |       B = N; | 
 | 417 |     } else { | 
 | 418 |       std::vector<SDOperand> Ops(N->op_begin(), N->op_end()); | 
 | 419 |       SDNode *&ORN = OneResultNodes[std::make_pair(N->getOpcode(), | 
| Chris Lattner | 809ec11 | 2006-01-28 10:09:25 +0000 | [diff] [blame] | 420 |                                       std::make_pair(N->getValueType(0), Ops))]; | 
| Chris Lattner | fe14b34 | 2005-12-01 23:14:50 +0000 | [diff] [blame] | 421 |       if (ORN) return ORN; | 
 | 422 |       ORN = N; | 
 | 423 |     } | 
 | 424 |   } else {   | 
 | 425 |     if (N->getOpcode() == ISD::LOAD) { | 
 | 426 |       SDNode *&L = Loads[std::make_pair(N->getOperand(1), | 
 | 427 |                                         std::make_pair(N->getOperand(0), | 
 | 428 |                                                        N->getValueType(0)))]; | 
 | 429 |       if (L) return L; | 
 | 430 |       L = N; | 
 | 431 |     } else { | 
 | 432 |       // Remove the node from the ArbitraryNodes map. | 
 | 433 |       std::vector<MVT::ValueType> RV(N->value_begin(), N->value_end()); | 
 | 434 |       std::vector<SDOperand>     Ops(N->op_begin(), N->op_end()); | 
 | 435 |       SDNode *&AN = ArbitraryNodes[std::make_pair(N->getOpcode(), | 
 | 436 |                                                   std::make_pair(RV, Ops))]; | 
 | 437 |       if (AN) return AN; | 
 | 438 |       AN = N; | 
 | 439 |     } | 
| Chris Lattner | 8b8749f | 2005-08-17 19:00:20 +0000 | [diff] [blame] | 440 |   } | 
 | 441 |   return 0; | 
| Chris Lattner | 8b8749f | 2005-08-17 19:00:20 +0000 | [diff] [blame] | 442 | } | 
 | 443 |  | 
| Chris Lattner | df6eb30 | 2006-01-28 09:32:45 +0000 | [diff] [blame] | 444 | /// FindModifiedNodeSlot - Find a slot for the specified node if its operands | 
 | 445 | /// were replaced with those specified.  If this node is never memoized,  | 
 | 446 | /// return null, otherwise return a pointer to the slot it would take.  If a | 
 | 447 | /// node already exists with these operands, the slot will be non-null. | 
 | 448 | SDNode **SelectionDAG::FindModifiedNodeSlot(SDNode *N, SDOperand Op) { | 
 | 449 |   if (N->getOpcode() == ISD::CALLSEQ_START ||  | 
 | 450 |       N->getOpcode() == ISD::CALLSEQ_END || | 
 | 451 |       N->getOpcode() == ISD::HANDLENODE || N->getValueType(0) == MVT::Flag) | 
 | 452 |     return 0;    // Never add these nodes. | 
 | 453 |    | 
 | 454 |   // Check that remaining values produced are not flags. | 
 | 455 |   for (unsigned i = 1, e = N->getNumValues(); i != e; ++i) | 
 | 456 |     if (N->getValueType(i) == MVT::Flag) | 
 | 457 |       return 0;   // Never CSE anything that produces a flag. | 
 | 458 |    | 
 | 459 |   if (N->getNumValues() == 1) { | 
 | 460 |     return &UnaryOps[std::make_pair(N->getOpcode(), | 
 | 461 |                                     std::make_pair(Op, N->getValueType(0)))]; | 
 | 462 |   } else {   | 
 | 463 |     // Remove the node from the ArbitraryNodes map. | 
 | 464 |     std::vector<MVT::ValueType> RV(N->value_begin(), N->value_end()); | 
 | 465 |     std::vector<SDOperand> Ops; | 
 | 466 |     Ops.push_back(Op); | 
 | 467 |     return &ArbitraryNodes[std::make_pair(N->getOpcode(), | 
 | 468 |                                           std::make_pair(RV, Ops))]; | 
 | 469 |   } | 
 | 470 |   return 0; | 
 | 471 | } | 
 | 472 |  | 
 | 473 | /// FindModifiedNodeSlot - Find a slot for the specified node if its operands | 
 | 474 | /// were replaced with those specified.  If this node is never memoized,  | 
 | 475 | /// return null, otherwise return a pointer to the slot it would take.  If a | 
 | 476 | /// node already exists with these operands, the slot will be non-null. | 
 | 477 | SDNode **SelectionDAG::FindModifiedNodeSlot(SDNode *N,  | 
 | 478 |                                             SDOperand Op1, SDOperand Op2) { | 
 | 479 |   if (N->getOpcode() == ISD::CALLSEQ_START ||  | 
 | 480 |       N->getOpcode() == ISD::CALLSEQ_END || | 
 | 481 |       N->getOpcode() == ISD::HANDLENODE || N->getValueType(0) == MVT::Flag) | 
 | 482 |     return 0;    // Never add these nodes. | 
 | 483 |    | 
 | 484 |   // Check that remaining values produced are not flags. | 
 | 485 |   for (unsigned i = 1, e = N->getNumValues(); i != e; ++i) | 
 | 486 |     if (N->getValueType(i) == MVT::Flag) | 
 | 487 |       return 0;   // Never CSE anything that produces a flag. | 
 | 488 |    | 
 | 489 |   if (N->getNumValues() == 1) { | 
 | 490 |     return &BinaryOps[std::make_pair(N->getOpcode(), | 
 | 491 |                                      std::make_pair(Op1, Op2))]; | 
 | 492 |   } else {   | 
 | 493 |     std::vector<MVT::ValueType> RV(N->value_begin(), N->value_end()); | 
 | 494 |     std::vector<SDOperand> Ops; | 
 | 495 |     Ops.push_back(Op1); | 
 | 496 |     Ops.push_back(Op2); | 
 | 497 |     return &ArbitraryNodes[std::make_pair(N->getOpcode(), | 
 | 498 |                                           std::make_pair(RV, Ops))]; | 
 | 499 |   } | 
 | 500 |   return 0; | 
 | 501 | } | 
 | 502 |  | 
 | 503 |  | 
 | 504 | /// FindModifiedNodeSlot - Find a slot for the specified node if its operands | 
 | 505 | /// were replaced with those specified.  If this node is never memoized,  | 
 | 506 | /// return null, otherwise return a pointer to the slot it would take.  If a | 
 | 507 | /// node already exists with these operands, the slot will be non-null. | 
 | 508 | SDNode **SelectionDAG::FindModifiedNodeSlot(SDNode *N,  | 
 | 509 |                                             const std::vector<SDOperand> &Ops) { | 
 | 510 |   if (N->getOpcode() == ISD::CALLSEQ_START ||  | 
 | 511 |       N->getOpcode() == ISD::CALLSEQ_END || | 
 | 512 |       N->getOpcode() == ISD::HANDLENODE || N->getValueType(0) == MVT::Flag) | 
 | 513 |     return 0;    // Never add these nodes. | 
 | 514 |    | 
 | 515 |   // Check that remaining values produced are not flags. | 
 | 516 |   for (unsigned i = 1, e = N->getNumValues(); i != e; ++i) | 
 | 517 |     if (N->getValueType(i) == MVT::Flag) | 
 | 518 |       return 0;   // Never CSE anything that produces a flag. | 
 | 519 |    | 
 | 520 |   if (N->getNumValues() == 1) { | 
 | 521 |     if (N->getNumOperands() == 1) { | 
 | 522 |       return &UnaryOps[std::make_pair(N->getOpcode(), | 
 | 523 |                                       std::make_pair(Ops[0], | 
 | 524 |                                                      N->getValueType(0)))]; | 
 | 525 |     } else if (N->getNumOperands() == 2) { | 
 | 526 |       return &BinaryOps[std::make_pair(N->getOpcode(), | 
 | 527 |                                        std::make_pair(Ops[0], Ops[1]))]; | 
 | 528 |     } else { | 
 | 529 |       return &OneResultNodes[std::make_pair(N->getOpcode(), | 
 | 530 |                                             std::make_pair(N->getValueType(0), | 
 | 531 |                                                            Ops))]; | 
 | 532 |     } | 
 | 533 |   } else {   | 
 | 534 |     if (N->getOpcode() == ISD::LOAD) { | 
 | 535 |       return &Loads[std::make_pair(Ops[1], | 
 | 536 |                                    std::make_pair(Ops[0], N->getValueType(0)))]; | 
 | 537 |     } else { | 
 | 538 |       std::vector<MVT::ValueType> RV(N->value_begin(), N->value_end()); | 
 | 539 |       return &ArbitraryNodes[std::make_pair(N->getOpcode(), | 
 | 540 |                                             std::make_pair(RV, Ops))]; | 
 | 541 |     } | 
 | 542 |   } | 
 | 543 |   return 0; | 
 | 544 | } | 
| Chris Lattner | 8b8749f | 2005-08-17 19:00:20 +0000 | [diff] [blame] | 545 |  | 
| Chris Lattner | 0e12e6e | 2005-01-07 21:09:16 +0000 | [diff] [blame] | 546 |  | 
| Chris Lattner | 78ec311 | 2003-08-11 14:57:33 +0000 | [diff] [blame] | 547 | SelectionDAG::~SelectionDAG() { | 
| Chris Lattner | de202b3 | 2005-11-09 23:47:37 +0000 | [diff] [blame] | 548 |   while (!AllNodes.empty()) { | 
 | 549 |     SDNode *N = AllNodes.begin(); | 
| Chris Lattner | 65113b2 | 2005-11-08 22:07:03 +0000 | [diff] [blame] | 550 |     delete [] N->OperandList; | 
 | 551 |     N->OperandList = 0; | 
 | 552 |     N->NumOperands = 0; | 
| Chris Lattner | de202b3 | 2005-11-09 23:47:37 +0000 | [diff] [blame] | 553 |     AllNodes.pop_front(); | 
| Chris Lattner | 65113b2 | 2005-11-08 22:07:03 +0000 | [diff] [blame] | 554 |   } | 
| Chris Lattner | 78ec311 | 2003-08-11 14:57:33 +0000 | [diff] [blame] | 555 | } | 
 | 556 |  | 
| Chris Lattner | 0f2287b | 2005-04-13 02:38:18 +0000 | [diff] [blame] | 557 | SDOperand SelectionDAG::getZeroExtendInReg(SDOperand Op, MVT::ValueType VT) { | 
| Chris Lattner | 51679c4 | 2005-04-13 19:41:05 +0000 | [diff] [blame] | 558 |   if (Op.getValueType() == VT) return Op; | 
| Jeff Cohen | 19bb228 | 2005-05-10 02:22:38 +0000 | [diff] [blame] | 559 |   int64_t Imm = ~0ULL >> (64-MVT::getSizeInBits(VT)); | 
| Chris Lattner | 0f2287b | 2005-04-13 02:38:18 +0000 | [diff] [blame] | 560 |   return getNode(ISD::AND, Op.getValueType(), Op, | 
 | 561 |                  getConstant(Imm, Op.getValueType())); | 
 | 562 | } | 
 | 563 |  | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 564 | SDOperand SelectionDAG::getConstant(uint64_t Val, MVT::ValueType VT) { | 
 | 565 |   assert(MVT::isInteger(VT) && "Cannot create FP integer constant!"); | 
 | 566 |   // Mask out any bits that are not valid for this constant. | 
| Chris Lattner | 623f70d | 2005-01-08 06:24:30 +0000 | [diff] [blame] | 567 |   if (VT != MVT::i64) | 
 | 568 |     Val &= ((uint64_t)1 << MVT::getSizeInBits(VT)) - 1; | 
| Misha Brukman | edf128a | 2005-04-21 22:36:52 +0000 | [diff] [blame] | 569 |  | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 570 |   SDNode *&N = Constants[std::make_pair(Val, VT)]; | 
 | 571 |   if (N) return SDOperand(N, 0); | 
| Chris Lattner | 37bfbb4 | 2005-08-17 00:34:06 +0000 | [diff] [blame] | 572 |   N = new ConstantSDNode(false, Val, VT); | 
 | 573 |   AllNodes.push_back(N); | 
 | 574 |   return SDOperand(N, 0); | 
 | 575 | } | 
 | 576 |  | 
| Chris Lattner | 36ce691 | 2005-11-29 06:21:05 +0000 | [diff] [blame] | 577 | SDOperand SelectionDAG::getString(const std::string &Val) { | 
 | 578 |   StringSDNode *&N = StringNodes[Val]; | 
 | 579 |   if (!N) { | 
 | 580 |     N = new StringSDNode(Val); | 
 | 581 |     AllNodes.push_back(N); | 
 | 582 |   } | 
 | 583 |   return SDOperand(N, 0); | 
 | 584 | } | 
 | 585 |  | 
| Chris Lattner | 37bfbb4 | 2005-08-17 00:34:06 +0000 | [diff] [blame] | 586 | SDOperand SelectionDAG::getTargetConstant(uint64_t Val, MVT::ValueType VT) { | 
 | 587 |   assert(MVT::isInteger(VT) && "Cannot create FP integer constant!"); | 
 | 588 |   // Mask out any bits that are not valid for this constant. | 
 | 589 |   if (VT != MVT::i64) | 
 | 590 |     Val &= ((uint64_t)1 << MVT::getSizeInBits(VT)) - 1; | 
 | 591 |    | 
 | 592 |   SDNode *&N = TargetConstants[std::make_pair(Val, VT)]; | 
 | 593 |   if (N) return SDOperand(N, 0); | 
 | 594 |   N = new ConstantSDNode(true, Val, VT); | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 595 |   AllNodes.push_back(N); | 
 | 596 |   return SDOperand(N, 0); | 
| Chris Lattner | 78ec311 | 2003-08-11 14:57:33 +0000 | [diff] [blame] | 597 | } | 
 | 598 |  | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 599 | SDOperand SelectionDAG::getConstantFP(double Val, MVT::ValueType VT) { | 
 | 600 |   assert(MVT::isFloatingPoint(VT) && "Cannot create integer FP constant!"); | 
 | 601 |   if (VT == MVT::f32) | 
 | 602 |     Val = (float)Val;  // Mask out extra precision. | 
 | 603 |  | 
| Chris Lattner | d865861 | 2005-02-17 20:17:32 +0000 | [diff] [blame] | 604 |   // Do the map lookup using the actual bit pattern for the floating point | 
 | 605 |   // value, so that we don't have problems with 0.0 comparing equal to -0.0, and | 
 | 606 |   // we don't have issues with SNANs. | 
| Jim Laskey | cb6682f | 2005-08-17 19:34:49 +0000 | [diff] [blame] | 607 |   SDNode *&N = ConstantFPs[std::make_pair(DoubleToBits(Val), VT)]; | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 608 |   if (N) return SDOperand(N, 0); | 
 | 609 |   N = new ConstantFPSDNode(Val, VT); | 
 | 610 |   AllNodes.push_back(N); | 
 | 611 |   return SDOperand(N, 0); | 
 | 612 | } | 
 | 613 |  | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 614 | SDOperand SelectionDAG::getGlobalAddress(const GlobalValue *GV, | 
| Evan Cheng | 14229bb | 2005-11-30 02:49:21 +0000 | [diff] [blame] | 615 |                                          MVT::ValueType VT, int offset) { | 
 | 616 |   SDNode *&N = GlobalValues[std::make_pair(GV, offset)]; | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 617 |   if (N) return SDOperand(N, 0); | 
| Nate Begeman | 512beb9 | 2005-12-30 00:10:38 +0000 | [diff] [blame] | 618 |   N = new GlobalAddressSDNode(false, GV, VT, offset); | 
| Chris Lattner | aaaa0b6 | 2005-08-19 22:31:04 +0000 | [diff] [blame] | 619 |   AllNodes.push_back(N); | 
 | 620 |   return SDOperand(N, 0); | 
 | 621 | } | 
 | 622 |  | 
 | 623 | SDOperand SelectionDAG::getTargetGlobalAddress(const GlobalValue *GV, | 
| Evan Cheng | 61ca74b | 2005-11-30 02:04:11 +0000 | [diff] [blame] | 624 |                                                MVT::ValueType VT, int offset) { | 
| Evan Cheng | 14229bb | 2005-11-30 02:49:21 +0000 | [diff] [blame] | 625 |   SDNode *&N = TargetGlobalValues[std::make_pair(GV, offset)]; | 
| Chris Lattner | aaaa0b6 | 2005-08-19 22:31:04 +0000 | [diff] [blame] | 626 |   if (N) return SDOperand(N, 0); | 
| Evan Cheng | 61ca74b | 2005-11-30 02:04:11 +0000 | [diff] [blame] | 627 |   N = new GlobalAddressSDNode(true, GV, VT, offset); | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 628 |   AllNodes.push_back(N); | 
 | 629 |   return SDOperand(N, 0); | 
 | 630 | } | 
 | 631 |  | 
 | 632 | SDOperand SelectionDAG::getFrameIndex(int FI, MVT::ValueType VT) { | 
 | 633 |   SDNode *&N = FrameIndices[FI]; | 
 | 634 |   if (N) return SDOperand(N, 0); | 
| Chris Lattner | afb2dd4 | 2005-08-25 00:43:01 +0000 | [diff] [blame] | 635 |   N = new FrameIndexSDNode(FI, VT, false); | 
 | 636 |   AllNodes.push_back(N); | 
 | 637 |   return SDOperand(N, 0); | 
 | 638 | } | 
 | 639 |  | 
 | 640 | SDOperand SelectionDAG::getTargetFrameIndex(int FI, MVT::ValueType VT) { | 
 | 641 |   SDNode *&N = TargetFrameIndices[FI]; | 
 | 642 |   if (N) return SDOperand(N, 0); | 
 | 643 |   N = new FrameIndexSDNode(FI, VT, true); | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 644 |   AllNodes.push_back(N); | 
 | 645 |   return SDOperand(N, 0); | 
 | 646 | } | 
 | 647 |  | 
| Chris Lattner | 5839bf2 | 2005-08-26 17:15:30 +0000 | [diff] [blame] | 648 | SDOperand SelectionDAG::getConstantPool(Constant *C, MVT::ValueType VT) { | 
 | 649 |   SDNode *&N = ConstantPoolIndices[C]; | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 650 |   if (N) return SDOperand(N, 0); | 
| Chris Lattner | 5839bf2 | 2005-08-26 17:15:30 +0000 | [diff] [blame] | 651 |   N = new ConstantPoolSDNode(C, VT, false); | 
| Chris Lattner | 4025a9c | 2005-08-25 05:03:06 +0000 | [diff] [blame] | 652 |   AllNodes.push_back(N); | 
 | 653 |   return SDOperand(N, 0); | 
 | 654 | } | 
 | 655 |  | 
| Chris Lattner | 5839bf2 | 2005-08-26 17:15:30 +0000 | [diff] [blame] | 656 | SDOperand SelectionDAG::getTargetConstantPool(Constant *C, MVT::ValueType VT) { | 
 | 657 |   SDNode *&N = TargetConstantPoolIndices[C]; | 
| Chris Lattner | 4025a9c | 2005-08-25 05:03:06 +0000 | [diff] [blame] | 658 |   if (N) return SDOperand(N, 0); | 
| Chris Lattner | 5839bf2 | 2005-08-26 17:15:30 +0000 | [diff] [blame] | 659 |   N = new ConstantPoolSDNode(C, VT, true); | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 660 |   AllNodes.push_back(N); | 
 | 661 |   return SDOperand(N, 0); | 
 | 662 | } | 
 | 663 |  | 
 | 664 | SDOperand SelectionDAG::getBasicBlock(MachineBasicBlock *MBB) { | 
 | 665 |   SDNode *&N = BBNodes[MBB]; | 
 | 666 |   if (N) return SDOperand(N, 0); | 
 | 667 |   N = new BasicBlockSDNode(MBB); | 
 | 668 |   AllNodes.push_back(N); | 
 | 669 |   return SDOperand(N, 0); | 
 | 670 | } | 
 | 671 |  | 
| Chris Lattner | 15e4b01 | 2005-07-10 00:07:11 +0000 | [diff] [blame] | 672 | SDOperand SelectionDAG::getValueType(MVT::ValueType VT) { | 
 | 673 |   if ((unsigned)VT >= ValueTypeNodes.size()) | 
 | 674 |     ValueTypeNodes.resize(VT+1); | 
 | 675 |   if (ValueTypeNodes[VT] == 0) { | 
 | 676 |     ValueTypeNodes[VT] = new VTSDNode(VT); | 
 | 677 |     AllNodes.push_back(ValueTypeNodes[VT]); | 
 | 678 |   } | 
 | 679 |  | 
 | 680 |   return SDOperand(ValueTypeNodes[VT], 0); | 
 | 681 | } | 
 | 682 |  | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 683 | SDOperand SelectionDAG::getExternalSymbol(const char *Sym, MVT::ValueType VT) { | 
 | 684 |   SDNode *&N = ExternalSymbols[Sym]; | 
 | 685 |   if (N) return SDOperand(N, 0); | 
| Andrew Lenharth | 2a2de66 | 2005-10-23 03:40:17 +0000 | [diff] [blame] | 686 |   N = new ExternalSymbolSDNode(false, Sym, VT); | 
 | 687 |   AllNodes.push_back(N); | 
 | 688 |   return SDOperand(N, 0); | 
 | 689 | } | 
 | 690 |  | 
| Chris Lattner | 809ec11 | 2006-01-28 10:09:25 +0000 | [diff] [blame] | 691 | SDOperand SelectionDAG::getTargetExternalSymbol(const char *Sym, | 
 | 692 |                                                 MVT::ValueType VT) { | 
| Andrew Lenharth | 2a2de66 | 2005-10-23 03:40:17 +0000 | [diff] [blame] | 693 |   SDNode *&N = TargetExternalSymbols[Sym]; | 
 | 694 |   if (N) return SDOperand(N, 0); | 
 | 695 |   N = new ExternalSymbolSDNode(true, Sym, VT); | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 696 |   AllNodes.push_back(N); | 
 | 697 |   return SDOperand(N, 0); | 
 | 698 | } | 
 | 699 |  | 
| Chris Lattner | 7cf7e3f | 2005-08-09 20:20:18 +0000 | [diff] [blame] | 700 | SDOperand SelectionDAG::getCondCode(ISD::CondCode Cond) { | 
 | 701 |   if ((unsigned)Cond >= CondCodeNodes.size()) | 
 | 702 |     CondCodeNodes.resize(Cond+1); | 
 | 703 |    | 
| Chris Lattner | 079a27a | 2005-08-09 20:40:02 +0000 | [diff] [blame] | 704 |   if (CondCodeNodes[Cond] == 0) { | 
| Chris Lattner | 7cf7e3f | 2005-08-09 20:20:18 +0000 | [diff] [blame] | 705 |     CondCodeNodes[Cond] = new CondCodeSDNode(Cond); | 
| Chris Lattner | 079a27a | 2005-08-09 20:40:02 +0000 | [diff] [blame] | 706 |     AllNodes.push_back(CondCodeNodes[Cond]); | 
 | 707 |   } | 
| Chris Lattner | 7cf7e3f | 2005-08-09 20:20:18 +0000 | [diff] [blame] | 708 |   return SDOperand(CondCodeNodes[Cond], 0); | 
 | 709 | } | 
 | 710 |  | 
| Chris Lattner | 0fdd768 | 2005-08-30 22:38:38 +0000 | [diff] [blame] | 711 | SDOperand SelectionDAG::getRegister(unsigned RegNo, MVT::ValueType VT) { | 
 | 712 |   RegisterSDNode *&Reg = RegNodes[std::make_pair(RegNo, VT)]; | 
 | 713 |   if (!Reg) { | 
 | 714 |     Reg = new RegisterSDNode(RegNo, VT); | 
 | 715 |     AllNodes.push_back(Reg); | 
| Chris Lattner | d5d0f9b | 2005-08-16 21:55:35 +0000 | [diff] [blame] | 716 |   } | 
| Chris Lattner | 0fdd768 | 2005-08-30 22:38:38 +0000 | [diff] [blame] | 717 |   return SDOperand(Reg, 0); | 
| Chris Lattner | d5d0f9b | 2005-08-16 21:55:35 +0000 | [diff] [blame] | 718 | } | 
 | 719 |  | 
| Chris Lattner | bd8625b | 2005-08-09 23:09:05 +0000 | [diff] [blame] | 720 | SDOperand SelectionDAG::SimplifySetCC(MVT::ValueType VT, SDOperand N1, | 
 | 721 |                                       SDOperand N2, ISD::CondCode Cond) { | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 722 |   // These setcc operations always fold. | 
 | 723 |   switch (Cond) { | 
 | 724 |   default: break; | 
 | 725 |   case ISD::SETFALSE: | 
| Chris Lattner | f30b73b | 2005-01-18 02:52:03 +0000 | [diff] [blame] | 726 |   case ISD::SETFALSE2: return getConstant(0, VT); | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 727 |   case ISD::SETTRUE: | 
| Chris Lattner | f30b73b | 2005-01-18 02:52:03 +0000 | [diff] [blame] | 728 |   case ISD::SETTRUE2:  return getConstant(1, VT); | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 729 |   } | 
 | 730 |  | 
| Chris Lattner | 67255a1 | 2005-04-07 18:14:58 +0000 | [diff] [blame] | 731 |   if (ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2.Val)) { | 
 | 732 |     uint64_t C2 = N2C->getValue(); | 
 | 733 |     if (ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.Val)) { | 
 | 734 |       uint64_t C1 = N1C->getValue(); | 
| Misha Brukman | edf128a | 2005-04-21 22:36:52 +0000 | [diff] [blame] | 735 |  | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 736 |       // Sign extend the operands if required | 
 | 737 |       if (ISD::isSignedIntSetCC(Cond)) { | 
 | 738 |         C1 = N1C->getSignExtended(); | 
 | 739 |         C2 = N2C->getSignExtended(); | 
 | 740 |       } | 
 | 741 |  | 
 | 742 |       switch (Cond) { | 
 | 743 |       default: assert(0 && "Unknown integer setcc!"); | 
| Chris Lattner | f30b73b | 2005-01-18 02:52:03 +0000 | [diff] [blame] | 744 |       case ISD::SETEQ:  return getConstant(C1 == C2, VT); | 
 | 745 |       case ISD::SETNE:  return getConstant(C1 != C2, VT); | 
 | 746 |       case ISD::SETULT: return getConstant(C1 <  C2, VT); | 
 | 747 |       case ISD::SETUGT: return getConstant(C1 >  C2, VT); | 
 | 748 |       case ISD::SETULE: return getConstant(C1 <= C2, VT); | 
 | 749 |       case ISD::SETUGE: return getConstant(C1 >= C2, VT); | 
 | 750 |       case ISD::SETLT:  return getConstant((int64_t)C1 <  (int64_t)C2, VT); | 
 | 751 |       case ISD::SETGT:  return getConstant((int64_t)C1 >  (int64_t)C2, VT); | 
 | 752 |       case ISD::SETLE:  return getConstant((int64_t)C1 <= (int64_t)C2, VT); | 
 | 753 |       case ISD::SETGE:  return getConstant((int64_t)C1 >= (int64_t)C2, VT); | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 754 |       } | 
| Chris Lattner | 2467392 | 2005-04-07 18:58:54 +0000 | [diff] [blame] | 755 |     } else { | 
| Chris Lattner | 7b2880c | 2005-08-24 22:44:39 +0000 | [diff] [blame] | 756 |       // If the LHS is a ZERO_EXTEND, perform the comparison on the input. | 
| Chris Lattner | 4a44c8d | 2005-04-18 04:30:45 +0000 | [diff] [blame] | 757 |       if (N1.getOpcode() == ISD::ZERO_EXTEND) { | 
 | 758 |         unsigned InSize = MVT::getSizeInBits(N1.getOperand(0).getValueType()); | 
 | 759 |  | 
 | 760 |         // If the comparison constant has bits in the upper part, the | 
 | 761 |         // zero-extended value could never match. | 
 | 762 |         if (C2 & (~0ULL << InSize)) { | 
 | 763 |           unsigned VSize = MVT::getSizeInBits(N1.getValueType()); | 
 | 764 |           switch (Cond) { | 
 | 765 |           case ISD::SETUGT: | 
 | 766 |           case ISD::SETUGE: | 
 | 767 |           case ISD::SETEQ: return getConstant(0, VT); | 
 | 768 |           case ISD::SETULT: | 
 | 769 |           case ISD::SETULE: | 
 | 770 |           case ISD::SETNE: return getConstant(1, VT); | 
 | 771 |           case ISD::SETGT: | 
 | 772 |           case ISD::SETGE: | 
 | 773 |             // True if the sign bit of C2 is set. | 
 | 774 |             return getConstant((C2 & (1ULL << VSize)) != 0, VT); | 
 | 775 |           case ISD::SETLT: | 
 | 776 |           case ISD::SETLE: | 
 | 777 |             // True if the sign bit of C2 isn't set. | 
 | 778 |             return getConstant((C2 & (1ULL << VSize)) == 0, VT); | 
 | 779 |           default: | 
 | 780 |             break; | 
 | 781 |           } | 
 | 782 |         } | 
 | 783 |  | 
 | 784 |         // Otherwise, we can perform the comparison with the low bits. | 
 | 785 |         switch (Cond) { | 
 | 786 |         case ISD::SETEQ: | 
 | 787 |         case ISD::SETNE: | 
 | 788 |         case ISD::SETUGT: | 
 | 789 |         case ISD::SETUGE: | 
 | 790 |         case ISD::SETULT: | 
 | 791 |         case ISD::SETULE: | 
| Chris Lattner | 7cf7e3f | 2005-08-09 20:20:18 +0000 | [diff] [blame] | 792 |           return getSetCC(VT, N1.getOperand(0), | 
 | 793 |                           getConstant(C2, N1.getOperand(0).getValueType()), | 
 | 794 |                           Cond); | 
| Chris Lattner | 4a44c8d | 2005-04-18 04:30:45 +0000 | [diff] [blame] | 795 |         default: | 
 | 796 |           break;   // todo, be more careful with signed comparisons | 
 | 797 |         } | 
| Chris Lattner | 7b2880c | 2005-08-24 22:44:39 +0000 | [diff] [blame] | 798 |       } else if (N1.getOpcode() == ISD::SIGN_EXTEND_INREG && | 
 | 799 |                  (Cond == ISD::SETEQ || Cond == ISD::SETNE)) { | 
 | 800 |         MVT::ValueType ExtSrcTy = cast<VTSDNode>(N1.getOperand(1))->getVT(); | 
 | 801 |         unsigned ExtSrcTyBits = MVT::getSizeInBits(ExtSrcTy); | 
 | 802 |         MVT::ValueType ExtDstTy = N1.getValueType(); | 
 | 803 |         unsigned ExtDstTyBits = MVT::getSizeInBits(ExtDstTy); | 
| Nate Begeman | 56eb868 | 2005-08-30 02:44:00 +0000 | [diff] [blame] | 804 |  | 
| Chris Lattner | 7b2880c | 2005-08-24 22:44:39 +0000 | [diff] [blame] | 805 |         // If the extended part has any inconsistent bits, it cannot ever | 
 | 806 |         // compare equal.  In other words, they have to be all ones or all | 
 | 807 |         // zeros. | 
 | 808 |         uint64_t ExtBits = | 
| Jeff Cohen | 7383ce4 | 2005-08-31 02:47:06 +0000 | [diff] [blame] | 809 |           (~0ULL >> (64-ExtSrcTyBits)) & (~0ULL << (ExtDstTyBits-1)); | 
| Chris Lattner | 7b2880c | 2005-08-24 22:44:39 +0000 | [diff] [blame] | 810 |         if ((C2 & ExtBits) != 0 && (C2 & ExtBits) != ExtBits) | 
 | 811 |           return getConstant(Cond == ISD::SETNE, VT); | 
 | 812 |          | 
 | 813 |         // Otherwise, make this a use of a zext. | 
 | 814 |         return getSetCC(VT, getZeroExtendInReg(N1.getOperand(0), ExtSrcTy), | 
| Jeff Cohen | 7383ce4 | 2005-08-31 02:47:06 +0000 | [diff] [blame] | 815 |                         getConstant(C2 & (~0ULL>>(64-ExtSrcTyBits)), ExtDstTy), | 
| Chris Lattner | 7b2880c | 2005-08-24 22:44:39 +0000 | [diff] [blame] | 816 |                         Cond); | 
| Chris Lattner | 4a44c8d | 2005-04-18 04:30:45 +0000 | [diff] [blame] | 817 |       } | 
 | 818 |  | 
| Chris Lattner | 67255a1 | 2005-04-07 18:14:58 +0000 | [diff] [blame] | 819 |       uint64_t MinVal, MaxVal; | 
 | 820 |       unsigned OperandBitSize = MVT::getSizeInBits(N2C->getValueType(0)); | 
 | 821 |       if (ISD::isSignedIntSetCC(Cond)) { | 
 | 822 |         MinVal = 1ULL << (OperandBitSize-1); | 
 | 823 |         if (OperandBitSize != 1)   // Avoid X >> 64, which is undefined. | 
 | 824 |           MaxVal = ~0ULL >> (65-OperandBitSize); | 
 | 825 |         else | 
 | 826 |           MaxVal = 0; | 
 | 827 |       } else { | 
 | 828 |         MinVal = 0; | 
 | 829 |         MaxVal = ~0ULL >> (64-OperandBitSize); | 
 | 830 |       } | 
 | 831 |  | 
 | 832 |       // Canonicalize GE/LE comparisons to use GT/LT comparisons. | 
 | 833 |       if (Cond == ISD::SETGE || Cond == ISD::SETUGE) { | 
 | 834 |         if (C2 == MinVal) return getConstant(1, VT);   // X >= MIN --> true | 
 | 835 |         --C2;                                          // X >= C1 --> X > (C1-1) | 
| Chris Lattner | bd8625b | 2005-08-09 23:09:05 +0000 | [diff] [blame] | 836 |         return getSetCC(VT, N1, getConstant(C2, N2.getValueType()), | 
 | 837 |                         (Cond == ISD::SETGE) ? ISD::SETGT : ISD::SETUGT); | 
| Chris Lattner | 67255a1 | 2005-04-07 18:14:58 +0000 | [diff] [blame] | 838 |       } | 
 | 839 |  | 
 | 840 |       if (Cond == ISD::SETLE || Cond == ISD::SETULE) { | 
 | 841 |         if (C2 == MaxVal) return getConstant(1, VT);   // X <= MAX --> true | 
 | 842 |         ++C2;                                          // X <= C1 --> X < (C1+1) | 
| Chris Lattner | bd8625b | 2005-08-09 23:09:05 +0000 | [diff] [blame] | 843 |         return getSetCC(VT, N1, getConstant(C2, N2.getValueType()), | 
 | 844 |                         (Cond == ISD::SETLE) ? ISD::SETLT : ISD::SETULT); | 
| Chris Lattner | 67255a1 | 2005-04-07 18:14:58 +0000 | [diff] [blame] | 845 |       } | 
| Misha Brukman | edf128a | 2005-04-21 22:36:52 +0000 | [diff] [blame] | 846 |  | 
| Nate Begeman | 72ea281 | 2005-04-14 08:56:52 +0000 | [diff] [blame] | 847 |       if ((Cond == ISD::SETLT || Cond == ISD::SETULT) && C2 == MinVal) | 
 | 848 |         return getConstant(0, VT);      // X < MIN --> false | 
| Misha Brukman | edf128a | 2005-04-21 22:36:52 +0000 | [diff] [blame] | 849 |  | 
| Nate Begeman | 72ea281 | 2005-04-14 08:56:52 +0000 | [diff] [blame] | 850 |       // Canonicalize setgt X, Min --> setne X, Min | 
 | 851 |       if ((Cond == ISD::SETGT || Cond == ISD::SETUGT) && C2 == MinVal) | 
| Chris Lattner | 7cf7e3f | 2005-08-09 20:20:18 +0000 | [diff] [blame] | 852 |         return getSetCC(VT, N1, N2, ISD::SETNE); | 
| Misha Brukman | edf128a | 2005-04-21 22:36:52 +0000 | [diff] [blame] | 853 |  | 
| Chris Lattner | 3b2c1d9 | 2005-04-12 00:28:49 +0000 | [diff] [blame] | 854 |       // If we have setult X, 1, turn it into seteq X, 0 | 
 | 855 |       if ((Cond == ISD::SETLT || Cond == ISD::SETULT) && C2 == MinVal+1) | 
| Chris Lattner | 7cf7e3f | 2005-08-09 20:20:18 +0000 | [diff] [blame] | 856 |         return getSetCC(VT, N1, getConstant(MinVal, N1.getValueType()), | 
 | 857 |                         ISD::SETEQ); | 
| Nate Begeman | 72ea281 | 2005-04-14 08:56:52 +0000 | [diff] [blame] | 858 |       // If we have setugt X, Max-1, turn it into seteq X, Max | 
| Chris Lattner | 3b2c1d9 | 2005-04-12 00:28:49 +0000 | [diff] [blame] | 859 |       else if ((Cond == ISD::SETGT || Cond == ISD::SETUGT) && C2 == MaxVal-1) | 
| Chris Lattner | 7cf7e3f | 2005-08-09 20:20:18 +0000 | [diff] [blame] | 860 |         return getSetCC(VT, N1, getConstant(MaxVal, N1.getValueType()), | 
 | 861 |                         ISD::SETEQ); | 
| Chris Lattner | 67255a1 | 2005-04-07 18:14:58 +0000 | [diff] [blame] | 862 |  | 
 | 863 |       // If we have "setcc X, C1", check to see if we can shrink the immediate | 
 | 864 |       // by changing cc. | 
 | 865 |  | 
 | 866 |       // SETUGT X, SINTMAX  -> SETLT X, 0 | 
 | 867 |       if (Cond == ISD::SETUGT && OperandBitSize != 1 && | 
 | 868 |           C2 == (~0ULL >> (65-OperandBitSize))) | 
| Chris Lattner | 7cf7e3f | 2005-08-09 20:20:18 +0000 | [diff] [blame] | 869 |         return getSetCC(VT, N1, getConstant(0, N2.getValueType()), ISD::SETLT); | 
| Chris Lattner | 67255a1 | 2005-04-07 18:14:58 +0000 | [diff] [blame] | 870 |  | 
 | 871 |       // FIXME: Implement the rest of these. | 
 | 872 |  | 
| Chris Lattner | 1c2a9b9 | 2005-04-21 06:12:41 +0000 | [diff] [blame] | 873 |  | 
 | 874 |       // Fold bit comparisons when we can. | 
 | 875 |       if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) && | 
 | 876 |           VT == N1.getValueType() && N1.getOpcode() == ISD::AND) | 
 | 877 |         if (ConstantSDNode *AndRHS = | 
 | 878 |                     dyn_cast<ConstantSDNode>(N1.getOperand(1))) { | 
 | 879 |           if (Cond == ISD::SETNE && C2 == 0) {// (X & 8) != 0  -->  (X & 8) >> 3 | 
 | 880 |             // Perform the xform if the AND RHS is a single bit. | 
 | 881 |             if ((AndRHS->getValue() & (AndRHS->getValue()-1)) == 0) { | 
 | 882 |               return getNode(ISD::SRL, VT, N1, | 
| Chris Lattner | 0561b3f | 2005-08-02 19:26:06 +0000 | [diff] [blame] | 883 |                              getConstant(Log2_64(AndRHS->getValue()), | 
| Chris Lattner | 1c2a9b9 | 2005-04-21 06:12:41 +0000 | [diff] [blame] | 884 |                                                    TLI.getShiftAmountTy())); | 
 | 885 |             } | 
 | 886 |           } else if (Cond == ISD::SETEQ && C2 == AndRHS->getValue()) { | 
 | 887 |             // (X & 8) == 8  -->  (X & 8) >> 3 | 
 | 888 |             // Perform the xform if C2 is a single bit. | 
 | 889 |             if ((C2 & (C2-1)) == 0) { | 
 | 890 |               return getNode(ISD::SRL, VT, N1, | 
| Chris Lattner | 0561b3f | 2005-08-02 19:26:06 +0000 | [diff] [blame] | 891 |                              getConstant(Log2_64(C2),TLI.getShiftAmountTy())); | 
| Chris Lattner | 1c2a9b9 | 2005-04-21 06:12:41 +0000 | [diff] [blame] | 892 |             } | 
 | 893 |           } | 
 | 894 |         } | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 895 |     } | 
| Chris Lattner | 67255a1 | 2005-04-07 18:14:58 +0000 | [diff] [blame] | 896 |   } else if (isa<ConstantSDNode>(N1.Val)) { | 
 | 897 |       // Ensure that the constant occurs on the RHS. | 
| Chris Lattner | 7cf7e3f | 2005-08-09 20:20:18 +0000 | [diff] [blame] | 898 |     return getSetCC(VT, N2, N1, ISD::getSetCCSwappedOperands(Cond)); | 
| Chris Lattner | 67255a1 | 2005-04-07 18:14:58 +0000 | [diff] [blame] | 899 |   } | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 900 |  | 
 | 901 |   if (ConstantFPSDNode *N1C = dyn_cast<ConstantFPSDNode>(N1.Val)) | 
 | 902 |     if (ConstantFPSDNode *N2C = dyn_cast<ConstantFPSDNode>(N2.Val)) { | 
 | 903 |       double C1 = N1C->getValue(), C2 = N2C->getValue(); | 
| Misha Brukman | edf128a | 2005-04-21 22:36:52 +0000 | [diff] [blame] | 904 |  | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 905 |       switch (Cond) { | 
 | 906 |       default: break; // FIXME: Implement the rest of these! | 
| Chris Lattner | f30b73b | 2005-01-18 02:52:03 +0000 | [diff] [blame] | 907 |       case ISD::SETEQ:  return getConstant(C1 == C2, VT); | 
 | 908 |       case ISD::SETNE:  return getConstant(C1 != C2, VT); | 
 | 909 |       case ISD::SETLT:  return getConstant(C1 < C2, VT); | 
 | 910 |       case ISD::SETGT:  return getConstant(C1 > C2, VT); | 
 | 911 |       case ISD::SETLE:  return getConstant(C1 <= C2, VT); | 
 | 912 |       case ISD::SETGE:  return getConstant(C1 >= C2, VT); | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 913 |       } | 
 | 914 |     } else { | 
 | 915 |       // Ensure that the constant occurs on the RHS. | 
| Chris Lattner | bd8625b | 2005-08-09 23:09:05 +0000 | [diff] [blame] | 916 |       return getSetCC(VT, N2, N1, ISD::getSetCCSwappedOperands(Cond)); | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 917 |     } | 
 | 918 |  | 
| Chris Lattner | 7cf7e3f | 2005-08-09 20:20:18 +0000 | [diff] [blame] | 919 |   // Could not fold it. | 
 | 920 |   return SDOperand(); | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 921 | } | 
 | 922 |  | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 923 | /// getNode - Gets or creates the specified node. | 
| Chris Lattner | 78ec311 | 2003-08-11 14:57:33 +0000 | [diff] [blame] | 924 | /// | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 925 | SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT) { | 
| Chris Lattner | 70b9b10 | 2005-09-02 19:36:17 +0000 | [diff] [blame] | 926 |   SDNode *&N = NullaryOps[std::make_pair(Opcode, VT)]; | 
 | 927 |   if (!N) { | 
 | 928 |     N = new SDNode(Opcode, VT); | 
 | 929 |     AllNodes.push_back(N); | 
 | 930 |   } | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 931 |   return SDOperand(N, 0); | 
 | 932 | } | 
 | 933 |  | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 934 | SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, | 
 | 935 |                                 SDOperand Operand) { | 
| Nate Begeman | 1b5db7a | 2006-01-16 08:07:10 +0000 | [diff] [blame] | 936 |   unsigned Tmp1; | 
| Chris Lattner | 9468377 | 2005-12-23 05:30:37 +0000 | [diff] [blame] | 937 |   // Constant fold unary operations with an integer constant operand. | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 938 |   if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Operand.Val)) { | 
 | 939 |     uint64_t Val = C->getValue(); | 
 | 940 |     switch (Opcode) { | 
 | 941 |     default: break; | 
 | 942 |     case ISD::SIGN_EXTEND: return getConstant(C->getSignExtended(), VT); | 
| Chris Lattner | 4ed11b4 | 2005-09-02 00:17:32 +0000 | [diff] [blame] | 943 |     case ISD::ANY_EXTEND: | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 944 |     case ISD::ZERO_EXTEND: return getConstant(Val, VT); | 
 | 945 |     case ISD::TRUNCATE:    return getConstant(Val, VT); | 
| Chris Lattner | ae0aacb | 2005-01-08 08:08:56 +0000 | [diff] [blame] | 946 |     case ISD::SINT_TO_FP:  return getConstantFP(C->getSignExtended(), VT); | 
 | 947 |     case ISD::UINT_TO_FP:  return getConstantFP(C->getValue(), VT); | 
| Chris Lattner | 9468377 | 2005-12-23 05:30:37 +0000 | [diff] [blame] | 948 |     case ISD::BIT_CONVERT: | 
 | 949 |       if (VT == MVT::f32) { | 
 | 950 |         assert(C->getValueType(0) == MVT::i32 && "Invalid bit_convert!"); | 
 | 951 |         return getConstantFP(BitsToFloat(Val), VT); | 
 | 952 |       } else if (VT == MVT::f64) { | 
 | 953 |         assert(C->getValueType(0) == MVT::i64 && "Invalid bit_convert!"); | 
 | 954 |         return getConstantFP(BitsToDouble(Val), VT); | 
 | 955 |       } | 
 | 956 |       break; | 
| Nate Begeman | 1b5db7a | 2006-01-16 08:07:10 +0000 | [diff] [blame] | 957 |     case ISD::BSWAP: | 
 | 958 |       switch(VT) { | 
 | 959 |       default: assert(0 && "Invalid bswap!"); break; | 
 | 960 |       case MVT::i16: return getConstant(ByteSwap_16((unsigned short)Val), VT); | 
 | 961 |       case MVT::i32: return getConstant(ByteSwap_32((unsigned)Val), VT); | 
 | 962 |       case MVT::i64: return getConstant(ByteSwap_64(Val), VT); | 
 | 963 |       } | 
 | 964 |       break; | 
 | 965 |     case ISD::CTPOP: | 
 | 966 |       switch(VT) { | 
 | 967 |       default: assert(0 && "Invalid ctpop!"); break; | 
 | 968 |       case MVT::i1: return getConstant(Val != 0, VT); | 
 | 969 |       case MVT::i8:  | 
 | 970 |         Tmp1 = (unsigned)Val & 0xFF; | 
 | 971 |         return getConstant(CountPopulation_32(Tmp1), VT); | 
 | 972 |       case MVT::i16: | 
 | 973 |         Tmp1 = (unsigned)Val & 0xFFFF; | 
 | 974 |         return getConstant(CountPopulation_32(Tmp1), VT); | 
 | 975 |       case MVT::i32: | 
 | 976 |         return getConstant(CountPopulation_32((unsigned)Val), VT); | 
 | 977 |       case MVT::i64: | 
 | 978 |         return getConstant(CountPopulation_64(Val), VT); | 
 | 979 |       } | 
 | 980 |     case ISD::CTLZ: | 
 | 981 |       switch(VT) { | 
 | 982 |       default: assert(0 && "Invalid ctlz!"); break; | 
 | 983 |       case MVT::i1: return getConstant(Val == 0, VT); | 
 | 984 |       case MVT::i8:  | 
 | 985 |         Tmp1 = (unsigned)Val & 0xFF; | 
 | 986 |         return getConstant(CountLeadingZeros_32(Tmp1)-24, VT); | 
 | 987 |       case MVT::i16: | 
 | 988 |         Tmp1 = (unsigned)Val & 0xFFFF; | 
 | 989 |         return getConstant(CountLeadingZeros_32(Tmp1)-16, VT); | 
 | 990 |       case MVT::i32: | 
 | 991 |         return getConstant(CountLeadingZeros_32((unsigned)Val), VT); | 
 | 992 |       case MVT::i64: | 
 | 993 |         return getConstant(CountLeadingZeros_64(Val), VT); | 
 | 994 |       } | 
 | 995 |     case ISD::CTTZ: | 
 | 996 |       switch(VT) { | 
 | 997 |       default: assert(0 && "Invalid cttz!"); break; | 
 | 998 |       case MVT::i1: return getConstant(Val == 0, VT); | 
 | 999 |       case MVT::i8:  | 
 | 1000 |         Tmp1 = (unsigned)Val | 0x100; | 
 | 1001 |         return getConstant(CountTrailingZeros_32(Tmp1), VT); | 
 | 1002 |       case MVT::i16: | 
 | 1003 |         Tmp1 = (unsigned)Val | 0x10000; | 
 | 1004 |         return getConstant(CountTrailingZeros_32(Tmp1), VT); | 
 | 1005 |       case MVT::i32: | 
 | 1006 |         return getConstant(CountTrailingZeros_32((unsigned)Val), VT); | 
 | 1007 |       case MVT::i64: | 
 | 1008 |         return getConstant(CountTrailingZeros_64(Val), VT); | 
 | 1009 |       } | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 1010 |     } | 
 | 1011 |   } | 
 | 1012 |  | 
| Chris Lattner | 9468377 | 2005-12-23 05:30:37 +0000 | [diff] [blame] | 1013 |   // Constant fold unary operations with an floating point constant operand. | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 1014 |   if (ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(Operand.Val)) | 
 | 1015 |     switch (Opcode) { | 
| Chris Lattner | 485df9b | 2005-04-09 03:02:46 +0000 | [diff] [blame] | 1016 |     case ISD::FNEG: | 
 | 1017 |       return getConstantFP(-C->getValue(), VT); | 
| Chris Lattner | 9468377 | 2005-12-23 05:30:37 +0000 | [diff] [blame] | 1018 |     case ISD::FABS: | 
 | 1019 |       return getConstantFP(fabs(C->getValue()), VT); | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 1020 |     case ISD::FP_ROUND: | 
 | 1021 |     case ISD::FP_EXTEND: | 
 | 1022 |       return getConstantFP(C->getValue(), VT); | 
| Chris Lattner | ae0aacb | 2005-01-08 08:08:56 +0000 | [diff] [blame] | 1023 |     case ISD::FP_TO_SINT: | 
 | 1024 |       return getConstant((int64_t)C->getValue(), VT); | 
 | 1025 |     case ISD::FP_TO_UINT: | 
 | 1026 |       return getConstant((uint64_t)C->getValue(), VT); | 
| Chris Lattner | 9468377 | 2005-12-23 05:30:37 +0000 | [diff] [blame] | 1027 |     case ISD::BIT_CONVERT: | 
 | 1028 |       if (VT == MVT::i32) { | 
 | 1029 |         assert(C->getValueType(0) == MVT::f32 && "Invalid bit_convert!"); | 
 | 1030 |         return getConstant(FloatToBits(C->getValue()), VT); | 
 | 1031 |       } else if (VT == MVT::i64) { | 
 | 1032 |         assert(C->getValueType(0) == MVT::f64 && "Invalid bit_convert!"); | 
 | 1033 |         return getConstant(DoubleToBits(C->getValue()), VT); | 
 | 1034 |       } | 
 | 1035 |       break; | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 1036 |     } | 
 | 1037 |  | 
 | 1038 |   unsigned OpOpcode = Operand.Val->getOpcode(); | 
 | 1039 |   switch (Opcode) { | 
| Chris Lattner | a93ec3e | 2005-01-21 18:01:22 +0000 | [diff] [blame] | 1040 |   case ISD::TokenFactor: | 
 | 1041 |     return Operand;         // Factor of one node?  No factor. | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 1042 |   case ISD::SIGN_EXTEND: | 
 | 1043 |     if (Operand.getValueType() == VT) return Operand;   // noop extension | 
 | 1044 |     if (OpOpcode == ISD::SIGN_EXTEND || OpOpcode == ISD::ZERO_EXTEND) | 
 | 1045 |       return getNode(OpOpcode, VT, Operand.Val->getOperand(0)); | 
 | 1046 |     break; | 
 | 1047 |   case ISD::ZERO_EXTEND: | 
 | 1048 |     if (Operand.getValueType() == VT) return Operand;   // noop extension | 
| Chris Lattner | 5a6bace | 2005-04-07 19:43:53 +0000 | [diff] [blame] | 1049 |     if (OpOpcode == ISD::ZERO_EXTEND)   // (zext (zext x)) -> (zext x) | 
| Chris Lattner | 2f0ca79 | 2005-01-12 18:51:15 +0000 | [diff] [blame] | 1050 |       return getNode(ISD::ZERO_EXTEND, VT, Operand.Val->getOperand(0)); | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 1051 |     break; | 
| Chris Lattner | 4ed11b4 | 2005-09-02 00:17:32 +0000 | [diff] [blame] | 1052 |   case ISD::ANY_EXTEND: | 
 | 1053 |     if (Operand.getValueType() == VT) return Operand;   // noop extension | 
 | 1054 |     if (OpOpcode == ISD::ZERO_EXTEND || OpOpcode == ISD::SIGN_EXTEND) | 
 | 1055 |       // (ext (zext x)) -> (zext x)  and  (ext (sext x)) -> (sext x) | 
 | 1056 |       return getNode(OpOpcode, VT, Operand.Val->getOperand(0)); | 
 | 1057 |     break; | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 1058 |   case ISD::TRUNCATE: | 
 | 1059 |     if (Operand.getValueType() == VT) return Operand;   // noop truncate | 
 | 1060 |     if (OpOpcode == ISD::TRUNCATE) | 
 | 1061 |       return getNode(ISD::TRUNCATE, VT, Operand.Val->getOperand(0)); | 
| Chris Lattner | 4ed11b4 | 2005-09-02 00:17:32 +0000 | [diff] [blame] | 1062 |     else if (OpOpcode == ISD::ZERO_EXTEND || OpOpcode == ISD::SIGN_EXTEND || | 
 | 1063 |              OpOpcode == ISD::ANY_EXTEND) { | 
| Chris Lattner | fd8c39b | 2005-01-07 21:56:24 +0000 | [diff] [blame] | 1064 |       // If the source is smaller than the dest, we still need an extend. | 
 | 1065 |       if (Operand.Val->getOperand(0).getValueType() < VT) | 
 | 1066 |         return getNode(OpOpcode, VT, Operand.Val->getOperand(0)); | 
 | 1067 |       else if (Operand.Val->getOperand(0).getValueType() > VT) | 
 | 1068 |         return getNode(ISD::TRUNCATE, VT, Operand.Val->getOperand(0)); | 
 | 1069 |       else | 
 | 1070 |         return Operand.Val->getOperand(0); | 
 | 1071 |     } | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 1072 |     break; | 
| Chris Lattner | 3548189 | 2005-12-23 00:16:34 +0000 | [diff] [blame] | 1073 |   case ISD::BIT_CONVERT: | 
 | 1074 |     // Basic sanity checking. | 
 | 1075 |     assert(MVT::getSizeInBits(VT)==MVT::getSizeInBits(Operand.getValueType()) && | 
 | 1076 |            "Cannot BIT_CONVERT between two different types!"); | 
 | 1077 |     if (VT == Operand.getValueType()) return Operand;  // noop conversion. | 
| Chris Lattner | c8547d8 | 2005-12-23 05:37:50 +0000 | [diff] [blame] | 1078 |     if (OpOpcode == ISD::BIT_CONVERT)  // bitconv(bitconv(x)) -> bitconv(x) | 
 | 1079 |       return getNode(ISD::BIT_CONVERT, VT, Operand.getOperand(0)); | 
| Chris Lattner | 3548189 | 2005-12-23 00:16:34 +0000 | [diff] [blame] | 1080 |     break; | 
| Chris Lattner | 485df9b | 2005-04-09 03:02:46 +0000 | [diff] [blame] | 1081 |   case ISD::FNEG: | 
| Chris Lattner | 01b3d73 | 2005-09-28 22:28:18 +0000 | [diff] [blame] | 1082 |     if (OpOpcode == ISD::FSUB)   // -(X-Y) -> (Y-X) | 
 | 1083 |       return getNode(ISD::FSUB, VT, Operand.Val->getOperand(1), | 
| Chris Lattner | 485df9b | 2005-04-09 03:02:46 +0000 | [diff] [blame] | 1084 |                      Operand.Val->getOperand(0)); | 
 | 1085 |     if (OpOpcode == ISD::FNEG)  // --X -> X | 
 | 1086 |       return Operand.Val->getOperand(0); | 
 | 1087 |     break; | 
 | 1088 |   case ISD::FABS: | 
 | 1089 |     if (OpOpcode == ISD::FNEG)  // abs(-X) -> abs(X) | 
 | 1090 |       return getNode(ISD::FABS, VT, Operand.Val->getOperand(0)); | 
 | 1091 |     break; | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 1092 |   } | 
 | 1093 |  | 
| Chris Lattner | 43247a1 | 2005-08-25 19:12:10 +0000 | [diff] [blame] | 1094 |   SDNode *N; | 
 | 1095 |   if (VT != MVT::Flag) { // Don't CSE flag producing nodes | 
 | 1096 |     SDNode *&E = UnaryOps[std::make_pair(Opcode, std::make_pair(Operand, VT))]; | 
| Chris Lattner | f07d023 | 2005-08-26 00:13:12 +0000 | [diff] [blame] | 1097 |     if (E) return SDOperand(E, 0); | 
| Chris Lattner | 43247a1 | 2005-08-25 19:12:10 +0000 | [diff] [blame] | 1098 |     E = N = new SDNode(Opcode, Operand); | 
 | 1099 |   } else { | 
 | 1100 |     N = new SDNode(Opcode, Operand); | 
 | 1101 |   } | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 1102 |   N->setValueTypes(VT); | 
 | 1103 |   AllNodes.push_back(N); | 
 | 1104 |   return SDOperand(N, 0); | 
| Chris Lattner | 78ec311 | 2003-08-11 14:57:33 +0000 | [diff] [blame] | 1105 | } | 
 | 1106 |  | 
| Chris Lattner | 36019aa | 2005-04-18 03:48:41 +0000 | [diff] [blame] | 1107 |  | 
 | 1108 |  | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 1109 | SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, | 
 | 1110 |                                 SDOperand N1, SDOperand N2) { | 
| Chris Lattner | 7636512 | 2005-01-16 02:23:22 +0000 | [diff] [blame] | 1111 | #ifndef NDEBUG | 
 | 1112 |   switch (Opcode) { | 
| Chris Lattner | 39908e0 | 2005-01-19 18:01:40 +0000 | [diff] [blame] | 1113 |   case ISD::TokenFactor: | 
 | 1114 |     assert(VT == MVT::Other && N1.getValueType() == MVT::Other && | 
 | 1115 |            N2.getValueType() == MVT::Other && "Invalid token factor!"); | 
 | 1116 |     break; | 
| Chris Lattner | 7636512 | 2005-01-16 02:23:22 +0000 | [diff] [blame] | 1117 |   case ISD::AND: | 
 | 1118 |   case ISD::OR: | 
 | 1119 |   case ISD::XOR: | 
 | 1120 |   case ISD::UDIV: | 
 | 1121 |   case ISD::UREM: | 
| Chris Lattner | e5eb6f8 | 2005-05-15 05:39:08 +0000 | [diff] [blame] | 1122 |   case ISD::MULHU: | 
 | 1123 |   case ISD::MULHS: | 
| Chris Lattner | 7636512 | 2005-01-16 02:23:22 +0000 | [diff] [blame] | 1124 |     assert(MVT::isInteger(VT) && "This operator does not apply to FP types!"); | 
 | 1125 |     // fall through | 
 | 1126 |   case ISD::ADD: | 
 | 1127 |   case ISD::SUB: | 
 | 1128 |   case ISD::MUL: | 
 | 1129 |   case ISD::SDIV: | 
 | 1130 |   case ISD::SREM: | 
| Chris Lattner | 01b3d73 | 2005-09-28 22:28:18 +0000 | [diff] [blame] | 1131 |     assert(MVT::isInteger(N1.getValueType()) && "Should use F* for FP ops"); | 
 | 1132 |     // fall through. | 
 | 1133 |   case ISD::FADD: | 
 | 1134 |   case ISD::FSUB: | 
 | 1135 |   case ISD::FMUL: | 
 | 1136 |   case ISD::FDIV: | 
 | 1137 |   case ISD::FREM: | 
| Chris Lattner | 7636512 | 2005-01-16 02:23:22 +0000 | [diff] [blame] | 1138 |     assert(N1.getValueType() == N2.getValueType() && | 
 | 1139 |            N1.getValueType() == VT && "Binary operator types must match!"); | 
 | 1140 |     break; | 
 | 1141 |  | 
 | 1142 |   case ISD::SHL: | 
 | 1143 |   case ISD::SRA: | 
 | 1144 |   case ISD::SRL: | 
| Nate Begeman | 35ef913 | 2006-01-11 21:21:00 +0000 | [diff] [blame] | 1145 |   case ISD::ROTL: | 
 | 1146 |   case ISD::ROTR: | 
| Chris Lattner | 7636512 | 2005-01-16 02:23:22 +0000 | [diff] [blame] | 1147 |     assert(VT == N1.getValueType() && | 
 | 1148 |            "Shift operators return type must be the same as their first arg"); | 
 | 1149 |     assert(MVT::isInteger(VT) && MVT::isInteger(N2.getValueType()) && | 
| Chris Lattner | 068a81e | 2005-01-17 17:15:02 +0000 | [diff] [blame] | 1150 |            VT != MVT::i1 && "Shifts only work on integers"); | 
| Chris Lattner | 7636512 | 2005-01-16 02:23:22 +0000 | [diff] [blame] | 1151 |     break; | 
| Chris Lattner | 15e4b01 | 2005-07-10 00:07:11 +0000 | [diff] [blame] | 1152 |   case ISD::FP_ROUND_INREG: { | 
 | 1153 |     MVT::ValueType EVT = cast<VTSDNode>(N2)->getVT(); | 
 | 1154 |     assert(VT == N1.getValueType() && "Not an inreg round!"); | 
 | 1155 |     assert(MVT::isFloatingPoint(VT) && MVT::isFloatingPoint(EVT) && | 
 | 1156 |            "Cannot FP_ROUND_INREG integer types"); | 
 | 1157 |     assert(EVT <= VT && "Not rounding down!"); | 
 | 1158 |     break; | 
 | 1159 |   } | 
| Nate Begeman | 56eb868 | 2005-08-30 02:44:00 +0000 | [diff] [blame] | 1160 |   case ISD::AssertSext: | 
 | 1161 |   case ISD::AssertZext: | 
| Chris Lattner | 15e4b01 | 2005-07-10 00:07:11 +0000 | [diff] [blame] | 1162 |   case ISD::SIGN_EXTEND_INREG: { | 
 | 1163 |     MVT::ValueType EVT = cast<VTSDNode>(N2)->getVT(); | 
 | 1164 |     assert(VT == N1.getValueType() && "Not an inreg extend!"); | 
 | 1165 |     assert(MVT::isInteger(VT) && MVT::isInteger(EVT) && | 
 | 1166 |            "Cannot *_EXTEND_INREG FP types"); | 
 | 1167 |     assert(EVT <= VT && "Not extending!"); | 
 | 1168 |   } | 
 | 1169 |  | 
| Chris Lattner | 7636512 | 2005-01-16 02:23:22 +0000 | [diff] [blame] | 1170 |   default: break; | 
 | 1171 |   } | 
 | 1172 | #endif | 
 | 1173 |  | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 1174 |   ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.Val); | 
 | 1175 |   ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2.Val); | 
 | 1176 |   if (N1C) { | 
 | 1177 |     if (N2C) { | 
 | 1178 |       uint64_t C1 = N1C->getValue(), C2 = N2C->getValue(); | 
 | 1179 |       switch (Opcode) { | 
 | 1180 |       case ISD::ADD: return getConstant(C1 + C2, VT); | 
 | 1181 |       case ISD::SUB: return getConstant(C1 - C2, VT); | 
 | 1182 |       case ISD::MUL: return getConstant(C1 * C2, VT); | 
 | 1183 |       case ISD::UDIV: | 
 | 1184 |         if (C2) return getConstant(C1 / C2, VT); | 
 | 1185 |         break; | 
 | 1186 |       case ISD::UREM : | 
 | 1187 |         if (C2) return getConstant(C1 % C2, VT); | 
 | 1188 |         break; | 
 | 1189 |       case ISD::SDIV : | 
 | 1190 |         if (C2) return getConstant(N1C->getSignExtended() / | 
 | 1191 |                                    N2C->getSignExtended(), VT); | 
 | 1192 |         break; | 
 | 1193 |       case ISD::SREM : | 
 | 1194 |         if (C2) return getConstant(N1C->getSignExtended() % | 
 | 1195 |                                    N2C->getSignExtended(), VT); | 
 | 1196 |         break; | 
 | 1197 |       case ISD::AND  : return getConstant(C1 & C2, VT); | 
 | 1198 |       case ISD::OR   : return getConstant(C1 | C2, VT); | 
 | 1199 |       case ISD::XOR  : return getConstant(C1 ^ C2, VT); | 
| Nate Begeman | b85dfab | 2005-08-31 00:27:53 +0000 | [diff] [blame] | 1200 |       case ISD::SHL  : return getConstant(C1 << C2, VT); | 
 | 1201 |       case ISD::SRL  : return getConstant(C1 >> C2, VT); | 
| Chris Lattner | 8136d1f | 2005-01-10 00:07:15 +0000 | [diff] [blame] | 1202 |       case ISD::SRA  : return getConstant(N1C->getSignExtended() >>(int)C2, VT); | 
| Nate Begeman | 35ef913 | 2006-01-11 21:21:00 +0000 | [diff] [blame] | 1203 |       case ISD::ROTL :  | 
 | 1204 |         return getConstant((C1 << C2) | (C1 >> (MVT::getSizeInBits(VT) - C2)), | 
 | 1205 |                            VT); | 
 | 1206 |       case ISD::ROTR :  | 
 | 1207 |         return getConstant((C1 >> C2) | (C1 << (MVT::getSizeInBits(VT) - C2)),  | 
 | 1208 |                            VT); | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 1209 |       default: break; | 
 | 1210 |       } | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 1211 |     } else {      // Cannonicalize constant to RHS if commutative | 
 | 1212 |       if (isCommutativeBinOp(Opcode)) { | 
 | 1213 |         std::swap(N1C, N2C); | 
 | 1214 |         std::swap(N1, N2); | 
 | 1215 |       } | 
 | 1216 |     } | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 1217 |   } | 
 | 1218 |  | 
 | 1219 |   ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N1.Val); | 
 | 1220 |   ConstantFPSDNode *N2CFP = dyn_cast<ConstantFPSDNode>(N2.Val); | 
| Chris Lattner | 15e4b01 | 2005-07-10 00:07:11 +0000 | [diff] [blame] | 1221 |   if (N1CFP) { | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 1222 |     if (N2CFP) { | 
 | 1223 |       double C1 = N1CFP->getValue(), C2 = N2CFP->getValue(); | 
 | 1224 |       switch (Opcode) { | 
| Chris Lattner | 01b3d73 | 2005-09-28 22:28:18 +0000 | [diff] [blame] | 1225 |       case ISD::FADD: return getConstantFP(C1 + C2, VT); | 
 | 1226 |       case ISD::FSUB: return getConstantFP(C1 - C2, VT); | 
 | 1227 |       case ISD::FMUL: return getConstantFP(C1 * C2, VT); | 
 | 1228 |       case ISD::FDIV: | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 1229 |         if (C2) return getConstantFP(C1 / C2, VT); | 
 | 1230 |         break; | 
| Chris Lattner | 01b3d73 | 2005-09-28 22:28:18 +0000 | [diff] [blame] | 1231 |       case ISD::FREM : | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 1232 |         if (C2) return getConstantFP(fmod(C1, C2), VT); | 
 | 1233 |         break; | 
 | 1234 |       default: break; | 
 | 1235 |       } | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 1236 |     } else {      // Cannonicalize constant to RHS if commutative | 
 | 1237 |       if (isCommutativeBinOp(Opcode)) { | 
 | 1238 |         std::swap(N1CFP, N2CFP); | 
 | 1239 |         std::swap(N1, N2); | 
 | 1240 |       } | 
 | 1241 |     } | 
| Chris Lattner | 15e4b01 | 2005-07-10 00:07:11 +0000 | [diff] [blame] | 1242 |   } | 
 | 1243 |  | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 1244 |   // Finally, fold operations that do not require constants. | 
 | 1245 |   switch (Opcode) { | 
| Chris Lattner | 15e4b01 | 2005-07-10 00:07:11 +0000 | [diff] [blame] | 1246 |   case ISD::FP_ROUND_INREG: | 
 | 1247 |     if (cast<VTSDNode>(N2)->getVT() == VT) return N1;  // Not actually rounding. | 
 | 1248 |     break; | 
 | 1249 |   case ISD::SIGN_EXTEND_INREG: { | 
 | 1250 |     MVT::ValueType EVT = cast<VTSDNode>(N2)->getVT(); | 
 | 1251 |     if (EVT == VT) return N1;  // Not actually extending | 
| Chris Lattner | 15e4b01 | 2005-07-10 00:07:11 +0000 | [diff] [blame] | 1252 |     break; | 
 | 1253 |   } | 
 | 1254 |  | 
| Nate Begeman | eea805e | 2005-04-13 21:23:31 +0000 | [diff] [blame] | 1255 |   // FIXME: figure out how to safely handle things like | 
 | 1256 |   // int foo(int x) { return 1 << (x & 255); } | 
 | 1257 |   // int bar() { return foo(256); } | 
 | 1258 | #if 0 | 
| Nate Begeman | db81eba | 2005-04-12 23:32:28 +0000 | [diff] [blame] | 1259 |   case ISD::SHL: | 
 | 1260 |   case ISD::SRL: | 
 | 1261 |   case ISD::SRA: | 
| Chris Lattner | e666fcf | 2005-04-13 02:58:13 +0000 | [diff] [blame] | 1262 |     if (N2.getOpcode() == ISD::SIGN_EXTEND_INREG && | 
| Chris Lattner | 15e4b01 | 2005-07-10 00:07:11 +0000 | [diff] [blame] | 1263 |         cast<VTSDNode>(N2.getOperand(1))->getVT() != MVT::i1) | 
| Nate Begeman | db81eba | 2005-04-12 23:32:28 +0000 | [diff] [blame] | 1264 |       return getNode(Opcode, VT, N1, N2.getOperand(0)); | 
| Chris Lattner | e666fcf | 2005-04-13 02:58:13 +0000 | [diff] [blame] | 1265 |     else if (N2.getOpcode() == ISD::AND) | 
 | 1266 |       if (ConstantSDNode *AndRHS = dyn_cast<ConstantSDNode>(N2.getOperand(1))) { | 
 | 1267 |         // If the and is only masking out bits that cannot effect the shift, | 
 | 1268 |         // eliminate the and. | 
 | 1269 |         unsigned NumBits = MVT::getSizeInBits(VT); | 
 | 1270 |         if ((AndRHS->getValue() & (NumBits-1)) == NumBits-1) | 
 | 1271 |           return getNode(Opcode, VT, N1, N2.getOperand(0)); | 
 | 1272 |       } | 
| Nate Begeman | db81eba | 2005-04-12 23:32:28 +0000 | [diff] [blame] | 1273 |     break; | 
| Nate Begeman | eea805e | 2005-04-13 21:23:31 +0000 | [diff] [blame] | 1274 | #endif | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 1275 |   } | 
 | 1276 |  | 
| Chris Lattner | 27e9b41 | 2005-05-11 18:57:39 +0000 | [diff] [blame] | 1277 |   // Memoize this node if possible. | 
 | 1278 |   SDNode *N; | 
| Chris Lattner | 43247a1 | 2005-08-25 19:12:10 +0000 | [diff] [blame] | 1279 |   if (Opcode != ISD::CALLSEQ_START && Opcode != ISD::CALLSEQ_END && | 
 | 1280 |       VT != MVT::Flag) { | 
| Chris Lattner | 27e9b41 | 2005-05-11 18:57:39 +0000 | [diff] [blame] | 1281 |     SDNode *&BON = BinaryOps[std::make_pair(Opcode, std::make_pair(N1, N2))]; | 
 | 1282 |     if (BON) return SDOperand(BON, 0); | 
 | 1283 |  | 
 | 1284 |     BON = N = new SDNode(Opcode, N1, N2); | 
 | 1285 |   } else { | 
| Chris Lattner | 88de6e7 | 2005-05-12 00:17:04 +0000 | [diff] [blame] | 1286 |     N = new SDNode(Opcode, N1, N2); | 
| Chris Lattner | 27e9b41 | 2005-05-11 18:57:39 +0000 | [diff] [blame] | 1287 |   } | 
 | 1288 |  | 
| Chris Lattner | 3e01136 | 2005-05-14 07:45:46 +0000 | [diff] [blame] | 1289 |   N->setValueTypes(VT); | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 1290 |   AllNodes.push_back(N); | 
 | 1291 |   return SDOperand(N, 0); | 
 | 1292 | } | 
 | 1293 |  | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 1294 | SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, | 
 | 1295 |                                 SDOperand N1, SDOperand N2, SDOperand N3) { | 
 | 1296 |   // Perform various simplifications. | 
 | 1297 |   ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.Val); | 
 | 1298 |   ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2.Val); | 
 | 1299 |   ConstantSDNode *N3C = dyn_cast<ConstantSDNode>(N3.Val); | 
 | 1300 |   switch (Opcode) { | 
| Chris Lattner | 7cf7e3f | 2005-08-09 20:20:18 +0000 | [diff] [blame] | 1301 |   case ISD::SETCC: { | 
 | 1302 |     // Use SimplifySetCC  to simplify SETCC's. | 
| Chris Lattner | bd8625b | 2005-08-09 23:09:05 +0000 | [diff] [blame] | 1303 |     SDOperand Simp = SimplifySetCC(VT, N1, N2, cast<CondCodeSDNode>(N3)->get()); | 
| Chris Lattner | 7cf7e3f | 2005-08-09 20:20:18 +0000 | [diff] [blame] | 1304 |     if (Simp.Val) return Simp; | 
 | 1305 |     break; | 
 | 1306 |   } | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 1307 |   case ISD::SELECT: | 
 | 1308 |     if (N1C) | 
 | 1309 |       if (N1C->getValue()) | 
 | 1310 |         return N2;             // select true, X, Y -> X | 
| Misha Brukman | edf128a | 2005-04-21 22:36:52 +0000 | [diff] [blame] | 1311 |       else | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 1312 |         return N3;             // select false, X, Y -> Y | 
 | 1313 |  | 
 | 1314 |     if (N2 == N3) return N2;   // select C, X, X -> X | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 1315 |     break; | 
| Chris Lattner | 5351e9b | 2005-01-07 22:49:57 +0000 | [diff] [blame] | 1316 |   case ISD::BRCOND: | 
 | 1317 |     if (N2C) | 
 | 1318 |       if (N2C->getValue()) // Unconditional branch | 
 | 1319 |         return getNode(ISD::BR, MVT::Other, N1, N3); | 
 | 1320 |       else | 
 | 1321 |         return N1;         // Never-taken branch | 
| Chris Lattner | 7c68ec6 | 2005-01-07 23:32:00 +0000 | [diff] [blame] | 1322 |     break; | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 1323 |   } | 
 | 1324 |  | 
| Chris Lattner | 385328c | 2005-05-14 07:42:29 +0000 | [diff] [blame] | 1325 |   std::vector<SDOperand> Ops; | 
 | 1326 |   Ops.reserve(3); | 
 | 1327 |   Ops.push_back(N1); | 
 | 1328 |   Ops.push_back(N2); | 
 | 1329 |   Ops.push_back(N3); | 
 | 1330 |  | 
| Chris Lattner | 43247a1 | 2005-08-25 19:12:10 +0000 | [diff] [blame] | 1331 |   // Memoize node if it doesn't produce a flag. | 
 | 1332 |   SDNode *N; | 
 | 1333 |   if (VT != MVT::Flag) { | 
 | 1334 |     SDNode *&E = OneResultNodes[std::make_pair(Opcode,std::make_pair(VT, Ops))]; | 
 | 1335 |     if (E) return SDOperand(E, 0); | 
 | 1336 |     E = N = new SDNode(Opcode, N1, N2, N3); | 
 | 1337 |   } else { | 
 | 1338 |     N = new SDNode(Opcode, N1, N2, N3); | 
 | 1339 |   } | 
| Chris Lattner | adf6c2a | 2005-05-14 07:29:57 +0000 | [diff] [blame] | 1340 |   N->setValueTypes(VT); | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 1341 |   AllNodes.push_back(N); | 
 | 1342 |   return SDOperand(N, 0); | 
 | 1343 | } | 
 | 1344 |  | 
 | 1345 | SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, | 
| Jeff Cohen | 00b16889 | 2005-07-27 06:12:32 +0000 | [diff] [blame] | 1346 |                                 SDOperand N1, SDOperand N2, SDOperand N3, | 
| Andrew Lenharth | 2d86ea2 | 2005-04-27 20:10:01 +0000 | [diff] [blame] | 1347 |                                 SDOperand N4) { | 
| Chris Lattner | b7f7d51 | 2005-05-14 07:32:14 +0000 | [diff] [blame] | 1348 |   std::vector<SDOperand> Ops; | 
 | 1349 |   Ops.reserve(4); | 
 | 1350 |   Ops.push_back(N1); | 
 | 1351 |   Ops.push_back(N2); | 
 | 1352 |   Ops.push_back(N3); | 
 | 1353 |   Ops.push_back(N4); | 
 | 1354 |   return getNode(Opcode, VT, Ops); | 
| Andrew Lenharth | 2d86ea2 | 2005-04-27 20:10:01 +0000 | [diff] [blame] | 1355 | } | 
 | 1356 |  | 
| Chris Lattner | 9fadb4c | 2005-07-10 00:29:18 +0000 | [diff] [blame] | 1357 | SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, | 
 | 1358 |                                 SDOperand N1, SDOperand N2, SDOperand N3, | 
 | 1359 |                                 SDOperand N4, SDOperand N5) { | 
 | 1360 |   std::vector<SDOperand> Ops; | 
 | 1361 |   Ops.reserve(5); | 
 | 1362 |   Ops.push_back(N1); | 
 | 1363 |   Ops.push_back(N2); | 
 | 1364 |   Ops.push_back(N3); | 
 | 1365 |   Ops.push_back(N4); | 
 | 1366 |   Ops.push_back(N5); | 
 | 1367 |   return getNode(Opcode, VT, Ops); | 
 | 1368 | } | 
 | 1369 |  | 
| Evan Cheng | 7038daf | 2005-12-10 00:37:58 +0000 | [diff] [blame] | 1370 | // setAdjCallChain - This method changes the token chain of an | 
 | 1371 | // CALLSEQ_START/END node to be the specified operand. | 
 | 1372 | void SDNode::setAdjCallChain(SDOperand N) { | 
 | 1373 |   assert(N.getValueType() == MVT::Other); | 
 | 1374 |   assert((getOpcode() == ISD::CALLSEQ_START || | 
 | 1375 |           getOpcode() == ISD::CALLSEQ_END) && "Cannot adjust this node!"); | 
 | 1376 |  | 
 | 1377 |   OperandList[0].Val->removeUser(this); | 
 | 1378 |   OperandList[0] = N; | 
 | 1379 |   OperandList[0].Val->Uses.push_back(this); | 
 | 1380 | } | 
 | 1381 |  | 
| Chris Lattner | 6a54289 | 2006-01-24 05:48:21 +0000 | [diff] [blame] | 1382 | // setAdjCallFlag - This method changes the flag input of an | 
 | 1383 | // CALLSEQ_START/END node to be the specified operand. | 
 | 1384 | void SDNode::setAdjCallFlag(SDOperand N) { | 
 | 1385 |   assert(N.getValueType() == MVT::Flag); | 
 | 1386 |   assert((getOpcode() == ISD::CALLSEQ_START || | 
 | 1387 |           getOpcode() == ISD::CALLSEQ_END) && "Cannot adjust this node!"); | 
 | 1388 |    | 
 | 1389 |   SDOperand &FlagOp = OperandList[getNumOperands()-1]; | 
 | 1390 |   assert(FlagOp.getValueType() == MVT::Flag); | 
 | 1391 |   FlagOp.Val->removeUser(this); | 
 | 1392 |   FlagOp = N; | 
 | 1393 |   FlagOp.Val->Uses.push_back(this); | 
 | 1394 | } | 
| Evan Cheng | 7038daf | 2005-12-10 00:37:58 +0000 | [diff] [blame] | 1395 |  | 
 | 1396 |  | 
 | 1397 | SDOperand SelectionDAG::getLoad(MVT::ValueType VT, | 
 | 1398 |                                 SDOperand Chain, SDOperand Ptr, | 
 | 1399 |                                 SDOperand SV) { | 
 | 1400 |   SDNode *&N = Loads[std::make_pair(Ptr, std::make_pair(Chain, VT))]; | 
 | 1401 |   if (N) return SDOperand(N, 0); | 
 | 1402 |   N = new SDNode(ISD::LOAD, Chain, Ptr, SV); | 
 | 1403 |  | 
 | 1404 |   // Loads have a token chain. | 
 | 1405 |   setNodeValueTypes(N, VT, MVT::Other); | 
 | 1406 |   AllNodes.push_back(N); | 
 | 1407 |   return SDOperand(N, 0); | 
 | 1408 | } | 
 | 1409 |  | 
 | 1410 | SDOperand SelectionDAG::getVecLoad(unsigned Count, MVT::ValueType EVT, | 
 | 1411 |                                    SDOperand Chain, SDOperand Ptr, | 
 | 1412 |                                    SDOperand SV) { | 
 | 1413 |   SDNode *&N = Loads[std::make_pair(Ptr, std::make_pair(Chain, EVT))]; | 
 | 1414 |   if (N) return SDOperand(N, 0); | 
 | 1415 |   std::vector<SDOperand> Ops; | 
 | 1416 |   Ops.reserve(5); | 
 | 1417 |   Ops.push_back(Chain); | 
 | 1418 |   Ops.push_back(Ptr); | 
 | 1419 |   Ops.push_back(getConstant(Count, MVT::i32)); | 
 | 1420 |   Ops.push_back(getValueType(EVT)); | 
 | 1421 |   Ops.push_back(SV); | 
 | 1422 |   std::vector<MVT::ValueType> VTs; | 
 | 1423 |   VTs.reserve(2); | 
 | 1424 |   VTs.push_back(MVT::Vector); VTs.push_back(MVT::Other);  // Add token chain. | 
 | 1425 |   return getNode(ISD::VLOAD, VTs, Ops); | 
 | 1426 | } | 
 | 1427 |  | 
 | 1428 | SDOperand SelectionDAG::getExtLoad(unsigned Opcode, MVT::ValueType VT, | 
 | 1429 |                                    SDOperand Chain, SDOperand Ptr, SDOperand SV, | 
 | 1430 |                                    MVT::ValueType EVT) { | 
 | 1431 |   std::vector<SDOperand> Ops; | 
 | 1432 |   Ops.reserve(4); | 
 | 1433 |   Ops.push_back(Chain); | 
 | 1434 |   Ops.push_back(Ptr); | 
 | 1435 |   Ops.push_back(SV); | 
 | 1436 |   Ops.push_back(getValueType(EVT)); | 
 | 1437 |   std::vector<MVT::ValueType> VTs; | 
 | 1438 |   VTs.reserve(2); | 
 | 1439 |   VTs.push_back(VT); VTs.push_back(MVT::Other);  // Add token chain. | 
 | 1440 |   return getNode(Opcode, VTs, Ops); | 
 | 1441 | } | 
| Chris Lattner | 9fadb4c | 2005-07-10 00:29:18 +0000 | [diff] [blame] | 1442 |  | 
| Chris Lattner | 0437cdd | 2005-05-09 04:14:13 +0000 | [diff] [blame] | 1443 | SDOperand SelectionDAG::getSrcValue(const Value *V, int Offset) { | 
| Andrew Lenharth | 06ef884 | 2005-06-29 18:54:02 +0000 | [diff] [blame] | 1444 |   assert((!V || isa<PointerType>(V->getType())) && | 
 | 1445 |          "SrcValue is not a pointer?"); | 
| Chris Lattner | 0437cdd | 2005-05-09 04:14:13 +0000 | [diff] [blame] | 1446 |   SDNode *&N = ValueNodes[std::make_pair(V, Offset)]; | 
 | 1447 |   if (N) return SDOperand(N, 0); | 
 | 1448 |  | 
 | 1449 |   N = new SrcValueSDNode(V, Offset); | 
| Andrew Lenharth | 2d86ea2 | 2005-04-27 20:10:01 +0000 | [diff] [blame] | 1450 |   AllNodes.push_back(N); | 
 | 1451 |   return SDOperand(N, 0); | 
 | 1452 | } | 
 | 1453 |  | 
| Nate Begeman | acc398c | 2006-01-25 18:21:52 +0000 | [diff] [blame] | 1454 | SDOperand SelectionDAG::getVAArg(MVT::ValueType VT, | 
 | 1455 |                                  SDOperand Chain, SDOperand Ptr, | 
 | 1456 |                                  SDOperand SV) { | 
 | 1457 |   std::vector<SDOperand> Ops; | 
 | 1458 |   Ops.reserve(3); | 
 | 1459 |   Ops.push_back(Chain); | 
 | 1460 |   Ops.push_back(Ptr); | 
 | 1461 |   Ops.push_back(SV); | 
 | 1462 |   std::vector<MVT::ValueType> VTs; | 
 | 1463 |   VTs.reserve(2); | 
 | 1464 |   VTs.push_back(VT); VTs.push_back(MVT::Other);  // Add token chain. | 
 | 1465 |   return getNode(ISD::VAARG, VTs, Ops); | 
 | 1466 | } | 
 | 1467 |  | 
| Andrew Lenharth | 2d86ea2 | 2005-04-27 20:10:01 +0000 | [diff] [blame] | 1468 | SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, | 
| Chris Lattner | 89c3463 | 2005-05-14 06:20:26 +0000 | [diff] [blame] | 1469 |                                 std::vector<SDOperand> &Ops) { | 
 | 1470 |   switch (Ops.size()) { | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 1471 |   case 0: return getNode(Opcode, VT); | 
| Chris Lattner | 89c3463 | 2005-05-14 06:20:26 +0000 | [diff] [blame] | 1472 |   case 1: return getNode(Opcode, VT, Ops[0]); | 
 | 1473 |   case 2: return getNode(Opcode, VT, Ops[0], Ops[1]); | 
 | 1474 |   case 3: return getNode(Opcode, VT, Ops[0], Ops[1], Ops[2]); | 
| Chris Lattner | ef847df | 2005-04-09 03:27:28 +0000 | [diff] [blame] | 1475 |   default: break; | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 1476 |   } | 
| Chris Lattner | de202b3 | 2005-11-09 23:47:37 +0000 | [diff] [blame] | 1477 |    | 
| Chris Lattner | 89c3463 | 2005-05-14 06:20:26 +0000 | [diff] [blame] | 1478 |   ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(Ops[1].Val); | 
| Chris Lattner | ef847df | 2005-04-09 03:27:28 +0000 | [diff] [blame] | 1479 |   switch (Opcode) { | 
 | 1480 |   default: break; | 
 | 1481 |   case ISD::BRCONDTWOWAY: | 
 | 1482 |     if (N1C) | 
 | 1483 |       if (N1C->getValue()) // Unconditional branch to true dest. | 
| Chris Lattner | 89c3463 | 2005-05-14 06:20:26 +0000 | [diff] [blame] | 1484 |         return getNode(ISD::BR, MVT::Other, Ops[0], Ops[2]); | 
| Chris Lattner | ef847df | 2005-04-09 03:27:28 +0000 | [diff] [blame] | 1485 |       else                 // Unconditional branch to false dest. | 
| Chris Lattner | 89c3463 | 2005-05-14 06:20:26 +0000 | [diff] [blame] | 1486 |         return getNode(ISD::BR, MVT::Other, Ops[0], Ops[3]); | 
| Chris Lattner | ef847df | 2005-04-09 03:27:28 +0000 | [diff] [blame] | 1487 |     break; | 
| Nate Begeman | 7cbd525 | 2005-08-16 19:49:35 +0000 | [diff] [blame] | 1488 |   case ISD::BRTWOWAY_CC: | 
 | 1489 |     assert(Ops.size() == 6 && "BRTWOWAY_CC takes 6 operands!"); | 
 | 1490 |     assert(Ops[2].getValueType() == Ops[3].getValueType() && | 
 | 1491 |            "LHS and RHS of comparison must have same type!"); | 
 | 1492 |     break; | 
| Chris Lattner | 9fadb4c | 2005-07-10 00:29:18 +0000 | [diff] [blame] | 1493 |   case ISD::TRUNCSTORE: { | 
 | 1494 |     assert(Ops.size() == 5 && "TRUNCSTORE takes 5 operands!"); | 
 | 1495 |     MVT::ValueType EVT = cast<VTSDNode>(Ops[4])->getVT(); | 
 | 1496 | #if 0 // FIXME: If the target supports EVT natively, convert to a truncate/store | 
 | 1497 |     // If this is a truncating store of a constant, convert to the desired type | 
 | 1498 |     // and store it instead. | 
 | 1499 |     if (isa<Constant>(Ops[0])) { | 
 | 1500 |       SDOperand Op = getNode(ISD::TRUNCATE, EVT, N1); | 
 | 1501 |       if (isa<Constant>(Op)) | 
 | 1502 |         N1 = Op; | 
 | 1503 |     } | 
 | 1504 |     // Also for ConstantFP? | 
 | 1505 | #endif | 
 | 1506 |     if (Ops[0].getValueType() == EVT)       // Normal store? | 
 | 1507 |       return getNode(ISD::STORE, VT, Ops[0], Ops[1], Ops[2], Ops[3]); | 
 | 1508 |     assert(Ops[1].getValueType() > EVT && "Not a truncation?"); | 
 | 1509 |     assert(MVT::isInteger(Ops[1].getValueType()) == MVT::isInteger(EVT) && | 
 | 1510 |            "Can't do FP-INT conversion!"); | 
 | 1511 |     break; | 
 | 1512 |   } | 
| Chris Lattner | 7b2880c | 2005-08-24 22:44:39 +0000 | [diff] [blame] | 1513 |   case ISD::SELECT_CC: { | 
| Chris Lattner | ad13715 | 2005-10-05 06:37:22 +0000 | [diff] [blame] | 1514 |     assert(Ops.size() == 5 && "SELECT_CC takes 5 operands!"); | 
| Chris Lattner | 7b2880c | 2005-08-24 22:44:39 +0000 | [diff] [blame] | 1515 |     assert(Ops[0].getValueType() == Ops[1].getValueType() && | 
 | 1516 |            "LHS and RHS of condition must have same type!"); | 
 | 1517 |     assert(Ops[2].getValueType() == Ops[3].getValueType() && | 
 | 1518 |            "True and False arms of SelectCC must have same type!"); | 
 | 1519 |     assert(Ops[2].getValueType() == VT && | 
 | 1520 |            "select_cc node must be of same type as true and false value!"); | 
| Chris Lattner | 7b2880c | 2005-08-24 22:44:39 +0000 | [diff] [blame] | 1521 |     break; | 
 | 1522 |   } | 
 | 1523 |   case ISD::BR_CC: { | 
| Chris Lattner | ad13715 | 2005-10-05 06:37:22 +0000 | [diff] [blame] | 1524 |     assert(Ops.size() == 5 && "BR_CC takes 5 operands!"); | 
| Chris Lattner | 7b2880c | 2005-08-24 22:44:39 +0000 | [diff] [blame] | 1525 |     assert(Ops[2].getValueType() == Ops[3].getValueType() && | 
 | 1526 |            "LHS/RHS of comparison should match types!"); | 
| Chris Lattner | 7b2880c | 2005-08-24 22:44:39 +0000 | [diff] [blame] | 1527 |     break; | 
 | 1528 |   } | 
| Chris Lattner | ef847df | 2005-04-09 03:27:28 +0000 | [diff] [blame] | 1529 |   } | 
 | 1530 |  | 
| Chris Lattner | 385328c | 2005-05-14 07:42:29 +0000 | [diff] [blame] | 1531 |   // Memoize nodes. | 
| Chris Lattner | 43247a1 | 2005-08-25 19:12:10 +0000 | [diff] [blame] | 1532 |   SDNode *N; | 
 | 1533 |   if (VT != MVT::Flag) { | 
 | 1534 |     SDNode *&E = | 
 | 1535 |       OneResultNodes[std::make_pair(Opcode, std::make_pair(VT, Ops))]; | 
 | 1536 |     if (E) return SDOperand(E, 0); | 
 | 1537 |     E = N = new SDNode(Opcode, Ops); | 
 | 1538 |   } else { | 
 | 1539 |     N = new SDNode(Opcode, Ops); | 
 | 1540 |   } | 
| Chris Lattner | e89083a | 2005-05-14 07:25:05 +0000 | [diff] [blame] | 1541 |   N->setValueTypes(VT); | 
| Chris Lattner | ef847df | 2005-04-09 03:27:28 +0000 | [diff] [blame] | 1542 |   AllNodes.push_back(N); | 
 | 1543 |   return SDOperand(N, 0); | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 1544 | } | 
 | 1545 |  | 
| Chris Lattner | 89c3463 | 2005-05-14 06:20:26 +0000 | [diff] [blame] | 1546 | SDOperand SelectionDAG::getNode(unsigned Opcode, | 
 | 1547 |                                 std::vector<MVT::ValueType> &ResultTys, | 
 | 1548 |                                 std::vector<SDOperand> &Ops) { | 
 | 1549 |   if (ResultTys.size() == 1) | 
 | 1550 |     return getNode(Opcode, ResultTys[0], Ops); | 
 | 1551 |  | 
| Chris Lattner | 5f056bf | 2005-07-10 01:55:33 +0000 | [diff] [blame] | 1552 |   switch (Opcode) { | 
 | 1553 |   case ISD::EXTLOAD: | 
 | 1554 |   case ISD::SEXTLOAD: | 
 | 1555 |   case ISD::ZEXTLOAD: { | 
 | 1556 |     MVT::ValueType EVT = cast<VTSDNode>(Ops[3])->getVT(); | 
 | 1557 |     assert(Ops.size() == 4 && ResultTys.size() == 2 && "Bad *EXTLOAD!"); | 
 | 1558 |     // If they are asking for an extending load from/to the same thing, return a | 
 | 1559 |     // normal load. | 
 | 1560 |     if (ResultTys[0] == EVT) | 
 | 1561 |       return getLoad(ResultTys[0], Ops[0], Ops[1], Ops[2]); | 
 | 1562 |     assert(EVT < ResultTys[0] && | 
 | 1563 |            "Should only be an extending load, not truncating!"); | 
 | 1564 |     assert((Opcode == ISD::EXTLOAD || MVT::isInteger(ResultTys[0])) && | 
 | 1565 |            "Cannot sign/zero extend a FP load!"); | 
 | 1566 |     assert(MVT::isInteger(ResultTys[0]) == MVT::isInteger(EVT) && | 
 | 1567 |            "Cannot convert from FP to Int or Int -> FP!"); | 
 | 1568 |     break; | 
 | 1569 |   } | 
 | 1570 |  | 
| Chris Lattner | e89083a | 2005-05-14 07:25:05 +0000 | [diff] [blame] | 1571 |   // FIXME: figure out how to safely handle things like | 
 | 1572 |   // int foo(int x) { return 1 << (x & 255); } | 
 | 1573 |   // int bar() { return foo(256); } | 
 | 1574 | #if 0 | 
| Chris Lattner | e89083a | 2005-05-14 07:25:05 +0000 | [diff] [blame] | 1575 |   case ISD::SRA_PARTS: | 
 | 1576 |   case ISD::SRL_PARTS: | 
 | 1577 |   case ISD::SHL_PARTS: | 
 | 1578 |     if (N3.getOpcode() == ISD::SIGN_EXTEND_INREG && | 
| Chris Lattner | 15e4b01 | 2005-07-10 00:07:11 +0000 | [diff] [blame] | 1579 |         cast<VTSDNode>(N3.getOperand(1))->getVT() != MVT::i1) | 
| Chris Lattner | e89083a | 2005-05-14 07:25:05 +0000 | [diff] [blame] | 1580 |       return getNode(Opcode, VT, N1, N2, N3.getOperand(0)); | 
 | 1581 |     else if (N3.getOpcode() == ISD::AND) | 
 | 1582 |       if (ConstantSDNode *AndRHS = dyn_cast<ConstantSDNode>(N3.getOperand(1))) { | 
 | 1583 |         // If the and is only masking out bits that cannot effect the shift, | 
 | 1584 |         // eliminate the and. | 
 | 1585 |         unsigned NumBits = MVT::getSizeInBits(VT)*2; | 
 | 1586 |         if ((AndRHS->getValue() & (NumBits-1)) == NumBits-1) | 
 | 1587 |           return getNode(Opcode, VT, N1, N2, N3.getOperand(0)); | 
 | 1588 |       } | 
 | 1589 |     break; | 
| Chris Lattner | e89083a | 2005-05-14 07:25:05 +0000 | [diff] [blame] | 1590 | #endif | 
| Chris Lattner | 5f056bf | 2005-07-10 01:55:33 +0000 | [diff] [blame] | 1591 |   } | 
| Chris Lattner | 89c3463 | 2005-05-14 06:20:26 +0000 | [diff] [blame] | 1592 |  | 
| Chris Lattner | 43247a1 | 2005-08-25 19:12:10 +0000 | [diff] [blame] | 1593 |   // Memoize the node unless it returns a flag. | 
 | 1594 |   SDNode *N; | 
 | 1595 |   if (ResultTys.back() != MVT::Flag) { | 
 | 1596 |     SDNode *&E = | 
 | 1597 |       ArbitraryNodes[std::make_pair(Opcode, std::make_pair(ResultTys, Ops))]; | 
 | 1598 |     if (E) return SDOperand(E, 0); | 
 | 1599 |     E = N = new SDNode(Opcode, Ops); | 
 | 1600 |   } else { | 
 | 1601 |     N = new SDNode(Opcode, Ops); | 
 | 1602 |   } | 
| Chris Lattner | a325511 | 2005-11-08 23:30:28 +0000 | [diff] [blame] | 1603 |   setNodeValueTypes(N, ResultTys); | 
| Chris Lattner | 5fa4fa4 | 2005-05-14 06:42:57 +0000 | [diff] [blame] | 1604 |   AllNodes.push_back(N); | 
| Chris Lattner | 89c3463 | 2005-05-14 06:20:26 +0000 | [diff] [blame] | 1605 |   return SDOperand(N, 0); | 
 | 1606 | } | 
 | 1607 |  | 
| Chris Lattner | a325511 | 2005-11-08 23:30:28 +0000 | [diff] [blame] | 1608 | void SelectionDAG::setNodeValueTypes(SDNode *N,  | 
 | 1609 |                                      std::vector<MVT::ValueType> &RetVals) { | 
 | 1610 |   switch (RetVals.size()) { | 
 | 1611 |   case 0: return; | 
 | 1612 |   case 1: N->setValueTypes(RetVals[0]); return; | 
 | 1613 |   case 2: setNodeValueTypes(N, RetVals[0], RetVals[1]); return; | 
 | 1614 |   default: break; | 
 | 1615 |   } | 
 | 1616 |    | 
 | 1617 |   std::list<std::vector<MVT::ValueType> >::iterator I = | 
 | 1618 |     std::find(VTList.begin(), VTList.end(), RetVals); | 
 | 1619 |   if (I == VTList.end()) { | 
 | 1620 |     VTList.push_front(RetVals); | 
 | 1621 |     I = VTList.begin(); | 
 | 1622 |   } | 
 | 1623 |  | 
 | 1624 |   N->setValueTypes(&(*I)[0], I->size()); | 
 | 1625 | } | 
 | 1626 |  | 
 | 1627 | void SelectionDAG::setNodeValueTypes(SDNode *N, MVT::ValueType VT1,  | 
 | 1628 |                                      MVT::ValueType VT2) { | 
 | 1629 |   for (std::list<std::vector<MVT::ValueType> >::iterator I = VTList.begin(), | 
 | 1630 |        E = VTList.end(); I != E; ++I) { | 
 | 1631 |     if (I->size() == 2 && (*I)[0] == VT1 && (*I)[1] == VT2) { | 
 | 1632 |       N->setValueTypes(&(*I)[0], 2); | 
 | 1633 |       return; | 
 | 1634 |     } | 
 | 1635 |   } | 
 | 1636 |   std::vector<MVT::ValueType> V; | 
 | 1637 |   V.push_back(VT1); | 
 | 1638 |   V.push_back(VT2); | 
 | 1639 |   VTList.push_front(V); | 
 | 1640 |   N->setValueTypes(&(*VTList.begin())[0], 2); | 
 | 1641 | } | 
 | 1642 |  | 
| Chris Lattner | df6eb30 | 2006-01-28 09:32:45 +0000 | [diff] [blame] | 1643 | /// UpdateNodeOperands - *Mutate* the specified node in-place to have the | 
 | 1644 | /// specified operands.  If the resultant node already exists in the DAG, | 
 | 1645 | /// this does not modify the specified node, instead it returns the node that | 
 | 1646 | /// already exists.  If the resultant node does not exist in the DAG, the | 
 | 1647 | /// input node is returned.  As a degenerate case, if you specify the same | 
 | 1648 | /// input operands as the node already has, the input node is returned. | 
 | 1649 | SDOperand SelectionDAG:: | 
 | 1650 | UpdateNodeOperands(SDOperand InN, SDOperand Op) { | 
 | 1651 |   SDNode *N = InN.Val; | 
 | 1652 |   assert(N->getNumOperands() == 1 && "Update with wrong number of operands"); | 
 | 1653 |    | 
 | 1654 |   // Check to see if there is no change. | 
 | 1655 |   if (Op == N->getOperand(0)) return InN; | 
 | 1656 |    | 
 | 1657 |   // See if the modified node already exists. | 
 | 1658 |   SDNode **NewSlot = FindModifiedNodeSlot(N, Op); | 
 | 1659 |   if (NewSlot && *NewSlot) | 
 | 1660 |     return SDOperand(*NewSlot, InN.ResNo); | 
 | 1661 |    | 
 | 1662 |   // Nope it doesn't.  Remove the node from it's current place in the maps. | 
 | 1663 |   if (NewSlot) | 
 | 1664 |     RemoveNodeFromCSEMaps(N); | 
 | 1665 |    | 
 | 1666 |   // Now we update the operands. | 
 | 1667 |   N->OperandList[0].Val->removeUser(N); | 
 | 1668 |   Op.Val->addUser(N); | 
 | 1669 |   N->OperandList[0] = Op; | 
 | 1670 |    | 
 | 1671 |   // If this gets put into a CSE map, add it. | 
 | 1672 |   if (NewSlot) *NewSlot = N; | 
 | 1673 |   return InN; | 
 | 1674 | } | 
 | 1675 |  | 
 | 1676 | SDOperand SelectionDAG:: | 
 | 1677 | UpdateNodeOperands(SDOperand InN, SDOperand Op1, SDOperand Op2) { | 
 | 1678 |   SDNode *N = InN.Val; | 
 | 1679 |   assert(N->getNumOperands() == 2 && "Update with wrong number of operands"); | 
 | 1680 |    | 
 | 1681 |   // Check to see if there is no change. | 
 | 1682 |   bool AnyChange = false; | 
 | 1683 |   if (Op1 == N->getOperand(0) && Op2 == N->getOperand(1)) | 
 | 1684 |     return InN;   // No operands changed, just return the input node. | 
 | 1685 |    | 
 | 1686 |   // See if the modified node already exists. | 
 | 1687 |   SDNode **NewSlot = FindModifiedNodeSlot(N, Op1, Op2); | 
 | 1688 |   if (NewSlot && *NewSlot) | 
 | 1689 |     return SDOperand(*NewSlot, InN.ResNo); | 
 | 1690 |    | 
 | 1691 |   // Nope it doesn't.  Remove the node from it's current place in the maps. | 
 | 1692 |   if (NewSlot) | 
 | 1693 |     RemoveNodeFromCSEMaps(N); | 
 | 1694 |    | 
 | 1695 |   // Now we update the operands. | 
 | 1696 |   if (N->OperandList[0] != Op1) { | 
 | 1697 |     N->OperandList[0].Val->removeUser(N); | 
 | 1698 |     Op1.Val->addUser(N); | 
 | 1699 |     N->OperandList[0] = Op1; | 
 | 1700 |   } | 
 | 1701 |   if (N->OperandList[1] != Op2) { | 
 | 1702 |     N->OperandList[1].Val->removeUser(N); | 
 | 1703 |     Op2.Val->addUser(N); | 
 | 1704 |     N->OperandList[1] = Op2; | 
 | 1705 |   } | 
 | 1706 |    | 
 | 1707 |   // If this gets put into a CSE map, add it. | 
 | 1708 |   if (NewSlot) *NewSlot = N; | 
 | 1709 |   return InN; | 
 | 1710 | } | 
 | 1711 |  | 
 | 1712 | SDOperand SelectionDAG:: | 
 | 1713 | UpdateNodeOperands(SDOperand N, SDOperand Op1, SDOperand Op2, SDOperand Op3) { | 
 | 1714 |   std::vector<SDOperand> Ops; | 
 | 1715 |   Ops.push_back(Op1); | 
 | 1716 |   Ops.push_back(Op2); | 
 | 1717 |   Ops.push_back(Op3); | 
 | 1718 |   return UpdateNodeOperands(N, Ops); | 
 | 1719 | } | 
 | 1720 |  | 
 | 1721 | SDOperand SelectionDAG:: | 
 | 1722 | UpdateNodeOperands(SDOperand N, SDOperand Op1, SDOperand Op2,  | 
 | 1723 |                    SDOperand Op3, SDOperand Op4) { | 
 | 1724 |   std::vector<SDOperand> Ops; | 
 | 1725 |   Ops.push_back(Op1); | 
 | 1726 |   Ops.push_back(Op2); | 
 | 1727 |   Ops.push_back(Op3); | 
 | 1728 |   Ops.push_back(Op4); | 
 | 1729 |   return UpdateNodeOperands(N, Ops); | 
 | 1730 | } | 
 | 1731 |  | 
 | 1732 | SDOperand SelectionDAG:: | 
| Chris Lattner | 809ec11 | 2006-01-28 10:09:25 +0000 | [diff] [blame] | 1733 | UpdateNodeOperands(SDOperand N, SDOperand Op1, SDOperand Op2, | 
 | 1734 |                    SDOperand Op3, SDOperand Op4, SDOperand Op5) { | 
 | 1735 |   std::vector<SDOperand> Ops; | 
 | 1736 |   Ops.push_back(Op1); | 
 | 1737 |   Ops.push_back(Op2); | 
 | 1738 |   Ops.push_back(Op3); | 
 | 1739 |   Ops.push_back(Op4); | 
 | 1740 |   Ops.push_back(Op5); | 
 | 1741 |   return UpdateNodeOperands(N, Ops); | 
 | 1742 | } | 
 | 1743 |  | 
 | 1744 |  | 
 | 1745 | SDOperand SelectionDAG:: | 
| Chris Lattner | df6eb30 | 2006-01-28 09:32:45 +0000 | [diff] [blame] | 1746 | UpdateNodeOperands(SDOperand InN, const std::vector<SDOperand> &Ops) { | 
 | 1747 |   SDNode *N = InN.Val; | 
 | 1748 |   assert(N->getNumOperands() == Ops.size() && | 
 | 1749 |          "Update with wrong number of operands"); | 
 | 1750 |    | 
 | 1751 |   // Check to see if there is no change. | 
 | 1752 |   unsigned NumOps = Ops.size(); | 
 | 1753 |   bool AnyChange = false; | 
 | 1754 |   for (unsigned i = 0; i != NumOps; ++i) { | 
 | 1755 |     if (Ops[i] != N->getOperand(i)) { | 
 | 1756 |       AnyChange = true; | 
 | 1757 |       break; | 
 | 1758 |     } | 
 | 1759 |   } | 
 | 1760 |    | 
 | 1761 |   // No operands changed, just return the input node. | 
 | 1762 |   if (!AnyChange) return InN; | 
 | 1763 |    | 
 | 1764 |   // See if the modified node already exists. | 
 | 1765 |   SDNode **NewSlot = FindModifiedNodeSlot(N, Ops); | 
 | 1766 |   if (NewSlot && *NewSlot) | 
 | 1767 |     return SDOperand(*NewSlot, InN.ResNo); | 
 | 1768 |    | 
 | 1769 |   // Nope it doesn't.  Remove the node from it's current place in the maps. | 
 | 1770 |   if (NewSlot) | 
 | 1771 |     RemoveNodeFromCSEMaps(N); | 
 | 1772 |    | 
 | 1773 |   // Now we update the operands. | 
 | 1774 |   for (unsigned i = 0; i != NumOps; ++i) { | 
 | 1775 |     if (N->OperandList[i] != Ops[i]) { | 
 | 1776 |       N->OperandList[i].Val->removeUser(N); | 
 | 1777 |       Ops[i].Val->addUser(N); | 
 | 1778 |       N->OperandList[i] = Ops[i]; | 
 | 1779 |     } | 
 | 1780 |   } | 
 | 1781 |  | 
 | 1782 |   // If this gets put into a CSE map, add it. | 
 | 1783 |   if (NewSlot) *NewSlot = N; | 
 | 1784 |   return InN; | 
 | 1785 | } | 
 | 1786 |  | 
 | 1787 |  | 
 | 1788 |  | 
| Chris Lattner | 149c58c | 2005-08-16 18:17:10 +0000 | [diff] [blame] | 1789 |  | 
 | 1790 | /// SelectNodeTo - These are used for target selectors to *mutate* the | 
 | 1791 | /// specified node to have the specified return type, Target opcode, and | 
 | 1792 | /// operands.  Note that target opcodes are stored as | 
 | 1793 | /// ISD::BUILTIN_OP_END+TargetOpcode in the node opcode field. | 
| Chris Lattner | c5e6c64 | 2005-12-01 18:00:57 +0000 | [diff] [blame] | 1794 | /// | 
 | 1795 | /// Note that SelectNodeTo returns the resultant node.  If there is already a | 
 | 1796 | /// node of the specified opcode and operands, it returns that node instead of | 
 | 1797 | /// the current one. | 
| Chris Lattner | eb19e40 | 2005-11-30 22:45:14 +0000 | [diff] [blame] | 1798 | SDOperand SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc, | 
 | 1799 |                                      MVT::ValueType VT) { | 
| Chris Lattner | c5e6c64 | 2005-12-01 18:00:57 +0000 | [diff] [blame] | 1800 |   // If an identical node already exists, use it. | 
 | 1801 |   SDNode *&ON = NullaryOps[std::make_pair(ISD::BUILTIN_OP_END+TargetOpc, VT)]; | 
 | 1802 |   if (ON) return SDOperand(ON, 0); | 
 | 1803 |    | 
| Chris Lattner | 7651fa4 | 2005-08-24 23:00:29 +0000 | [diff] [blame] | 1804 |   RemoveNodeFromCSEMaps(N); | 
| Chris Lattner | c5e6c64 | 2005-12-01 18:00:57 +0000 | [diff] [blame] | 1805 |    | 
| Chris Lattner | 7651fa4 | 2005-08-24 23:00:29 +0000 | [diff] [blame] | 1806 |   N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc); | 
 | 1807 |   N->setValueTypes(VT); | 
| Chris Lattner | c5e6c64 | 2005-12-01 18:00:57 +0000 | [diff] [blame] | 1808 |  | 
 | 1809 |   ON = N;   // Memoize the new node. | 
| Chris Lattner | eb19e40 | 2005-11-30 22:45:14 +0000 | [diff] [blame] | 1810 |   return SDOperand(N, 0); | 
| Chris Lattner | 7651fa4 | 2005-08-24 23:00:29 +0000 | [diff] [blame] | 1811 | } | 
| Chris Lattner | 0fb094f | 2005-11-19 01:44:53 +0000 | [diff] [blame] | 1812 |  | 
| Chris Lattner | eb19e40 | 2005-11-30 22:45:14 +0000 | [diff] [blame] | 1813 | SDOperand SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc, | 
 | 1814 |                                      MVT::ValueType VT, SDOperand Op1) { | 
| Chris Lattner | c5e6c64 | 2005-12-01 18:00:57 +0000 | [diff] [blame] | 1815 |   // If an identical node already exists, use it. | 
 | 1816 |   SDNode *&ON = UnaryOps[std::make_pair(ISD::BUILTIN_OP_END+TargetOpc, | 
 | 1817 |                                         std::make_pair(Op1, VT))]; | 
 | 1818 |   if (ON) return SDOperand(ON, 0); | 
 | 1819 |    | 
| Chris Lattner | 149c58c | 2005-08-16 18:17:10 +0000 | [diff] [blame] | 1820 |   RemoveNodeFromCSEMaps(N); | 
 | 1821 |   N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc); | 
 | 1822 |   N->setValueTypes(VT); | 
 | 1823 |   N->setOperands(Op1); | 
| Chris Lattner | c5e6c64 | 2005-12-01 18:00:57 +0000 | [diff] [blame] | 1824 |    | 
 | 1825 |   ON = N;   // Memoize the new node. | 
| Chris Lattner | eb19e40 | 2005-11-30 22:45:14 +0000 | [diff] [blame] | 1826 |   return SDOperand(N, 0); | 
| Chris Lattner | 149c58c | 2005-08-16 18:17:10 +0000 | [diff] [blame] | 1827 | } | 
| Chris Lattner | 0fb094f | 2005-11-19 01:44:53 +0000 | [diff] [blame] | 1828 |  | 
| Chris Lattner | eb19e40 | 2005-11-30 22:45:14 +0000 | [diff] [blame] | 1829 | SDOperand SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc, | 
 | 1830 |                                      MVT::ValueType VT, SDOperand Op1, | 
 | 1831 |                                      SDOperand Op2) { | 
| Chris Lattner | c5e6c64 | 2005-12-01 18:00:57 +0000 | [diff] [blame] | 1832 |   // If an identical node already exists, use it. | 
 | 1833 |   SDNode *&ON = BinaryOps[std::make_pair(ISD::BUILTIN_OP_END+TargetOpc, | 
 | 1834 |                                          std::make_pair(Op1, Op2))]; | 
 | 1835 |   if (ON) return SDOperand(ON, 0); | 
 | 1836 |    | 
| Chris Lattner | 149c58c | 2005-08-16 18:17:10 +0000 | [diff] [blame] | 1837 |   RemoveNodeFromCSEMaps(N); | 
 | 1838 |   N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc); | 
 | 1839 |   N->setValueTypes(VT); | 
 | 1840 |   N->setOperands(Op1, Op2); | 
| Chris Lattner | c5e6c64 | 2005-12-01 18:00:57 +0000 | [diff] [blame] | 1841 |    | 
 | 1842 |   ON = N;   // Memoize the new node. | 
| Chris Lattner | eb19e40 | 2005-11-30 22:45:14 +0000 | [diff] [blame] | 1843 |   return SDOperand(N, 0); | 
| Chris Lattner | 149c58c | 2005-08-16 18:17:10 +0000 | [diff] [blame] | 1844 | } | 
| Chris Lattner | 0fb094f | 2005-11-19 01:44:53 +0000 | [diff] [blame] | 1845 |  | 
| Chris Lattner | eb19e40 | 2005-11-30 22:45:14 +0000 | [diff] [blame] | 1846 | SDOperand SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc, | 
 | 1847 |                                      MVT::ValueType VT, SDOperand Op1, | 
 | 1848 |                                      SDOperand Op2, SDOperand Op3) { | 
| Chris Lattner | c5e6c64 | 2005-12-01 18:00:57 +0000 | [diff] [blame] | 1849 |   // If an identical node already exists, use it. | 
 | 1850 |   std::vector<SDOperand> OpList; | 
 | 1851 |   OpList.push_back(Op1); OpList.push_back(Op2); OpList.push_back(Op3); | 
 | 1852 |   SDNode *&ON = OneResultNodes[std::make_pair(ISD::BUILTIN_OP_END+TargetOpc, | 
 | 1853 |                                               std::make_pair(VT, OpList))]; | 
 | 1854 |   if (ON) return SDOperand(ON, 0); | 
 | 1855 |    | 
| Chris Lattner | 149c58c | 2005-08-16 18:17:10 +0000 | [diff] [blame] | 1856 |   RemoveNodeFromCSEMaps(N); | 
 | 1857 |   N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc); | 
 | 1858 |   N->setValueTypes(VT); | 
 | 1859 |   N->setOperands(Op1, Op2, Op3); | 
| Chris Lattner | c5e6c64 | 2005-12-01 18:00:57 +0000 | [diff] [blame] | 1860 |  | 
 | 1861 |   ON = N;   // Memoize the new node. | 
| Chris Lattner | eb19e40 | 2005-11-30 22:45:14 +0000 | [diff] [blame] | 1862 |   return SDOperand(N, 0); | 
| Chris Lattner | 149c58c | 2005-08-16 18:17:10 +0000 | [diff] [blame] | 1863 | } | 
| Chris Lattner | c975e1d | 2005-08-21 22:30:30 +0000 | [diff] [blame] | 1864 |  | 
| Chris Lattner | eb19e40 | 2005-11-30 22:45:14 +0000 | [diff] [blame] | 1865 | SDOperand SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc, | 
 | 1866 |                                      MVT::ValueType VT, SDOperand Op1, | 
 | 1867 |                                      SDOperand Op2, SDOperand Op3, | 
 | 1868 |                                      SDOperand Op4) { | 
| Chris Lattner | c5e6c64 | 2005-12-01 18:00:57 +0000 | [diff] [blame] | 1869 |   // If an identical node already exists, use it. | 
 | 1870 |   std::vector<SDOperand> OpList; | 
 | 1871 |   OpList.push_back(Op1); OpList.push_back(Op2); OpList.push_back(Op3); | 
 | 1872 |   OpList.push_back(Op4); | 
 | 1873 |   SDNode *&ON = OneResultNodes[std::make_pair(ISD::BUILTIN_OP_END+TargetOpc, | 
 | 1874 |                                               std::make_pair(VT, OpList))]; | 
 | 1875 |   if (ON) return SDOperand(ON, 0); | 
 | 1876 |    | 
| Nate Begeman | 294a0a1 | 2005-08-18 07:30:15 +0000 | [diff] [blame] | 1877 |   RemoveNodeFromCSEMaps(N); | 
 | 1878 |   N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc); | 
 | 1879 |   N->setValueTypes(VT); | 
 | 1880 |   N->setOperands(Op1, Op2, Op3, Op4); | 
| Chris Lattner | c5e6c64 | 2005-12-01 18:00:57 +0000 | [diff] [blame] | 1881 |  | 
 | 1882 |   ON = N;   // Memoize the new node. | 
| Chris Lattner | eb19e40 | 2005-11-30 22:45:14 +0000 | [diff] [blame] | 1883 |   return SDOperand(N, 0); | 
| Nate Begeman | 294a0a1 | 2005-08-18 07:30:15 +0000 | [diff] [blame] | 1884 | } | 
| Chris Lattner | 0fb094f | 2005-11-19 01:44:53 +0000 | [diff] [blame] | 1885 |  | 
| Chris Lattner | eb19e40 | 2005-11-30 22:45:14 +0000 | [diff] [blame] | 1886 | SDOperand SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc, | 
 | 1887 |                                      MVT::ValueType VT, SDOperand Op1, | 
 | 1888 |                                      SDOperand Op2, SDOperand Op3,SDOperand Op4, | 
 | 1889 |                                      SDOperand Op5) { | 
| Chris Lattner | c5e6c64 | 2005-12-01 18:00:57 +0000 | [diff] [blame] | 1890 |   // If an identical node already exists, use it. | 
 | 1891 |   std::vector<SDOperand> OpList; | 
 | 1892 |   OpList.push_back(Op1); OpList.push_back(Op2); OpList.push_back(Op3); | 
 | 1893 |   OpList.push_back(Op4); OpList.push_back(Op5); | 
 | 1894 |   SDNode *&ON = OneResultNodes[std::make_pair(ISD::BUILTIN_OP_END+TargetOpc, | 
 | 1895 |                                               std::make_pair(VT, OpList))]; | 
 | 1896 |   if (ON) return SDOperand(ON, 0); | 
 | 1897 |    | 
| Chris Lattner | 6b09a29 | 2005-08-21 18:49:33 +0000 | [diff] [blame] | 1898 |   RemoveNodeFromCSEMaps(N); | 
 | 1899 |   N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc); | 
 | 1900 |   N->setValueTypes(VT); | 
 | 1901 |   N->setOperands(Op1, Op2, Op3, Op4, Op5); | 
| Chris Lattner | c5e6c64 | 2005-12-01 18:00:57 +0000 | [diff] [blame] | 1902 |    | 
 | 1903 |   ON = N;   // Memoize the new node. | 
| Chris Lattner | eb19e40 | 2005-11-30 22:45:14 +0000 | [diff] [blame] | 1904 |   return SDOperand(N, 0); | 
| Chris Lattner | 6b09a29 | 2005-08-21 18:49:33 +0000 | [diff] [blame] | 1905 | } | 
| Chris Lattner | 149c58c | 2005-08-16 18:17:10 +0000 | [diff] [blame] | 1906 |  | 
| Chris Lattner | eb19e40 | 2005-11-30 22:45:14 +0000 | [diff] [blame] | 1907 | SDOperand SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc, | 
 | 1908 |                                      MVT::ValueType VT, SDOperand Op1, | 
 | 1909 |                                      SDOperand Op2, SDOperand Op3,SDOperand Op4, | 
 | 1910 |                                      SDOperand Op5, SDOperand Op6) { | 
| Chris Lattner | c5e6c64 | 2005-12-01 18:00:57 +0000 | [diff] [blame] | 1911 |   // If an identical node already exists, use it. | 
 | 1912 |   std::vector<SDOperand> OpList; | 
 | 1913 |   OpList.push_back(Op1); OpList.push_back(Op2); OpList.push_back(Op3); | 
 | 1914 |   OpList.push_back(Op4); OpList.push_back(Op5); OpList.push_back(Op6); | 
 | 1915 |   SDNode *&ON = OneResultNodes[std::make_pair(ISD::BUILTIN_OP_END+TargetOpc, | 
 | 1916 |                                               std::make_pair(VT, OpList))]; | 
 | 1917 |   if (ON) return SDOperand(ON, 0); | 
 | 1918 |  | 
| Evan Cheng | 61ca74b | 2005-11-30 02:04:11 +0000 | [diff] [blame] | 1919 |   RemoveNodeFromCSEMaps(N); | 
 | 1920 |   N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc); | 
 | 1921 |   N->setValueTypes(VT); | 
 | 1922 |   N->setOperands(Op1, Op2, Op3, Op4, Op5, Op6); | 
| Chris Lattner | c5e6c64 | 2005-12-01 18:00:57 +0000 | [diff] [blame] | 1923 |    | 
 | 1924 |   ON = N;   // Memoize the new node. | 
| Chris Lattner | eb19e40 | 2005-11-30 22:45:14 +0000 | [diff] [blame] | 1925 |   return SDOperand(N, 0); | 
| Evan Cheng | 61ca74b | 2005-11-30 02:04:11 +0000 | [diff] [blame] | 1926 | } | 
 | 1927 |  | 
| Andrew Lenharth | 8c6f1ee | 2006-01-23 20:59:12 +0000 | [diff] [blame] | 1928 | SDOperand SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc, | 
 | 1929 |                                      MVT::ValueType VT, SDOperand Op1, | 
 | 1930 |                                      SDOperand Op2, SDOperand Op3,SDOperand Op4, | 
 | 1931 |                                      SDOperand Op5, SDOperand Op6, | 
 | 1932 | 				     SDOperand Op7) { | 
 | 1933 |   // If an identical node already exists, use it. | 
 | 1934 |   std::vector<SDOperand> OpList; | 
 | 1935 |   OpList.push_back(Op1); OpList.push_back(Op2); OpList.push_back(Op3); | 
 | 1936 |   OpList.push_back(Op4); OpList.push_back(Op5); OpList.push_back(Op6); | 
 | 1937 |   OpList.push_back(Op7); | 
 | 1938 |   SDNode *&ON = OneResultNodes[std::make_pair(ISD::BUILTIN_OP_END+TargetOpc, | 
 | 1939 |                                               std::make_pair(VT, OpList))]; | 
 | 1940 |   if (ON) return SDOperand(ON, 0); | 
 | 1941 |  | 
 | 1942 |   RemoveNodeFromCSEMaps(N); | 
 | 1943 |   N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc); | 
 | 1944 |   N->setValueTypes(VT); | 
 | 1945 |   N->setOperands(Op1, Op2, Op3, Op4, Op5, Op6, Op7); | 
 | 1946 |    | 
 | 1947 |   ON = N;   // Memoize the new node. | 
 | 1948 |   return SDOperand(N, 0); | 
 | 1949 | } | 
| Andrew Lenharth | 7cf11b4 | 2006-01-23 21:51:14 +0000 | [diff] [blame] | 1950 | SDOperand SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc, | 
 | 1951 |                                      MVT::ValueType VT, SDOperand Op1, | 
 | 1952 |                                      SDOperand Op2, SDOperand Op3,SDOperand Op4, | 
 | 1953 |                                      SDOperand Op5, SDOperand Op6, | 
 | 1954 | 				     SDOperand Op7, SDOperand Op8) { | 
 | 1955 |   // If an identical node already exists, use it. | 
 | 1956 |   std::vector<SDOperand> OpList; | 
 | 1957 |   OpList.push_back(Op1); OpList.push_back(Op2); OpList.push_back(Op3); | 
 | 1958 |   OpList.push_back(Op4); OpList.push_back(Op5); OpList.push_back(Op6); | 
 | 1959 |   OpList.push_back(Op7); OpList.push_back(Op8); | 
 | 1960 |   SDNode *&ON = OneResultNodes[std::make_pair(ISD::BUILTIN_OP_END+TargetOpc, | 
 | 1961 |                                               std::make_pair(VT, OpList))]; | 
 | 1962 |   if (ON) return SDOperand(ON, 0); | 
 | 1963 |  | 
 | 1964 |   RemoveNodeFromCSEMaps(N); | 
 | 1965 |   N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc); | 
 | 1966 |   N->setValueTypes(VT); | 
 | 1967 |   N->setOperands(Op1, Op2, Op3, Op4, Op5, Op6, Op7, Op8); | 
 | 1968 |    | 
 | 1969 |   ON = N;   // Memoize the new node. | 
 | 1970 |   return SDOperand(N, 0); | 
 | 1971 | } | 
| Andrew Lenharth | 8c6f1ee | 2006-01-23 20:59:12 +0000 | [diff] [blame] | 1972 |  | 
| Chris Lattner | eb19e40 | 2005-11-30 22:45:14 +0000 | [diff] [blame] | 1973 | SDOperand SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc,  | 
 | 1974 |                                      MVT::ValueType VT1, MVT::ValueType VT2, | 
 | 1975 |                                      SDOperand Op1, SDOperand Op2) { | 
| Chris Lattner | c5e6c64 | 2005-12-01 18:00:57 +0000 | [diff] [blame] | 1976 |   // If an identical node already exists, use it. | 
 | 1977 |   std::vector<SDOperand> OpList; | 
 | 1978 |   OpList.push_back(Op1); OpList.push_back(Op2);  | 
 | 1979 |   std::vector<MVT::ValueType> VTList; | 
 | 1980 |   VTList.push_back(VT1); VTList.push_back(VT2); | 
 | 1981 |   SDNode *&ON = ArbitraryNodes[std::make_pair(ISD::BUILTIN_OP_END+TargetOpc, | 
 | 1982 |                                               std::make_pair(VTList, OpList))]; | 
 | 1983 |   if (ON) return SDOperand(ON, 0); | 
 | 1984 |  | 
| Chris Lattner | 0fb094f | 2005-11-19 01:44:53 +0000 | [diff] [blame] | 1985 |   RemoveNodeFromCSEMaps(N); | 
 | 1986 |   N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc); | 
 | 1987 |   setNodeValueTypes(N, VT1, VT2); | 
 | 1988 |   N->setOperands(Op1, Op2); | 
| Chris Lattner | c5e6c64 | 2005-12-01 18:00:57 +0000 | [diff] [blame] | 1989 |    | 
 | 1990 |   ON = N;   // Memoize the new node. | 
| Chris Lattner | eb19e40 | 2005-11-30 22:45:14 +0000 | [diff] [blame] | 1991 |   return SDOperand(N, 0); | 
| Chris Lattner | 0fb094f | 2005-11-19 01:44:53 +0000 | [diff] [blame] | 1992 | } | 
 | 1993 |  | 
| Chris Lattner | eb19e40 | 2005-11-30 22:45:14 +0000 | [diff] [blame] | 1994 | SDOperand SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc, | 
 | 1995 |                                      MVT::ValueType VT1, MVT::ValueType VT2, | 
 | 1996 |                                      SDOperand Op1, SDOperand Op2,  | 
 | 1997 |                                      SDOperand Op3) { | 
| Chris Lattner | c5e6c64 | 2005-12-01 18:00:57 +0000 | [diff] [blame] | 1998 |   // If an identical node already exists, use it. | 
 | 1999 |   std::vector<SDOperand> OpList; | 
 | 2000 |   OpList.push_back(Op1); OpList.push_back(Op2); OpList.push_back(Op3); | 
 | 2001 |   std::vector<MVT::ValueType> VTList; | 
 | 2002 |   VTList.push_back(VT1); VTList.push_back(VT2); | 
 | 2003 |   SDNode *&ON = ArbitraryNodes[std::make_pair(ISD::BUILTIN_OP_END+TargetOpc, | 
 | 2004 |                                               std::make_pair(VTList, OpList))]; | 
 | 2005 |   if (ON) return SDOperand(ON, 0); | 
 | 2006 |  | 
| Chris Lattner | 0fb094f | 2005-11-19 01:44:53 +0000 | [diff] [blame] | 2007 |   RemoveNodeFromCSEMaps(N); | 
 | 2008 |   N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc); | 
 | 2009 |   setNodeValueTypes(N, VT1, VT2); | 
 | 2010 |   N->setOperands(Op1, Op2, Op3); | 
| Chris Lattner | c5e6c64 | 2005-12-01 18:00:57 +0000 | [diff] [blame] | 2011 |    | 
 | 2012 |   ON = N;   // Memoize the new node. | 
| Chris Lattner | eb19e40 | 2005-11-30 22:45:14 +0000 | [diff] [blame] | 2013 |   return SDOperand(N, 0); | 
| Chris Lattner | 0fb094f | 2005-11-19 01:44:53 +0000 | [diff] [blame] | 2014 | } | 
 | 2015 |  | 
| Chris Lattner | eb19e40 | 2005-11-30 22:45:14 +0000 | [diff] [blame] | 2016 | SDOperand SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc, | 
 | 2017 |                                      MVT::ValueType VT1, MVT::ValueType VT2, | 
 | 2018 |                                      SDOperand Op1, SDOperand Op2, | 
 | 2019 |                                      SDOperand Op3, SDOperand Op4) { | 
| Chris Lattner | c5e6c64 | 2005-12-01 18:00:57 +0000 | [diff] [blame] | 2020 |   // If an identical node already exists, use it. | 
 | 2021 |   std::vector<SDOperand> OpList; | 
 | 2022 |   OpList.push_back(Op1); OpList.push_back(Op2); OpList.push_back(Op3); | 
 | 2023 |   OpList.push_back(Op4); | 
 | 2024 |   std::vector<MVT::ValueType> VTList; | 
 | 2025 |   VTList.push_back(VT1); VTList.push_back(VT2); | 
 | 2026 |   SDNode *&ON = ArbitraryNodes[std::make_pair(ISD::BUILTIN_OP_END+TargetOpc, | 
 | 2027 |                                               std::make_pair(VTList, OpList))]; | 
 | 2028 |   if (ON) return SDOperand(ON, 0); | 
 | 2029 |  | 
| Chris Lattner | 0fb094f | 2005-11-19 01:44:53 +0000 | [diff] [blame] | 2030 |   RemoveNodeFromCSEMaps(N); | 
 | 2031 |   N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc); | 
 | 2032 |   setNodeValueTypes(N, VT1, VT2); | 
 | 2033 |   N->setOperands(Op1, Op2, Op3, Op4); | 
| Chris Lattner | c5e6c64 | 2005-12-01 18:00:57 +0000 | [diff] [blame] | 2034 |  | 
 | 2035 |   ON = N;   // Memoize the new node. | 
| Chris Lattner | eb19e40 | 2005-11-30 22:45:14 +0000 | [diff] [blame] | 2036 |   return SDOperand(N, 0); | 
| Chris Lattner | 0fb094f | 2005-11-19 01:44:53 +0000 | [diff] [blame] | 2037 | } | 
 | 2038 |  | 
| Chris Lattner | eb19e40 | 2005-11-30 22:45:14 +0000 | [diff] [blame] | 2039 | SDOperand SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc, | 
 | 2040 |                                      MVT::ValueType VT1, MVT::ValueType VT2, | 
 | 2041 |                                      SDOperand Op1, SDOperand Op2, | 
 | 2042 |                                      SDOperand Op3, SDOperand Op4,  | 
 | 2043 |                                      SDOperand Op5) { | 
| Chris Lattner | c5e6c64 | 2005-12-01 18:00:57 +0000 | [diff] [blame] | 2044 |   // If an identical node already exists, use it. | 
 | 2045 |   std::vector<SDOperand> OpList; | 
 | 2046 |   OpList.push_back(Op1); OpList.push_back(Op2); OpList.push_back(Op3); | 
 | 2047 |   OpList.push_back(Op4); OpList.push_back(Op5); | 
 | 2048 |   std::vector<MVT::ValueType> VTList; | 
 | 2049 |   VTList.push_back(VT1); VTList.push_back(VT2); | 
 | 2050 |   SDNode *&ON = ArbitraryNodes[std::make_pair(ISD::BUILTIN_OP_END+TargetOpc, | 
 | 2051 |                                               std::make_pair(VTList, OpList))]; | 
 | 2052 |   if (ON) return SDOperand(ON, 0); | 
 | 2053 |  | 
| Chris Lattner | 0fb094f | 2005-11-19 01:44:53 +0000 | [diff] [blame] | 2054 |   RemoveNodeFromCSEMaps(N); | 
 | 2055 |   N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc); | 
 | 2056 |   setNodeValueTypes(N, VT1, VT2); | 
 | 2057 |   N->setOperands(Op1, Op2, Op3, Op4, Op5); | 
| Chris Lattner | c5e6c64 | 2005-12-01 18:00:57 +0000 | [diff] [blame] | 2058 |    | 
 | 2059 |   ON = N;   // Memoize the new node. | 
| Chris Lattner | eb19e40 | 2005-11-30 22:45:14 +0000 | [diff] [blame] | 2060 |   return SDOperand(N, 0); | 
| Chris Lattner | 0fb094f | 2005-11-19 01:44:53 +0000 | [diff] [blame] | 2061 | } | 
 | 2062 |  | 
 | 2063 | // ReplaceAllUsesWith - Modify anything using 'From' to use 'To' instead. | 
| Chris Lattner | 8b8749f | 2005-08-17 19:00:20 +0000 | [diff] [blame] | 2064 | /// This can cause recursive merging of nodes in the DAG. | 
 | 2065 | /// | 
| Chris Lattner | 8b52f21 | 2005-08-26 18:36:28 +0000 | [diff] [blame] | 2066 | /// This version assumes From/To have a single result value. | 
 | 2067 | /// | 
| Chris Lattner | 1e111c7 | 2005-09-07 05:37:01 +0000 | [diff] [blame] | 2068 | void SelectionDAG::ReplaceAllUsesWith(SDOperand FromN, SDOperand ToN, | 
 | 2069 |                                       std::vector<SDNode*> *Deleted) { | 
| Chris Lattner | 8b52f21 | 2005-08-26 18:36:28 +0000 | [diff] [blame] | 2070 |   SDNode *From = FromN.Val, *To = ToN.Val; | 
 | 2071 |   assert(From->getNumValues() == 1 && To->getNumValues() == 1 && | 
 | 2072 |          "Cannot replace with this method!"); | 
| Chris Lattner | 8b8749f | 2005-08-17 19:00:20 +0000 | [diff] [blame] | 2073 |   assert(From != To && "Cannot replace uses of with self"); | 
| Chris Lattner | 8b52f21 | 2005-08-26 18:36:28 +0000 | [diff] [blame] | 2074 |    | 
| Chris Lattner | 8b8749f | 2005-08-17 19:00:20 +0000 | [diff] [blame] | 2075 |   while (!From->use_empty()) { | 
 | 2076 |     // Process users until they are all gone. | 
 | 2077 |     SDNode *U = *From->use_begin(); | 
 | 2078 |      | 
 | 2079 |     // This node is about to morph, remove its old self from the CSE maps. | 
 | 2080 |     RemoveNodeFromCSEMaps(U); | 
 | 2081 |      | 
| Chris Lattner | 65113b2 | 2005-11-08 22:07:03 +0000 | [diff] [blame] | 2082 |     for (SDOperand *I = U->OperandList, *E = U->OperandList+U->NumOperands; | 
 | 2083 |          I != E; ++I) | 
 | 2084 |       if (I->Val == From) { | 
| Chris Lattner | 8b52f21 | 2005-08-26 18:36:28 +0000 | [diff] [blame] | 2085 |         From->removeUser(U); | 
| Chris Lattner | 65113b2 | 2005-11-08 22:07:03 +0000 | [diff] [blame] | 2086 |         I->Val = To; | 
| Chris Lattner | 8b52f21 | 2005-08-26 18:36:28 +0000 | [diff] [blame] | 2087 |         To->addUser(U); | 
 | 2088 |       } | 
 | 2089 |  | 
 | 2090 |     // Now that we have modified U, add it back to the CSE maps.  If it already | 
 | 2091 |     // exists there, recursively merge the results together. | 
| Chris Lattner | 1e111c7 | 2005-09-07 05:37:01 +0000 | [diff] [blame] | 2092 |     if (SDNode *Existing = AddNonLeafNodeToCSEMaps(U)) { | 
 | 2093 |       ReplaceAllUsesWith(U, Existing, Deleted); | 
| Chris Lattner | 8b52f21 | 2005-08-26 18:36:28 +0000 | [diff] [blame] | 2094 |       // U is now dead. | 
| Chris Lattner | 1e111c7 | 2005-09-07 05:37:01 +0000 | [diff] [blame] | 2095 |       if (Deleted) Deleted->push_back(U); | 
 | 2096 |       DeleteNodeNotInCSEMaps(U); | 
 | 2097 |     } | 
| Chris Lattner | 8b52f21 | 2005-08-26 18:36:28 +0000 | [diff] [blame] | 2098 |   } | 
 | 2099 | } | 
 | 2100 |  | 
 | 2101 | /// ReplaceAllUsesWith - Modify anything using 'From' to use 'To' instead. | 
 | 2102 | /// This can cause recursive merging of nodes in the DAG. | 
 | 2103 | /// | 
 | 2104 | /// This version assumes From/To have matching types and numbers of result | 
 | 2105 | /// values. | 
 | 2106 | /// | 
| Chris Lattner | 1e111c7 | 2005-09-07 05:37:01 +0000 | [diff] [blame] | 2107 | void SelectionDAG::ReplaceAllUsesWith(SDNode *From, SDNode *To, | 
 | 2108 |                                       std::vector<SDNode*> *Deleted) { | 
| Chris Lattner | 8b52f21 | 2005-08-26 18:36:28 +0000 | [diff] [blame] | 2109 |   assert(From != To && "Cannot replace uses of with self"); | 
 | 2110 |   assert(From->getNumValues() == To->getNumValues() && | 
 | 2111 |          "Cannot use this version of ReplaceAllUsesWith!"); | 
 | 2112 |   if (From->getNumValues() == 1) {  // If possible, use the faster version. | 
| Chris Lattner | 1e111c7 | 2005-09-07 05:37:01 +0000 | [diff] [blame] | 2113 |     ReplaceAllUsesWith(SDOperand(From, 0), SDOperand(To, 0), Deleted); | 
| Chris Lattner | 8b52f21 | 2005-08-26 18:36:28 +0000 | [diff] [blame] | 2114 |     return; | 
 | 2115 |   } | 
 | 2116 |    | 
 | 2117 |   while (!From->use_empty()) { | 
 | 2118 |     // Process users until they are all gone. | 
 | 2119 |     SDNode *U = *From->use_begin(); | 
 | 2120 |      | 
 | 2121 |     // This node is about to morph, remove its old self from the CSE maps. | 
 | 2122 |     RemoveNodeFromCSEMaps(U); | 
 | 2123 |      | 
| Chris Lattner | 65113b2 | 2005-11-08 22:07:03 +0000 | [diff] [blame] | 2124 |     for (SDOperand *I = U->OperandList, *E = U->OperandList+U->NumOperands; | 
 | 2125 |          I != E; ++I) | 
 | 2126 |       if (I->Val == From) { | 
| Chris Lattner | 8b8749f | 2005-08-17 19:00:20 +0000 | [diff] [blame] | 2127 |         From->removeUser(U); | 
| Chris Lattner | 65113b2 | 2005-11-08 22:07:03 +0000 | [diff] [blame] | 2128 |         I->Val = To; | 
| Chris Lattner | 8b8749f | 2005-08-17 19:00:20 +0000 | [diff] [blame] | 2129 |         To->addUser(U); | 
 | 2130 |       } | 
 | 2131 |          | 
 | 2132 |     // Now that we have modified U, add it back to the CSE maps.  If it already | 
 | 2133 |     // exists there, recursively merge the results together. | 
| Chris Lattner | 1e111c7 | 2005-09-07 05:37:01 +0000 | [diff] [blame] | 2134 |     if (SDNode *Existing = AddNonLeafNodeToCSEMaps(U)) { | 
 | 2135 |       ReplaceAllUsesWith(U, Existing, Deleted); | 
 | 2136 |       // U is now dead. | 
 | 2137 |       if (Deleted) Deleted->push_back(U); | 
 | 2138 |       DeleteNodeNotInCSEMaps(U); | 
 | 2139 |     } | 
| Chris Lattner | 8b8749f | 2005-08-17 19:00:20 +0000 | [diff] [blame] | 2140 |   } | 
 | 2141 | } | 
 | 2142 |  | 
| Chris Lattner | 8b52f21 | 2005-08-26 18:36:28 +0000 | [diff] [blame] | 2143 | /// ReplaceAllUsesWith - Modify anything using 'From' to use 'To' instead. | 
 | 2144 | /// This can cause recursive merging of nodes in the DAG. | 
 | 2145 | /// | 
 | 2146 | /// This version can replace From with any result values.  To must match the | 
 | 2147 | /// number and types of values returned by From. | 
| Chris Lattner | 7b2880c | 2005-08-24 22:44:39 +0000 | [diff] [blame] | 2148 | void SelectionDAG::ReplaceAllUsesWith(SDNode *From, | 
| Chris Lattner | 1e111c7 | 2005-09-07 05:37:01 +0000 | [diff] [blame] | 2149 |                                       const std::vector<SDOperand> &To, | 
 | 2150 |                                       std::vector<SDNode*> *Deleted) { | 
| Chris Lattner | 7b2880c | 2005-08-24 22:44:39 +0000 | [diff] [blame] | 2151 |   assert(From->getNumValues() == To.size() && | 
 | 2152 |          "Incorrect number of values to replace with!"); | 
| Chris Lattner | ff01698 | 2005-08-28 23:59:36 +0000 | [diff] [blame] | 2153 |   if (To.size() == 1 && To[0].Val->getNumValues() == 1) { | 
| Chris Lattner | 7b2880c | 2005-08-24 22:44:39 +0000 | [diff] [blame] | 2154 |     // Degenerate case handled above. | 
| Chris Lattner | 1e111c7 | 2005-09-07 05:37:01 +0000 | [diff] [blame] | 2155 |     ReplaceAllUsesWith(SDOperand(From, 0), To[0], Deleted); | 
| Chris Lattner | 7b2880c | 2005-08-24 22:44:39 +0000 | [diff] [blame] | 2156 |     return; | 
 | 2157 |   } | 
 | 2158 |  | 
 | 2159 |   while (!From->use_empty()) { | 
 | 2160 |     // Process users until they are all gone. | 
 | 2161 |     SDNode *U = *From->use_begin(); | 
 | 2162 |      | 
 | 2163 |     // This node is about to morph, remove its old self from the CSE maps. | 
 | 2164 |     RemoveNodeFromCSEMaps(U); | 
 | 2165 |      | 
| Chris Lattner | 65113b2 | 2005-11-08 22:07:03 +0000 | [diff] [blame] | 2166 |     for (SDOperand *I = U->OperandList, *E = U->OperandList+U->NumOperands; | 
 | 2167 |          I != E; ++I) | 
 | 2168 |       if (I->Val == From) { | 
 | 2169 |         const SDOperand &ToOp = To[I->ResNo]; | 
| Chris Lattner | 7b2880c | 2005-08-24 22:44:39 +0000 | [diff] [blame] | 2170 |         From->removeUser(U); | 
| Chris Lattner | 65113b2 | 2005-11-08 22:07:03 +0000 | [diff] [blame] | 2171 |         *I = ToOp; | 
| Chris Lattner | 7b2880c | 2005-08-24 22:44:39 +0000 | [diff] [blame] | 2172 |         ToOp.Val->addUser(U); | 
 | 2173 |       } | 
 | 2174 |          | 
 | 2175 |     // Now that we have modified U, add it back to the CSE maps.  If it already | 
 | 2176 |     // exists there, recursively merge the results together. | 
| Chris Lattner | 1e111c7 | 2005-09-07 05:37:01 +0000 | [diff] [blame] | 2177 |     if (SDNode *Existing = AddNonLeafNodeToCSEMaps(U)) { | 
 | 2178 |       ReplaceAllUsesWith(U, Existing, Deleted); | 
 | 2179 |       // U is now dead. | 
 | 2180 |       if (Deleted) Deleted->push_back(U); | 
 | 2181 |       DeleteNodeNotInCSEMaps(U); | 
 | 2182 |     } | 
| Chris Lattner | 7b2880c | 2005-08-24 22:44:39 +0000 | [diff] [blame] | 2183 |   } | 
 | 2184 | } | 
 | 2185 |  | 
 | 2186 |  | 
| Jim Laskey | 58b968b | 2005-08-17 20:08:02 +0000 | [diff] [blame] | 2187 | //===----------------------------------------------------------------------===// | 
 | 2188 | //                              SDNode Class | 
 | 2189 | //===----------------------------------------------------------------------===// | 
| Chris Lattner | 149c58c | 2005-08-16 18:17:10 +0000 | [diff] [blame] | 2190 |  | 
| Chris Lattner | a325511 | 2005-11-08 23:30:28 +0000 | [diff] [blame] | 2191 |  | 
 | 2192 | /// getValueTypeList - Return a pointer to the specified value type. | 
 | 2193 | /// | 
 | 2194 | MVT::ValueType *SDNode::getValueTypeList(MVT::ValueType VT) { | 
 | 2195 |   static MVT::ValueType VTs[MVT::LAST_VALUETYPE]; | 
 | 2196 |   VTs[VT] = VT; | 
 | 2197 |   return &VTs[VT]; | 
 | 2198 | } | 
 | 2199 |  | 
| Chris Lattner | 5c88456 | 2005-01-12 18:37:47 +0000 | [diff] [blame] | 2200 | /// hasNUsesOfValue - Return true if there are exactly NUSES uses of the | 
 | 2201 | /// indicated value.  This method ignores uses of other values defined by this | 
 | 2202 | /// operation. | 
 | 2203 | bool SDNode::hasNUsesOfValue(unsigned NUses, unsigned Value) { | 
 | 2204 |   assert(Value < getNumValues() && "Bad value!"); | 
 | 2205 |  | 
 | 2206 |   // If there is only one value, this is easy. | 
 | 2207 |   if (getNumValues() == 1) | 
 | 2208 |     return use_size() == NUses; | 
 | 2209 |   if (Uses.size() < NUses) return false; | 
 | 2210 |  | 
 | 2211 |   SDOperand TheValue(this, Value); | 
 | 2212 |  | 
 | 2213 |   std::set<SDNode*> UsersHandled; | 
 | 2214 |  | 
 | 2215 |   for (std::vector<SDNode*>::iterator UI = Uses.begin(), E = Uses.end(); | 
 | 2216 |        UI != E; ++UI) { | 
 | 2217 |     SDNode *User = *UI; | 
 | 2218 |     if (User->getNumOperands() == 1 || | 
 | 2219 |         UsersHandled.insert(User).second)     // First time we've seen this? | 
 | 2220 |       for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i) | 
 | 2221 |         if (User->getOperand(i) == TheValue) { | 
 | 2222 |           if (NUses == 0) | 
 | 2223 |             return false;   // too many uses | 
 | 2224 |           --NUses; | 
 | 2225 |         } | 
 | 2226 |   } | 
 | 2227 |  | 
 | 2228 |   // Found exactly the right number of uses? | 
 | 2229 |   return NUses == 0; | 
 | 2230 | } | 
 | 2231 |  | 
 | 2232 |  | 
| Chris Lattner | f3e133a | 2005-08-16 18:33:07 +0000 | [diff] [blame] | 2233 | const char *SDNode::getOperationName(const SelectionDAG *G) const { | 
| Chris Lattner | d75f19f | 2005-01-10 23:25:25 +0000 | [diff] [blame] | 2234 |   switch (getOpcode()) { | 
| Chris Lattner | f3e133a | 2005-08-16 18:33:07 +0000 | [diff] [blame] | 2235 |   default: | 
 | 2236 |     if (getOpcode() < ISD::BUILTIN_OP_END) | 
 | 2237 |       return "<<Unknown DAG Node>>"; | 
 | 2238 |     else { | 
| Evan Cheng | 7226158 | 2005-12-20 06:22:03 +0000 | [diff] [blame] | 2239 |       if (G) { | 
| Chris Lattner | f3e133a | 2005-08-16 18:33:07 +0000 | [diff] [blame] | 2240 |         if (const TargetInstrInfo *TII = G->getTarget().getInstrInfo()) | 
| Chris Lattner | 08addbd | 2005-09-09 22:35:03 +0000 | [diff] [blame] | 2241 |           if (getOpcode()-ISD::BUILTIN_OP_END < TII->getNumOpcodes()) | 
 | 2242 |             return TII->getName(getOpcode()-ISD::BUILTIN_OP_END); | 
| Evan Cheng | 115c036 | 2005-12-19 23:11:49 +0000 | [diff] [blame] | 2243 |  | 
| Evan Cheng | 7226158 | 2005-12-20 06:22:03 +0000 | [diff] [blame] | 2244 |         TargetLowering &TLI = G->getTargetLoweringInfo(); | 
 | 2245 |         const char *Name = | 
 | 2246 |           TLI.getTargetNodeName(getOpcode()); | 
 | 2247 |         if (Name) return Name; | 
 | 2248 |       } | 
 | 2249 |  | 
 | 2250 |       return "<<Unknown Target Node>>"; | 
| Chris Lattner | f3e133a | 2005-08-16 18:33:07 +0000 | [diff] [blame] | 2251 |     } | 
 | 2252 |     | 
| Andrew Lenharth | 9576212 | 2005-03-31 21:24:06 +0000 | [diff] [blame] | 2253 |   case ISD::PCMARKER:      return "PCMarker"; | 
| Andrew Lenharth | 51b8d54 | 2005-11-11 16:47:30 +0000 | [diff] [blame] | 2254 |   case ISD::READCYCLECOUNTER: return "ReadCycleCounter"; | 
| Chris Lattner | 2bf3c26 | 2005-05-09 04:08:27 +0000 | [diff] [blame] | 2255 |   case ISD::SRCVALUE:      return "SrcValue"; | 
| Chris Lattner | a23e815 | 2005-08-18 03:31:02 +0000 | [diff] [blame] | 2256 |   case ISD::VALUETYPE:     return "ValueType"; | 
| Chris Lattner | 36ce691 | 2005-11-29 06:21:05 +0000 | [diff] [blame] | 2257 |   case ISD::STRING:        return "String"; | 
| Chris Lattner | d75f19f | 2005-01-10 23:25:25 +0000 | [diff] [blame] | 2258 |   case ISD::EntryToken:    return "EntryToken"; | 
| Chris Lattner | 282c5ca | 2005-01-13 17:59:10 +0000 | [diff] [blame] | 2259 |   case ISD::TokenFactor:   return "TokenFactor"; | 
| Nate Begeman | 56eb868 | 2005-08-30 02:44:00 +0000 | [diff] [blame] | 2260 |   case ISD::AssertSext:    return "AssertSext"; | 
 | 2261 |   case ISD::AssertZext:    return "AssertZext"; | 
| Chris Lattner | d75f19f | 2005-01-10 23:25:25 +0000 | [diff] [blame] | 2262 |   case ISD::Constant:      return "Constant"; | 
| Chris Lattner | 37bfbb4 | 2005-08-17 00:34:06 +0000 | [diff] [blame] | 2263 |   case ISD::TargetConstant: return "TargetConstant"; | 
| Chris Lattner | d75f19f | 2005-01-10 23:25:25 +0000 | [diff] [blame] | 2264 |   case ISD::ConstantFP:    return "ConstantFP"; | 
| Nate Begeman | 8cfa57b | 2005-12-06 06:18:55 +0000 | [diff] [blame] | 2265 |   case ISD::ConstantVec:   return "ConstantVec"; | 
| Chris Lattner | d75f19f | 2005-01-10 23:25:25 +0000 | [diff] [blame] | 2266 |   case ISD::GlobalAddress: return "GlobalAddress"; | 
| Chris Lattner | aaaa0b6 | 2005-08-19 22:31:04 +0000 | [diff] [blame] | 2267 |   case ISD::TargetGlobalAddress: return "TargetGlobalAddress"; | 
| Chris Lattner | d75f19f | 2005-01-10 23:25:25 +0000 | [diff] [blame] | 2268 |   case ISD::FrameIndex:    return "FrameIndex"; | 
| Chris Lattner | afb2dd4 | 2005-08-25 00:43:01 +0000 | [diff] [blame] | 2269 |   case ISD::TargetFrameIndex: return "TargetFrameIndex"; | 
| Chris Lattner | d75f19f | 2005-01-10 23:25:25 +0000 | [diff] [blame] | 2270 |   case ISD::BasicBlock:    return "BasicBlock"; | 
| Chris Lattner | d5d0f9b | 2005-08-16 21:55:35 +0000 | [diff] [blame] | 2271 |   case ISD::Register:      return "Register"; | 
| Chris Lattner | d75f19f | 2005-01-10 23:25:25 +0000 | [diff] [blame] | 2272 |   case ISD::ExternalSymbol: return "ExternalSymbol"; | 
| Andrew Lenharth | 2a2de66 | 2005-10-23 03:40:17 +0000 | [diff] [blame] | 2273 |   case ISD::TargetExternalSymbol: return "TargetExternalSymbol"; | 
| Chris Lattner | 5839bf2 | 2005-08-26 17:15:30 +0000 | [diff] [blame] | 2274 |   case ISD::ConstantPool:  return "ConstantPool"; | 
 | 2275 |   case ISD::TargetConstantPool:  return "TargetConstantPool"; | 
| Chris Lattner | d75f19f | 2005-01-10 23:25:25 +0000 | [diff] [blame] | 2276 |   case ISD::CopyToReg:     return "CopyToReg"; | 
 | 2277 |   case ISD::CopyFromReg:   return "CopyFromReg"; | 
| Nate Begeman | fc1b1da | 2005-04-01 22:34:39 +0000 | [diff] [blame] | 2278 |   case ISD::UNDEF:         return "undef"; | 
| Chris Lattner | cc0aad2 | 2006-01-15 08:39:35 +0000 | [diff] [blame] | 2279 |   case ISD::MERGE_VALUES:  return "mergevalues"; | 
| Chris Lattner | ce7518c | 2006-01-26 22:24:51 +0000 | [diff] [blame] | 2280 |   case ISD::INLINEASM:     return "inlineasm"; | 
 | 2281 |      | 
| Chris Lattner | ff9fd0a | 2005-04-02 04:58:41 +0000 | [diff] [blame] | 2282 |   // Unary operators | 
 | 2283 |   case ISD::FABS:   return "fabs"; | 
 | 2284 |   case ISD::FNEG:   return "fneg"; | 
| Chris Lattner | 7f64464 | 2005-04-28 21:44:03 +0000 | [diff] [blame] | 2285 |   case ISD::FSQRT:  return "fsqrt"; | 
 | 2286 |   case ISD::FSIN:   return "fsin"; | 
 | 2287 |   case ISD::FCOS:   return "fcos"; | 
| Chris Lattner | ff9fd0a | 2005-04-02 04:58:41 +0000 | [diff] [blame] | 2288 |  | 
 | 2289 |   // Binary operators | 
| Chris Lattner | d75f19f | 2005-01-10 23:25:25 +0000 | [diff] [blame] | 2290 |   case ISD::ADD:    return "add"; | 
 | 2291 |   case ISD::SUB:    return "sub"; | 
 | 2292 |   case ISD::MUL:    return "mul"; | 
| Nate Begeman | 1867054 | 2005-04-05 22:36:56 +0000 | [diff] [blame] | 2293 |   case ISD::MULHU:  return "mulhu"; | 
 | 2294 |   case ISD::MULHS:  return "mulhs"; | 
| Chris Lattner | d75f19f | 2005-01-10 23:25:25 +0000 | [diff] [blame] | 2295 |   case ISD::SDIV:   return "sdiv"; | 
 | 2296 |   case ISD::UDIV:   return "udiv"; | 
 | 2297 |   case ISD::SREM:   return "srem"; | 
 | 2298 |   case ISD::UREM:   return "urem"; | 
 | 2299 |   case ISD::AND:    return "and"; | 
 | 2300 |   case ISD::OR:     return "or"; | 
 | 2301 |   case ISD::XOR:    return "xor"; | 
 | 2302 |   case ISD::SHL:    return "shl"; | 
 | 2303 |   case ISD::SRA:    return "sra"; | 
 | 2304 |   case ISD::SRL:    return "srl"; | 
| Nate Begeman | 35ef913 | 2006-01-11 21:21:00 +0000 | [diff] [blame] | 2305 |   case ISD::ROTL:   return "rotl"; | 
 | 2306 |   case ISD::ROTR:   return "rotr"; | 
| Chris Lattner | 01b3d73 | 2005-09-28 22:28:18 +0000 | [diff] [blame] | 2307 |   case ISD::FADD:   return "fadd"; | 
 | 2308 |   case ISD::FSUB:   return "fsub"; | 
 | 2309 |   case ISD::FMUL:   return "fmul"; | 
 | 2310 |   case ISD::FDIV:   return "fdiv"; | 
 | 2311 |   case ISD::FREM:   return "frem"; | 
| Nate Begeman | 5fbb5d2 | 2005-11-19 00:36:38 +0000 | [diff] [blame] | 2312 |   case ISD::VADD:   return "vadd"; | 
 | 2313 |   case ISD::VSUB:   return "vsub"; | 
 | 2314 |   case ISD::VMUL:   return "vmul"; | 
| Chris Lattner | 01b3d73 | 2005-09-28 22:28:18 +0000 | [diff] [blame] | 2315 |      | 
| Chris Lattner | 7cf7e3f | 2005-08-09 20:20:18 +0000 | [diff] [blame] | 2316 |   case ISD::SETCC:       return "setcc"; | 
 | 2317 |   case ISD::SELECT:      return "select"; | 
| Nate Begeman | 9373a81 | 2005-08-10 20:51:12 +0000 | [diff] [blame] | 2318 |   case ISD::SELECT_CC:   return "select_cc"; | 
| Chris Lattner | 17eee18 | 2005-01-20 18:50:55 +0000 | [diff] [blame] | 2319 |   case ISD::ADD_PARTS:   return "add_parts"; | 
 | 2320 |   case ISD::SUB_PARTS:   return "sub_parts"; | 
| Chris Lattner | 41be951 | 2005-04-02 03:30:42 +0000 | [diff] [blame] | 2321 |   case ISD::SHL_PARTS:   return "shl_parts"; | 
 | 2322 |   case ISD::SRA_PARTS:   return "sra_parts"; | 
 | 2323 |   case ISD::SRL_PARTS:   return "srl_parts"; | 
| Chris Lattner | d75f19f | 2005-01-10 23:25:25 +0000 | [diff] [blame] | 2324 |  | 
| Chris Lattner | 7f64464 | 2005-04-28 21:44:03 +0000 | [diff] [blame] | 2325 |   // Conversion operators. | 
| Chris Lattner | d75f19f | 2005-01-10 23:25:25 +0000 | [diff] [blame] | 2326 |   case ISD::SIGN_EXTEND: return "sign_extend"; | 
 | 2327 |   case ISD::ZERO_EXTEND: return "zero_extend"; | 
| Chris Lattner | 4ed11b4 | 2005-09-02 00:17:32 +0000 | [diff] [blame] | 2328 |   case ISD::ANY_EXTEND:  return "any_extend"; | 
| Chris Lattner | 859157d | 2005-01-15 06:17:04 +0000 | [diff] [blame] | 2329 |   case ISD::SIGN_EXTEND_INREG: return "sign_extend_inreg"; | 
| Chris Lattner | d75f19f | 2005-01-10 23:25:25 +0000 | [diff] [blame] | 2330 |   case ISD::TRUNCATE:    return "truncate"; | 
 | 2331 |   case ISD::FP_ROUND:    return "fp_round"; | 
| Chris Lattner | 859157d | 2005-01-15 06:17:04 +0000 | [diff] [blame] | 2332 |   case ISD::FP_ROUND_INREG: return "fp_round_inreg"; | 
| Chris Lattner | d75f19f | 2005-01-10 23:25:25 +0000 | [diff] [blame] | 2333 |   case ISD::FP_EXTEND:   return "fp_extend"; | 
 | 2334 |  | 
 | 2335 |   case ISD::SINT_TO_FP:  return "sint_to_fp"; | 
 | 2336 |   case ISD::UINT_TO_FP:  return "uint_to_fp"; | 
 | 2337 |   case ISD::FP_TO_SINT:  return "fp_to_sint"; | 
 | 2338 |   case ISD::FP_TO_UINT:  return "fp_to_uint"; | 
| Chris Lattner | 3548189 | 2005-12-23 00:16:34 +0000 | [diff] [blame] | 2339 |   case ISD::BIT_CONVERT: return "bit_convert"; | 
| Chris Lattner | d75f19f | 2005-01-10 23:25:25 +0000 | [diff] [blame] | 2340 |  | 
 | 2341 |     // Control flow instructions | 
 | 2342 |   case ISD::BR:      return "br"; | 
 | 2343 |   case ISD::BRCOND:  return "brcond"; | 
| Chris Lattner | ef847df | 2005-04-09 03:27:28 +0000 | [diff] [blame] | 2344 |   case ISD::BRCONDTWOWAY:  return "brcondtwoway"; | 
| Nate Begeman | 7cbd525 | 2005-08-16 19:49:35 +0000 | [diff] [blame] | 2345 |   case ISD::BR_CC:  return "br_cc"; | 
 | 2346 |   case ISD::BRTWOWAY_CC:  return "brtwoway_cc"; | 
| Chris Lattner | d75f19f | 2005-01-10 23:25:25 +0000 | [diff] [blame] | 2347 |   case ISD::RET:     return "ret"; | 
| Chris Lattner | a364fa1 | 2005-05-12 23:51:40 +0000 | [diff] [blame] | 2348 |   case ISD::CALLSEQ_START:  return "callseq_start"; | 
 | 2349 |   case ISD::CALLSEQ_END:    return "callseq_end"; | 
| Chris Lattner | d75f19f | 2005-01-10 23:25:25 +0000 | [diff] [blame] | 2350 |  | 
 | 2351 |     // Other operators | 
| Nate Begeman | acc398c | 2006-01-25 18:21:52 +0000 | [diff] [blame] | 2352 |   case ISD::LOAD:               return "load"; | 
 | 2353 |   case ISD::STORE:              return "store"; | 
 | 2354 |   case ISD::VLOAD:              return "vload"; | 
 | 2355 |   case ISD::EXTLOAD:            return "extload"; | 
 | 2356 |   case ISD::SEXTLOAD:           return "sextload"; | 
 | 2357 |   case ISD::ZEXTLOAD:           return "zextload"; | 
 | 2358 |   case ISD::TRUNCSTORE:         return "truncstore"; | 
 | 2359 |   case ISD::VAARG:              return "vaarg"; | 
 | 2360 |   case ISD::VACOPY:             return "vacopy"; | 
 | 2361 |   case ISD::VAEND:              return "vaend"; | 
 | 2362 |   case ISD::VASTART:            return "vastart"; | 
| Chris Lattner | d75f19f | 2005-01-10 23:25:25 +0000 | [diff] [blame] | 2363 |   case ISD::DYNAMIC_STACKALLOC: return "dynamic_stackalloc"; | 
| Chris Lattner | 5a67afc | 2006-01-13 02:39:42 +0000 | [diff] [blame] | 2364 |   case ISD::EXTRACT_ELEMENT:    return "extract_element"; | 
 | 2365 |   case ISD::BUILD_PAIR:         return "build_pair"; | 
 | 2366 |   case ISD::STACKSAVE:          return "stacksave"; | 
 | 2367 |   case ISD::STACKRESTORE:       return "stackrestore"; | 
 | 2368 |      | 
 | 2369 |   // Block memory operations. | 
| Chris Lattner | 4c633e8 | 2005-01-11 05:57:01 +0000 | [diff] [blame] | 2370 |   case ISD::MEMSET:  return "memset"; | 
 | 2371 |   case ISD::MEMCPY:  return "memcpy"; | 
 | 2372 |   case ISD::MEMMOVE: return "memmove"; | 
| Chris Lattner | d75f19f | 2005-01-10 23:25:25 +0000 | [diff] [blame] | 2373 |  | 
| Nate Begeman | 1b5db7a | 2006-01-16 08:07:10 +0000 | [diff] [blame] | 2374 |   // Bit manipulation | 
 | 2375 |   case ISD::BSWAP:   return "bswap"; | 
| Chris Lattner | 276260b | 2005-05-11 04:50:30 +0000 | [diff] [blame] | 2376 |   case ISD::CTPOP:   return "ctpop"; | 
 | 2377 |   case ISD::CTTZ:    return "cttz"; | 
 | 2378 |   case ISD::CTLZ:    return "ctlz"; | 
 | 2379 |  | 
 | 2380 |   // IO Intrinsics | 
| Chris Lattner | 3c69101 | 2005-05-09 20:22:17 +0000 | [diff] [blame] | 2381 |   case ISD::READPORT: return "readport"; | 
 | 2382 |   case ISD::WRITEPORT: return "writeport"; | 
 | 2383 |   case ISD::READIO: return "readio"; | 
 | 2384 |   case ISD::WRITEIO: return "writeio"; | 
 | 2385 |  | 
| Chris Lattner | 36ce691 | 2005-11-29 06:21:05 +0000 | [diff] [blame] | 2386 |   // Debug info | 
 | 2387 |   case ISD::LOCATION: return "location"; | 
| Jim Laskey | f5395ce | 2005-12-16 22:45:29 +0000 | [diff] [blame] | 2388 |   case ISD::DEBUG_LOC: return "debug_loc"; | 
| Jim Laskey | abf6d17 | 2006-01-05 01:25:28 +0000 | [diff] [blame] | 2389 |   case ISD::DEBUG_LABEL: return "debug_label"; | 
| Chris Lattner | 36ce691 | 2005-11-29 06:21:05 +0000 | [diff] [blame] | 2390 |  | 
| Chris Lattner | 7cf7e3f | 2005-08-09 20:20:18 +0000 | [diff] [blame] | 2391 |   case ISD::CONDCODE: | 
 | 2392 |     switch (cast<CondCodeSDNode>(this)->get()) { | 
| Chris Lattner | d75f19f | 2005-01-10 23:25:25 +0000 | [diff] [blame] | 2393 |     default: assert(0 && "Unknown setcc condition!"); | 
| Chris Lattner | 7cf7e3f | 2005-08-09 20:20:18 +0000 | [diff] [blame] | 2394 |     case ISD::SETOEQ:  return "setoeq"; | 
 | 2395 |     case ISD::SETOGT:  return "setogt"; | 
 | 2396 |     case ISD::SETOGE:  return "setoge"; | 
 | 2397 |     case ISD::SETOLT:  return "setolt"; | 
 | 2398 |     case ISD::SETOLE:  return "setole"; | 
 | 2399 |     case ISD::SETONE:  return "setone"; | 
| Misha Brukman | edf128a | 2005-04-21 22:36:52 +0000 | [diff] [blame] | 2400 |  | 
| Chris Lattner | 7cf7e3f | 2005-08-09 20:20:18 +0000 | [diff] [blame] | 2401 |     case ISD::SETO:    return "seto"; | 
 | 2402 |     case ISD::SETUO:   return "setuo"; | 
 | 2403 |     case ISD::SETUEQ:  return "setue"; | 
 | 2404 |     case ISD::SETUGT:  return "setugt"; | 
 | 2405 |     case ISD::SETUGE:  return "setuge"; | 
 | 2406 |     case ISD::SETULT:  return "setult"; | 
 | 2407 |     case ISD::SETULE:  return "setule"; | 
 | 2408 |     case ISD::SETUNE:  return "setune"; | 
| Misha Brukman | edf128a | 2005-04-21 22:36:52 +0000 | [diff] [blame] | 2409 |  | 
| Chris Lattner | 7cf7e3f | 2005-08-09 20:20:18 +0000 | [diff] [blame] | 2410 |     case ISD::SETEQ:   return "seteq"; | 
 | 2411 |     case ISD::SETGT:   return "setgt"; | 
 | 2412 |     case ISD::SETGE:   return "setge"; | 
 | 2413 |     case ISD::SETLT:   return "setlt"; | 
 | 2414 |     case ISD::SETLE:   return "setle"; | 
 | 2415 |     case ISD::SETNE:   return "setne"; | 
| Chris Lattner | d75f19f | 2005-01-10 23:25:25 +0000 | [diff] [blame] | 2416 |     } | 
 | 2417 |   } | 
 | 2418 | } | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 2419 |  | 
| Chris Lattner | f3e133a | 2005-08-16 18:33:07 +0000 | [diff] [blame] | 2420 | void SDNode::dump() const { dump(0); } | 
 | 2421 | void SDNode::dump(const SelectionDAG *G) const { | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 2422 |   std::cerr << (void*)this << ": "; | 
 | 2423 |  | 
 | 2424 |   for (unsigned i = 0, e = getNumValues(); i != e; ++i) { | 
 | 2425 |     if (i) std::cerr << ","; | 
| Chris Lattner | 4ea6924 | 2005-01-15 07:14:32 +0000 | [diff] [blame] | 2426 |     if (getValueType(i) == MVT::Other) | 
 | 2427 |       std::cerr << "ch"; | 
 | 2428 |     else | 
 | 2429 |       std::cerr << MVT::getValueTypeString(getValueType(i)); | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 2430 |   } | 
| Chris Lattner | f3e133a | 2005-08-16 18:33:07 +0000 | [diff] [blame] | 2431 |   std::cerr << " = " << getOperationName(G); | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 2432 |  | 
 | 2433 |   std::cerr << " "; | 
 | 2434 |   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { | 
 | 2435 |     if (i) std::cerr << ", "; | 
 | 2436 |     std::cerr << (void*)getOperand(i).Val; | 
 | 2437 |     if (unsigned RN = getOperand(i).ResNo) | 
 | 2438 |       std::cerr << ":" << RN; | 
 | 2439 |   } | 
 | 2440 |  | 
 | 2441 |   if (const ConstantSDNode *CSDN = dyn_cast<ConstantSDNode>(this)) { | 
 | 2442 |     std::cerr << "<" << CSDN->getValue() << ">"; | 
 | 2443 |   } else if (const ConstantFPSDNode *CSDN = dyn_cast<ConstantFPSDNode>(this)) { | 
 | 2444 |     std::cerr << "<" << CSDN->getValue() << ">"; | 
| Misha Brukman | edf128a | 2005-04-21 22:36:52 +0000 | [diff] [blame] | 2445 |   } else if (const GlobalAddressSDNode *GADN = | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 2446 |              dyn_cast<GlobalAddressSDNode>(this)) { | 
| Evan Cheng | 61ca74b | 2005-11-30 02:04:11 +0000 | [diff] [blame] | 2447 |     int offset = GADN->getOffset(); | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 2448 |     std::cerr << "<"; | 
 | 2449 |     WriteAsOperand(std::cerr, GADN->getGlobal()) << ">"; | 
| Evan Cheng | 61ca74b | 2005-11-30 02:04:11 +0000 | [diff] [blame] | 2450 |     if (offset > 0) | 
 | 2451 |       std::cerr << " + " << offset; | 
 | 2452 |     else | 
 | 2453 |       std::cerr << " " << offset; | 
| Misha Brukman | dedf2bd | 2005-04-22 04:01:18 +0000 | [diff] [blame] | 2454 |   } else if (const FrameIndexSDNode *FIDN = dyn_cast<FrameIndexSDNode>(this)) { | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 2455 |     std::cerr << "<" << FIDN->getIndex() << ">"; | 
 | 2456 |   } else if (const ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(this)){ | 
| Chris Lattner | 5839bf2 | 2005-08-26 17:15:30 +0000 | [diff] [blame] | 2457 |     std::cerr << "<" << *CP->get() << ">"; | 
| Misha Brukman | dedf2bd | 2005-04-22 04:01:18 +0000 | [diff] [blame] | 2458 |   } else if (const BasicBlockSDNode *BBDN = dyn_cast<BasicBlockSDNode>(this)) { | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 2459 |     std::cerr << "<"; | 
 | 2460 |     const Value *LBB = (const Value*)BBDN->getBasicBlock()->getBasicBlock(); | 
 | 2461 |     if (LBB) | 
 | 2462 |       std::cerr << LBB->getName() << " "; | 
 | 2463 |     std::cerr << (const void*)BBDN->getBasicBlock() << ">"; | 
| Chris Lattner | fa164b6 | 2005-08-19 21:34:13 +0000 | [diff] [blame] | 2464 |   } else if (const RegisterSDNode *R = dyn_cast<RegisterSDNode>(this)) { | 
| Evan Cheng | 140e99b | 2006-01-11 22:13:48 +0000 | [diff] [blame] | 2465 |     if (G && R->getReg() && MRegisterInfo::isPhysicalRegister(R->getReg())) { | 
| Chris Lattner | 7228aa7 | 2005-08-19 21:21:16 +0000 | [diff] [blame] | 2466 |       std::cerr << " " <<G->getTarget().getRegisterInfo()->getName(R->getReg()); | 
 | 2467 |     } else { | 
 | 2468 |       std::cerr << " #" << R->getReg(); | 
 | 2469 |     } | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 2470 |   } else if (const ExternalSymbolSDNode *ES = | 
 | 2471 |              dyn_cast<ExternalSymbolSDNode>(this)) { | 
 | 2472 |     std::cerr << "'" << ES->getSymbol() << "'"; | 
| Chris Lattner | 2bf3c26 | 2005-05-09 04:08:27 +0000 | [diff] [blame] | 2473 |   } else if (const SrcValueSDNode *M = dyn_cast<SrcValueSDNode>(this)) { | 
 | 2474 |     if (M->getValue()) | 
 | 2475 |       std::cerr << "<" << M->getValue() << ":" << M->getOffset() << ">"; | 
 | 2476 |     else | 
 | 2477 |       std::cerr << "<null:" << M->getOffset() << ">"; | 
| Chris Lattner | a23e815 | 2005-08-18 03:31:02 +0000 | [diff] [blame] | 2478 |   } else if (const VTSDNode *N = dyn_cast<VTSDNode>(this)) { | 
 | 2479 |     std::cerr << ":" << getValueTypeString(N->getVT()); | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 2480 |   } | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 2481 | } | 
 | 2482 |  | 
| Chris Lattner | de202b3 | 2005-11-09 23:47:37 +0000 | [diff] [blame] | 2483 | static void DumpNodes(const SDNode *N, unsigned indent, const SelectionDAG *G) { | 
| Chris Lattner | ea946cd | 2005-01-09 20:38:33 +0000 | [diff] [blame] | 2484 |   for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) | 
 | 2485 |     if (N->getOperand(i).Val->hasOneUse()) | 
| Chris Lattner | f3e133a | 2005-08-16 18:33:07 +0000 | [diff] [blame] | 2486 |       DumpNodes(N->getOperand(i).Val, indent+2, G); | 
| Chris Lattner | ea946cd | 2005-01-09 20:38:33 +0000 | [diff] [blame] | 2487 |     else | 
 | 2488 |       std::cerr << "\n" << std::string(indent+2, ' ') | 
 | 2489 |                 << (void*)N->getOperand(i).Val << ": <multiple use>"; | 
| Misha Brukman | edf128a | 2005-04-21 22:36:52 +0000 | [diff] [blame] | 2490 |  | 
| Chris Lattner | ea946cd | 2005-01-09 20:38:33 +0000 | [diff] [blame] | 2491 |  | 
 | 2492 |   std::cerr << "\n" << std::string(indent, ' '); | 
| Chris Lattner | f3e133a | 2005-08-16 18:33:07 +0000 | [diff] [blame] | 2493 |   N->dump(G); | 
| Chris Lattner | ea946cd | 2005-01-09 20:38:33 +0000 | [diff] [blame] | 2494 | } | 
 | 2495 |  | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 2496 | void SelectionDAG::dump() const { | 
 | 2497 |   std::cerr << "SelectionDAG has " << AllNodes.size() << " nodes:"; | 
| Chris Lattner | de202b3 | 2005-11-09 23:47:37 +0000 | [diff] [blame] | 2498 |   std::vector<const SDNode*> Nodes; | 
 | 2499 |   for (allnodes_const_iterator I = allnodes_begin(), E = allnodes_end(); | 
 | 2500 |        I != E; ++I) | 
 | 2501 |     Nodes.push_back(I); | 
 | 2502 |    | 
| Chris Lattner | 49d2471 | 2005-01-09 20:26:36 +0000 | [diff] [blame] | 2503 |   std::sort(Nodes.begin(), Nodes.end()); | 
 | 2504 |  | 
 | 2505 |   for (unsigned i = 0, e = Nodes.size(); i != e; ++i) { | 
| Chris Lattner | ea946cd | 2005-01-09 20:38:33 +0000 | [diff] [blame] | 2506 |     if (!Nodes[i]->hasOneUse() && Nodes[i] != getRoot().Val) | 
| Chris Lattner | f3e133a | 2005-08-16 18:33:07 +0000 | [diff] [blame] | 2507 |       DumpNodes(Nodes[i], 2, this); | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 2508 |   } | 
| Chris Lattner | ea946cd | 2005-01-09 20:38:33 +0000 | [diff] [blame] | 2509 |  | 
| Chris Lattner | f3e133a | 2005-08-16 18:33:07 +0000 | [diff] [blame] | 2510 |   DumpNodes(getRoot().Val, 2, this); | 
| Chris Lattner | ea946cd | 2005-01-09 20:38:33 +0000 | [diff] [blame] | 2511 |  | 
| Chris Lattner | c3aae25 | 2005-01-07 07:46:32 +0000 | [diff] [blame] | 2512 |   std::cerr << "\n\n"; | 
 | 2513 | } | 
 | 2514 |  |