X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FSelectionDAG%2FSelectionDAG.cpp;h=5f92df3f2d54d59baf6b64ab073292a035290961;hb=d97321ceb313f06fd9a824cf26b9dc5b80b3eb9d;hp=6b1a1e15daa2b5ae3960e9e40b42b21759972aa6;hpb=def69b92e70d156ed6f8c7af33c9a87d3f475e09;p=oota-llvm.git diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 6b1a1e15daa..5f92df3f2d5 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -26,10 +26,9 @@ #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" -#include #include -#include #include +#include 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(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) { @@ -331,7 +315,7 @@ static void AddNodeIDNode(FoldingSetNodeID &ID, SDOperand Op1, SDOperand Op2, SDOperand Op3) { AddNodeIDOpcode(ID, OpC); AddNodeIDValueTypes(ID, VTList); - AddNodeIDOperands(ID, Op1, Op2); + AddNodeIDOperands(ID, Op1, Op2, Op3); } static void AddNodeIDNode(FoldingSetNodeID &ID, unsigned short OpC, SDVTList VTList, @@ -363,20 +347,24 @@ static void AddNodeIDNode(FoldingSetNodeID &ID, SDNode *N) { ID.AddDouble(cast(N)->getValue()); break; case ISD::TargetGlobalAddress: - case ISD::GlobalAddress: - ID.AddPointer(cast(N)->getGlobal()); - ID.AddInteger(cast(N)->getOffset()); + case ISD::GlobalAddress: { + GlobalAddressSDNode *GA = cast(N); + ID.AddPointer(GA->getGlobal()); + ID.AddInteger(GA->getOffset()); break; + } case ISD::BasicBlock: ID.AddPointer(cast(N)->getBasicBlock()); break; case ISD::Register: ID.AddInteger(cast(N)->getReg()); break; - case ISD::SRCVALUE: - ID.AddPointer(cast(N)->getValue()); - ID.AddInteger(cast(N)->getOffset()); + case ISD::SRCVALUE: { + SrcValueSDNode *SV = cast(N); + ID.AddPointer(SV->getValue()); + ID.AddInteger(SV->getOffset()); break; + } case ISD::FrameIndex: case ISD::TargetFrameIndex: ID.AddInteger(cast(N)->getIndex()); @@ -386,16 +374,39 @@ static void AddNodeIDNode(FoldingSetNodeID &ID, SDNode *N) { ID.AddInteger(cast(N)->getIndex()); break; case ISD::ConstantPool: - case ISD::TargetConstantPool: - ID.AddInteger(cast(N)->getAlignment()); - ID.AddInteger(cast(N)->getOffset()); - if (cast(N)->isMachineConstantPoolEntry()) - cast(N)->getMachineCPVal()-> - AddSelectionDAGCSEId(ID); + case ISD::TargetConstantPool: { + ConstantPoolSDNode *CP = cast(N); + ID.AddInteger(CP->getAlignment()); + ID.AddInteger(CP->getOffset()); + if (CP->isMachineConstantPoolEntry()) + CP->getMachineCPVal()->AddSelectionDAGCSEId(ID); else - ID.AddPointer(cast(N)->getConstVal()); + ID.AddPointer(CP->getConstVal()); + break; + } + case ISD::LOAD: { + LoadSDNode *LD = cast(N); + ID.AddInteger(LD->getAddressingMode()); + ID.AddInteger(LD->getExtensionType()); + ID.AddInteger(LD->getLoadedVT()); + ID.AddPointer(LD->getSrcValue()); + ID.AddInteger(LD->getSrcValueOffset()); + ID.AddInteger(LD->getAlignment()); + ID.AddInteger(LD->isVolatile()); + break; + } + case ISD::STORE: { + StoreSDNode *ST = cast(N); + ID.AddInteger(ST->getAddressingMode()); + ID.AddInteger(ST->isTruncatingStore()); + ID.AddInteger(ST->getStoredVT()); + ID.AddPointer(ST->getSrcValue()); + ID.AddInteger(ST->getSrcValueOffset()); + ID.AddInteger(ST->getAlignment()); + ID.AddInteger(ST->isVolatile()); break; } + } } } @@ -547,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 @@ -1119,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)); @@ -1470,7 +1481,6 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT, // Perform various simplifications. ConstantSDNode *N1C = dyn_cast(N1.Val); ConstantSDNode *N2C = dyn_cast(N2.Val); - //ConstantSDNode *N3C = dyn_cast(N3.Val); switch (Opcode) { case ISD::SETCC: { // Use FoldSetCC to simplify SETCC's. @@ -1608,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(OrigLoad); assert(LD->getOffset().getOpcode() == ISD::UNDEF && "Load is already a indexed load!"); @@ -1645,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); @@ -1667,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); @@ -1675,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?"); @@ -1690,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); @@ -1703,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); @@ -1711,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(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) { @@ -1929,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. @@ -2523,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) { @@ -2537,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)) @@ -2552,6 +2595,32 @@ bool SDNode::isOperand(SDNode *N) const { return false; } +static void findPredecessor(SDNode *N, const SDNode *P, bool &found, + std::set &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 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(OperandList[Num])->getValue(); @@ -2707,6 +2776,7 @@ const char *SDNode::getOperationName(const SelectionDAG *G) const { // Control flow instructions case ISD::BR: return "br"; case ISD::BRIND: return "brind"; + case ISD::BR_JT: return "br_jt"; case ISD::BRCOND: return "brcond"; case ISD::BR_CC: return "br_cc"; case ISD::RET: return "ret"; @@ -2772,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 ""; @@ -2789,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(this)) { - std::cerr << "<" << CSDN->getValue() << ">"; + cerr << "<" << CSDN->getValue() << ">"; } else if (const ConstantFPSDNode *CSDN = dyn_cast(this)) { - std::cerr << "<" << CSDN->getValue() << ">"; + cerr << "<" << CSDN->getValue() << ">"; } else if (const GlobalAddressSDNode *GADN = dyn_cast(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(this)) { - std::cerr << "<" << FIDN->getIndex() << ">"; + cerr << "<" << FIDN->getIndex() << ">"; + } else if (const JumpTableSDNode *JTDN = dyn_cast(this)) { + cerr << "<" << JTDN->getIndex() << ">"; } else if (const ConstantPoolSDNode *CP = dyn_cast(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(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(this)) { if (G && R->getReg() && MRegisterInfo::isPhysicalRegister(R->getReg())) { - std::cerr << " " <getTarget().getRegisterInfo()->getName(R->getReg()); + cerr << " " <getTarget().getRegisterInfo()->getName(R->getReg()); } else { - std::cerr << " #" << R->getReg(); + cerr << " #" << R->getReg(); } } else if (const ExternalSymbolSDNode *ES = dyn_cast(this)) { - std::cerr << "'" << ES->getSymbol() << "'"; + cerr << "'" << ES->getSymbol() << "'"; } else if (const SrcValueSDNode *M = dyn_cast(this)) { if (M->getValue()) - std::cerr << "<" << M->getValue() << ":" << M->getOffset() << ">"; + cerr << "<" << M->getValue() << ":" << M->getOffset() << ">"; else - std::cerr << "getOffset() << ">"; + cerr << "getOffset() << ">"; } else if (const VTSDNode *N = dyn_cast(this)) { - std::cerr << ":" << getValueTypeString(N->getVT()); + cerr << ":" << getValueTypeString(N->getVT()); } else if (const LoadSDNode *LD = dyn_cast(this)) { bool doExt = true; switch (LD->getExtensionType()) { default: doExt = false; break; case ISD::EXTLOAD: - std::cerr << " 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(this)) { if (ST->isTruncatingStore()) - std::cerr << " getStoredVT()) << ">"; + cerr << " getStoredVT()) << ">"; - const char *AM = getAddressingModeName(ST->getAddressingMode()); + const char *AM = getIndexedModeName(ST->getAddressingMode()); if (AM != "") - std::cerr << " " << AM; + cerr << " " << AM; } } @@ -2891,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 << ": "; + cerr << "\n" << std::string(indent+2, ' ') + << (void*)N->getOperand(i).Val << ": "; - 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 Nodes; for (allnodes_const_iterator I = allnodes_begin(), E = allnodes_end(); I != E; ++I) @@ -2915,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 {