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