Remove the two-argument (inferred cast) form of ConstantExpr::getCast now
[oota-llvm.git] / lib / CodeGen / SelectionDAG / SelectionDAG.cpp
index 3d8441c51240dde8a6d2f34935badac93744895a..5f92df3f2d54d59baf6b64ab073292a035290961 100644 (file)
 #include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringExtras.h"
-#include <iostream>
 #include <set>
-#include <cmath>
 #include <algorithm>
+#include <cmath>
 using namespace llvm;
 
 /// makeVTList - Return an instance of the SDVTList struct initialized with the
@@ -39,15 +38,6 @@ static SDVTList makeVTList(const MVT::ValueType *VTs, unsigned NumVTs) {
   return Res;
 }
 
-// isInvertibleForFree - Return true if there is no cost to emitting the logical
-// inverse of this node.
-static bool isInvertibleForFree(SDOperand N) {
-  if (isa<ConstantSDNode>(N.Val)) return true;
-  if (N.Val->getOpcode() == ISD::SETCC && N.Val->hasOneUse())
-    return true;
-  return false;
-}
-
 //===----------------------------------------------------------------------===//
 //                              ConstantFPSDNode Class
 //===----------------------------------------------------------------------===//
@@ -255,12 +245,6 @@ const TargetMachine &SelectionDAG::getTarget() const {
 //                           SDNode Profile Support
 //===----------------------------------------------------------------------===//
 
-/// getNodeIDOpcode - Return the opcode that has been set for this NodeID.
-///
-static unsigned getNodeIDOpcode(FoldingSetNodeID &ID)  {
-  return ID.getRawData(0);
-}
-
 /// AddNodeIDOpcode - Add the node opcode to the NodeID data.
 ///
 static void AddNodeIDOpcode(FoldingSetNodeID &ID, unsigned OpC)  {
@@ -574,7 +558,7 @@ void SelectionDAG::RemoveNodeFromCSEMaps(SDNode *N) {
   if (!Erased && N->getValueType(N->getNumValues()-1) != MVT::Flag &&
       !N->isTargetOpcode()) {
     N->dump();
-    std::cerr << "\n";
+    cerr << "\n";
     assert(0 && "Node is not in map!");
   }
 #endif
@@ -1146,7 +1130,7 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
   case ISD::BIT_CONVERT:
     // Basic sanity checking.
     assert(MVT::getSizeInBits(VT) == MVT::getSizeInBits(Operand.getValueType())
-           && "Cannot BIT_CONVERT between two different types!");
+           && "Cannot BIT_CONVERT between types of different sizes!");
     if (VT == Operand.getValueType()) return Operand;  // noop conversion.
     if (OpOpcode == ISD::BIT_CONVERT)  // bitconv(bitconv(x)) -> bitconv(x)
       return getNode(ISD::BIT_CONVERT, VT, Operand.getOperand(0));
@@ -1497,7 +1481,6 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
   // Perform various simplifications.
   ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.Val);
   ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2.Val);
-  //ConstantSDNode *N3C = dyn_cast<ConstantSDNode>(N3.Val);
   switch (Opcode) {
   case ISD::SETCC: {
     // Use FoldSetCC to simplify SETCC's.
@@ -1635,8 +1618,9 @@ SDOperand SelectionDAG::getExtLoad(ISD::LoadExtType ExtType, MVT::ValueType VT,
   return SDOperand(N, 0);
 }
 
-SDOperand SelectionDAG::getIndexedLoad(SDOperand OrigLoad, SDOperand Base,
-                                       SDOperand Offset, ISD::MemOpAddrMode AM){
+SDOperand
+SelectionDAG::getIndexedLoad(SDOperand OrigLoad, SDOperand Base,
+                             SDOperand Offset, ISD::MemIndexedMode AM) {
   LoadSDNode *LD = cast<LoadSDNode>(OrigLoad);
   assert(LD->getOffset().getOpcode() == ISD::UNDEF &&
          "Load is already a indexed load!");
@@ -1672,16 +1656,16 @@ SDOperand SelectionDAG::getVecLoad(unsigned Count, MVT::ValueType EVT,
   return getNode(ISD::VLOAD, getVTList(MVT::Vector, MVT::Other), Ops, 5);
 }
 
-SDOperand SelectionDAG::getStore(SDOperand Chain, SDOperand Value,
+SDOperand SelectionDAG::getStore(SDOperand Chain, SDOperand Val,
                                  SDOperand Ptr, const Value *SV, int SVOffset,
                                  bool isVolatile) {
-  MVT::ValueType VT = Value.getValueType();
+  MVT::ValueType VT = Val.getValueType();
 
   // FIXME: Alignment == 1 for now.
   unsigned Alignment = 1;
   SDVTList VTs = getVTList(MVT::Other);
   SDOperand Undef = getNode(ISD::UNDEF, Ptr.getValueType());
-  SDOperand Ops[] = { Chain, Value, Ptr, Undef };
+  SDOperand Ops[] = { Chain, Val, Ptr, Undef };
   FoldingSetNodeID ID;
   AddNodeIDNode(ID, ISD::STORE, VTs, Ops, 4);
   ID.AddInteger(ISD::UNINDEXED);
@@ -1694,7 +1678,7 @@ SDOperand SelectionDAG::getStore(SDOperand Chain, SDOperand Value,
   void *IP = 0;
   if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
     return SDOperand(E, 0);
-  SDNode *N = new StoreSDNode(Chain, Value, Ptr, Undef, ISD::UNINDEXED, false,
+  SDNode *N = new StoreSDNode(Chain, Val, Ptr, Undef, ISD::UNINDEXED, false,
                               VT, SV, SVOffset, Alignment, isVolatile);
   N->setValueTypes(VTs);
   CSEMap.InsertNode(N, IP);
@@ -1702,11 +1686,11 @@ SDOperand SelectionDAG::getStore(SDOperand Chain, SDOperand Value,
   return SDOperand(N, 0);
 }
 
-SDOperand SelectionDAG::getTruncStore(SDOperand Chain, SDOperand Value,
+SDOperand SelectionDAG::getTruncStore(SDOperand Chain, SDOperand Val,
                                       SDOperand Ptr, const Value *SV,
                                       int SVOffset, MVT::ValueType SVT,
                                       bool isVolatile) {
-  MVT::ValueType VT = Value.getValueType();
+  MVT::ValueType VT = Val.getValueType();
   bool isTrunc = VT != SVT;
 
   assert(VT > SVT && "Not a truncation?");
@@ -1717,7 +1701,7 @@ SDOperand SelectionDAG::getTruncStore(SDOperand Chain, SDOperand Value,
   unsigned Alignment = 1;
   SDVTList VTs = getVTList(MVT::Other);
   SDOperand Undef = getNode(ISD::UNDEF, Ptr.getValueType());
-  SDOperand Ops[] = { Chain, Value, Ptr, Undef };
+  SDOperand Ops[] = { Chain, Val, Ptr, Undef };
   FoldingSetNodeID ID;
   AddNodeIDNode(ID, ISD::STORE, VTs, Ops, 4);
   ID.AddInteger(ISD::UNINDEXED);
@@ -1730,7 +1714,7 @@ SDOperand SelectionDAG::getTruncStore(SDOperand Chain, SDOperand Value,
   void *IP = 0;
   if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
     return SDOperand(E, 0);
-  SDNode *N = new StoreSDNode(Chain, Value, Ptr, Undef, ISD::UNINDEXED, isTrunc,
+  SDNode *N = new StoreSDNode(Chain, Val, Ptr, Undef, ISD::UNINDEXED, isTrunc,
                               SVT, SV, SVOffset, Alignment, isVolatile);
   N->setValueTypes(VTs);
   CSEMap.InsertNode(N, IP);
@@ -1738,6 +1722,37 @@ SDOperand SelectionDAG::getTruncStore(SDOperand Chain, SDOperand Value,
   return SDOperand(N, 0);
 }
 
+SDOperand
+SelectionDAG::getIndexedStore(SDOperand OrigStore, SDOperand Base,
+                              SDOperand Offset, ISD::MemIndexedMode AM) {
+  StoreSDNode *ST = cast<StoreSDNode>(OrigStore);
+  assert(ST->getOffset().getOpcode() == ISD::UNDEF &&
+         "Store is already a indexed store!");
+  SDVTList VTs = getVTList(Base.getValueType(), MVT::Other);
+  SDOperand Ops[] = { ST->getChain(), ST->getValue(), Base, Offset };
+  FoldingSetNodeID ID;
+  AddNodeIDNode(ID, ISD::STORE, VTs, Ops, 4);
+  ID.AddInteger(AM);
+  ID.AddInteger(ST->isTruncatingStore());
+  ID.AddInteger(ST->getStoredVT());
+  ID.AddPointer(ST->getSrcValue());
+  ID.AddInteger(ST->getSrcValueOffset());
+  ID.AddInteger(ST->getAlignment());
+  ID.AddInteger(ST->isVolatile());
+  void *IP = 0;
+  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
+    return SDOperand(E, 0);
+  SDNode *N = new StoreSDNode(ST->getChain(), ST->getValue(),
+                              Base, Offset, AM,
+                              ST->isTruncatingStore(), ST->getStoredVT(),
+                              ST->getSrcValue(), ST->getSrcValueOffset(),
+                              ST->getAlignment(), ST->isVolatile());
+  N->setValueTypes(VTs);
+  CSEMap.InsertNode(N, IP);
+  AllNodes.push_back(N);
+  return SDOperand(N, 0);
+}
+
 SDOperand SelectionDAG::getVAArg(MVT::ValueType VT,
                                  SDOperand Chain, SDOperand Ptr,
                                  SDOperand SV) {
@@ -1956,7 +1971,6 @@ UpdateNodeOperands(SDOperand InN, SDOperand Op1, SDOperand Op2) {
   assert(N->getNumOperands() == 2 && "Update with wrong number of operands");
   
   // Check to see if there is no change.
-  bool AnyChange = false;
   if (Op1 == N->getOperand(0) && Op2 == N->getOperand(1))
     return InN;   // No operands changed, just return the input node.
   
@@ -2550,7 +2564,8 @@ bool SDNode::hasNUsesOfValue(unsigned NUses, unsigned Value) const {
 }
 
 
-// isOnlyUse - Return true if this node is the only use of N.
+/// isOnlyUse - Return true if this node is the only use of N.
+///
 bool SDNode::isOnlyUse(SDNode *N) const {
   bool Seen = false;
   for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) {
@@ -2564,7 +2579,8 @@ bool SDNode::isOnlyUse(SDNode *N) const {
   return Seen;
 }
 
-// isOperand - Return true if this node is an operand of N.
+/// isOperand - Return true if this node is an operand of N.
+///
 bool SDOperand::isOperand(SDNode *N) const {
   for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
     if (*this == N->getOperand(i))
@@ -2579,6 +2595,32 @@ bool SDNode::isOperand(SDNode *N) const {
   return false;
 }
 
+static void findPredecessor(SDNode *N, const SDNode *P, bool &found,
+                            std::set<SDNode *> &Visited) {
+  if (found || !Visited.insert(N).second)
+    return;
+
+  for (unsigned i = 0, e = N->getNumOperands(); !found && i != e; ++i) {
+    SDNode *Op = N->getOperand(i).Val;
+    if (Op == P) {
+      found = true;
+      return;
+    }
+    findPredecessor(Op, P, found, Visited);
+  }
+}
+
+/// isPredecessor - Return true if this node is a predecessor of N. This node
+/// is either an operand of N or it can be reached by recursively traversing
+/// up the operands.
+/// NOTE: this is an expensive method. Use it carefully.
+bool SDNode::isPredecessor(SDNode *N) const {
+  std::set<SDNode *> Visited;
+  bool found = false;
+  findPredecessor(N, this, found, Visited);
+  return found;
+}
+
 uint64_t SDNode::getConstantOperandVal(unsigned Num) const {
   assert(Num < NumOperands && "Invalid child # of SDNode!");
   return cast<ConstantSDNode>(OperandList[Num])->getValue();
@@ -2800,7 +2842,7 @@ const char *SDNode::getOperationName(const SelectionDAG *G) const {
   }
 }
 
-const char *SDNode::getAddressingModeName(ISD::MemOpAddrMode AM) {
+const char *SDNode::getIndexedModeName(ISD::MemIndexedMode AM) {
   switch (AM) {
   default:
     return "";
@@ -2817,100 +2859,102 @@ const char *SDNode::getAddressingModeName(ISD::MemOpAddrMode AM) {
 
 void SDNode::dump() const { dump(0); }
 void SDNode::dump(const SelectionDAG *G) const {
-  std::cerr << (void*)this << ": ";
+  cerr << (void*)this << ": ";
 
   for (unsigned i = 0, e = getNumValues(); i != e; ++i) {
-    if (i) std::cerr << ",";
+    if (i) cerr << ",";
     if (getValueType(i) == MVT::Other)
-      std::cerr << "ch";
+      cerr << "ch";
     else
-      std::cerr << MVT::getValueTypeString(getValueType(i));
+      cerr << MVT::getValueTypeString(getValueType(i));
   }
-  std::cerr << " = " << getOperationName(G);
+  cerr << " = " << getOperationName(G);
 
-  std::cerr << " ";
+  cerr << " ";
   for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
-    if (i) std::cerr << ", ";
-    std::cerr << (void*)getOperand(i).Val;
+    if (i) cerr << ", ";
+    cerr << (void*)getOperand(i).Val;
     if (unsigned RN = getOperand(i).ResNo)
-      std::cerr << ":" << RN;
+      cerr << ":" << RN;
   }
 
   if (const ConstantSDNode *CSDN = dyn_cast<ConstantSDNode>(this)) {
-    std::cerr << "<" << CSDN->getValue() << ">";
+    cerr << "<" << CSDN->getValue() << ">";
   } else if (const ConstantFPSDNode *CSDN = dyn_cast<ConstantFPSDNode>(this)) {
-    std::cerr << "<" << CSDN->getValue() << ">";
+    cerr << "<" << CSDN->getValue() << ">";
   } else if (const GlobalAddressSDNode *GADN =
              dyn_cast<GlobalAddressSDNode>(this)) {
     int offset = GADN->getOffset();
-    std::cerr << "<";
-    WriteAsOperand(std::cerr, GADN->getGlobal()) << ">";
+    cerr << "<";
+    WriteAsOperand(*cerr.stream(), GADN->getGlobal()) << ">";
     if (offset > 0)
-      std::cerr << " + " << offset;
+      cerr << " + " << offset;
     else
-      std::cerr << " " << offset;
+      cerr << " " << offset;
   } else if (const FrameIndexSDNode *FIDN = dyn_cast<FrameIndexSDNode>(this)) {
-    std::cerr << "<" << FIDN->getIndex() << ">";
+    cerr << "<" << FIDN->getIndex() << ">";
+  } else if (const JumpTableSDNode *JTDN = dyn_cast<JumpTableSDNode>(this)) {
+    cerr << "<" << JTDN->getIndex() << ">";
   } else if (const ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(this)){
     int offset = CP->getOffset();
     if (CP->isMachineConstantPoolEntry())
-      std::cerr << "<" << *CP->getMachineCPVal() << ">";
+      cerr << "<" << *CP->getMachineCPVal() << ">";
     else
-      std::cerr << "<" << *CP->getConstVal() << ">";
+      cerr << "<" << *CP->getConstVal() << ">";
     if (offset > 0)
-      std::cerr << " + " << offset;
+      cerr << " + " << offset;
     else
-      std::cerr << " " << offset;
+      cerr << " " << offset;
   } else if (const BasicBlockSDNode *BBDN = dyn_cast<BasicBlockSDNode>(this)) {
-    std::cerr << "<";
+    cerr << "<";
     const Value *LBB = (const Value*)BBDN->getBasicBlock()->getBasicBlock();
     if (LBB)
-      std::cerr << LBB->getName() << " ";
-    std::cerr << (const void*)BBDN->getBasicBlock() << ">";
+      cerr << LBB->getName() << " ";
+    cerr << (const void*)BBDN->getBasicBlock() << ">";
   } else if (const RegisterSDNode *R = dyn_cast<RegisterSDNode>(this)) {
     if (G && R->getReg() && MRegisterInfo::isPhysicalRegister(R->getReg())) {
-      std::cerr << " " <<G->getTarget().getRegisterInfo()->getName(R->getReg());
+      cerr << " " <<G->getTarget().getRegisterInfo()->getName(R->getReg());
     } else {
-      std::cerr << " #" << R->getReg();
+      cerr << " #" << R->getReg();
     }
   } else if (const ExternalSymbolSDNode *ES =
              dyn_cast<ExternalSymbolSDNode>(this)) {
-    std::cerr << "'" << ES->getSymbol() << "'";
+    cerr << "'" << ES->getSymbol() << "'";
   } else if (const SrcValueSDNode *M = dyn_cast<SrcValueSDNode>(this)) {
     if (M->getValue())
-      std::cerr << "<" << M->getValue() << ":" << M->getOffset() << ">";
+      cerr << "<" << M->getValue() << ":" << M->getOffset() << ">";
     else
-      std::cerr << "<null:" << M->getOffset() << ">";
+      cerr << "<null:" << M->getOffset() << ">";
   } else if (const VTSDNode *N = dyn_cast<VTSDNode>(this)) {
-    std::cerr << ":" << getValueTypeString(N->getVT());
+    cerr << ":" << getValueTypeString(N->getVT());
   } else if (const LoadSDNode *LD = dyn_cast<LoadSDNode>(this)) {
     bool doExt = true;
     switch (LD->getExtensionType()) {
     default: doExt = false; break;
     case ISD::EXTLOAD:
-      std::cerr << " <anyext ";
+      cerr << " <anyext ";
       break;
     case ISD::SEXTLOAD:
-      std::cerr << " <sext ";
+      cerr << " <sext ";
       break;
     case ISD::ZEXTLOAD:
-      std::cerr << " <zext ";
+      cerr << " <zext ";
       break;
     }
     if (doExt)
-      std::cerr << MVT::getValueTypeString(LD->getLoadedVT()) << ">";
+      cerr << MVT::getValueTypeString(LD->getLoadedVT()) << ">";
 
-    const char *AM = getAddressingModeName(LD->getAddressingMode());
+    const char *AM = getIndexedModeName(LD->getAddressingMode());
     if (AM != "")
-      std::cerr << " " << AM;
+      cerr << " " << AM;
   } else if (const StoreSDNode *ST = dyn_cast<StoreSDNode>(this)) {
     if (ST->isTruncatingStore())
-      std::cerr << " <trunc "
-                << MVT::getValueTypeString(ST->getStoredVT()) << ">";
+      cerr << " <trunc "
+           << MVT::getValueTypeString(ST->getStoredVT()) << ">";
 
-    const char *AM = getAddressingModeName(ST->getAddressingMode());
+    const char *AM = getIndexedModeName(ST->getAddressingMode());
     if (AM != "")
-      std::cerr << " " << AM;
+      cerr << " " << AM;
   }
 }
 
@@ -2919,16 +2963,16 @@ static void DumpNodes(const SDNode *N, unsigned indent, const SelectionDAG *G) {
     if (N->getOperand(i).Val->hasOneUse())
       DumpNodes(N->getOperand(i).Val, indent+2, G);
     else
-      std::cerr << "\n" << std::string(indent+2, ' ')
-                << (void*)N->getOperand(i).Val << ": <multiple use>";
+      cerr << "\n" << std::string(indent+2, ' ')
+           << (void*)N->getOperand(i).Val << ": <multiple use>";
 
 
-  std::cerr << "\n" << std::string(indent, ' ');
+  cerr << "\n" << std::string(indent, ' ');
   N->dump(G);
 }
 
 void SelectionDAG::dump() const {
-  std::cerr << "SelectionDAG has " << AllNodes.size() << " nodes:";
+  cerr << "SelectionDAG has " << AllNodes.size() << " nodes:";
   std::vector<const SDNode*> Nodes;
   for (allnodes_const_iterator I = allnodes_begin(), E = allnodes_end();
        I != E; ++I)
@@ -2943,7 +2987,7 @@ void SelectionDAG::dump() const {
 
   if (getRoot().Val) DumpNodes(getRoot().Val, 2, this);
 
-  std::cerr << "\n\n";
+  cerr << "\n\n";
 }
 
 const Type *ConstantPoolSDNode::getType() const {