diff options
21 files changed, 520 insertions, 310 deletions
diff --git a/include/llvm/CodeGen/DAGISelHeader.h b/include/llvm/CodeGen/DAGISelHeader.h index f1774bf6b3..79f6276282 100644 --- a/include/llvm/CodeGen/DAGISelHeader.h +++ b/include/llvm/CodeGen/DAGISelHeader.h @@ -124,6 +124,17 @@ void ReplaceUses(SDOperand F, SDOperand T) DISABLE_INLINE { UpdateQueue(ISQU); } +/// ReplaceUses - replace all uses of the old nodes F with the use +/// of the new nodes T. +void ReplaceUses(const SDOperand *F, const SDOperand *T, + unsigned Num) DISABLE_INLINE { + ISelQueueUpdater ISQU(ISelQueue); + CurDAG->ReplaceAllUsesOfValuesWith(F, T, Num, &ISQU); + for (unsigned i = 0; i != Num; ++i) + setSelected(F[i].Val->getNodeId()); + UpdateQueue(ISQU); +} + /// ReplaceUses - replace all uses of the old node F with the use /// of the new node T. void ReplaceUses(SDNode *F, SDNode *T) DISABLE_INLINE { diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index 636e36d591..f530f3380a 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -60,6 +60,10 @@ class SelectionDAG { /// CSE with existing nodes with a duplicate is requested. FoldingSet<SDNode> CSEMap; + /// Allocator - Pool allocation for misc. objects that are created once per + /// SelectionDAG. + BumpPtrAllocator Allocator; + public: SelectionDAG(TargetLowering &tli, MachineFunction &mf, FunctionLoweringInfo &fli, MachineModuleInfo *mmi, @@ -457,8 +461,7 @@ public: /// SelectNodeTo - These are used for target selectors to *mutate* the /// specified node to have the specified return type, Target opcode, and /// operands. Note that target opcodes are stored as - /// ISD::BUILTIN_OP_END+TargetOpcode in the node opcode field. The 0th value - /// of the resultant node is returned. + /// ~TargetOpcode in the node opcode field. The resultant node is returned. SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT VT); SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT VT, SDOperand Op1); SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT VT, @@ -481,6 +484,29 @@ public: SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, SDVTList VTs, const SDOperand *Ops, unsigned NumOps); + /// MorphNodeTo - These *mutate* the specified node to have the specified + /// return type, opcode, and operands. + SDNode *MorphNodeTo(SDNode *N, unsigned Opc, MVT VT); + SDNode *MorphNodeTo(SDNode *N, unsigned Opc, MVT VT, SDOperand Op1); + SDNode *MorphNodeTo(SDNode *N, unsigned Opc, MVT VT, + SDOperand Op1, SDOperand Op2); + SDNode *MorphNodeTo(SDNode *N, unsigned Opc, MVT VT, + SDOperand Op1, SDOperand Op2, SDOperand Op3); + SDNode *MorphNodeTo(SDNode *N, unsigned Opc, MVT VT, + const SDOperand *Ops, unsigned NumOps); + SDNode *MorphNodeTo(SDNode *N, unsigned Opc, MVT VT1, MVT VT2); + SDNode *MorphNodeTo(SDNode *N, unsigned Opc, MVT VT1, + MVT VT2, const SDOperand *Ops, unsigned NumOps); + SDNode *MorphNodeTo(SDNode *N, unsigned Opc, MVT VT1, + MVT VT2, MVT VT3, const SDOperand *Ops, unsigned NumOps); + SDNode *MorphNodeTo(SDNode *N, unsigned Opc, MVT VT1, + MVT VT2, SDOperand Op1); + SDNode *MorphNodeTo(SDNode *N, unsigned Opc, MVT VT1, + MVT VT2, SDOperand Op1, SDOperand Op2); + SDNode *MorphNodeTo(SDNode *N, unsigned Opc, MVT VT1, + MVT VT2, SDOperand Op1, SDOperand Op2, SDOperand Op3); + SDNode *MorphNodeTo(SDNode *N, unsigned Opc, SDVTList VTs, + const SDOperand *Ops, unsigned NumOps); /// getTargetNode - These are used for target selectors to create a new node /// with specified return type(s), target opcode, and operands. @@ -565,6 +591,13 @@ public: void ReplaceAllUsesOfValueWith(SDOperand From, SDOperand To, DAGUpdateListener *UpdateListener = 0); + /// ReplaceAllUsesOfValuesWith - Like ReplaceAllUsesOfValueWith, but + /// for multiple values at once. This correctly handles the case where + /// there is an overlap between the From values and the To values. + void ReplaceAllUsesOfValuesWith(const SDOperand *From, const SDOperand *To, + unsigned Num, + DAGUpdateListener *UpdateListener = 0); + /// AssignTopologicalOrder - Assign a unique node id for each node in the DAG /// based on their topological order. It returns the maximum id and a vector /// of the SDNodes* in assigned order by reference. @@ -654,7 +687,7 @@ private: unsigned getMVTAlignment(MVT MemoryVT) const; // List of non-single value types. - std::list<std::vector<MVT> > VTList; + std::vector<SDVTList> VTList; // Maps to auto-CSE operations. std::vector<CondCodeSDNode*> CondCodeNodes; diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index d1363e9ec3..78897cbbdd 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -846,7 +846,8 @@ public: inline const SDOperand &getOperand(unsigned i) const; inline uint64_t getConstantOperandVal(unsigned i) const; inline bool isTargetOpcode() const; - inline unsigned getTargetOpcode() const; + inline bool isMachineOpcode() const; + inline unsigned getMachineOpcode() const; /// reachesChainWithoutSideEffects - Return true if this operand (which must @@ -1028,7 +1029,7 @@ class SDNode : public FoldingSetNode { private: /// NodeType - The operation that this node performs. /// - unsigned short NodeType; + short NodeType; /// OperandsNeedDelete - This is true if OperandList was new[]'d. If true, /// then they will be delete[]'d when the node is destroyed. @@ -1072,11 +1073,27 @@ public: //===--------------------------------------------------------------------===// // Accessors // - unsigned getOpcode() const { return NodeType; } + + /// getOpcode - Return the SelectionDAG opcode value for this node. For + /// pre-isel nodes (those for which isMachineOpcode returns false), these + /// are the opcode values in the ISD and <target>ISD namespaces. For + /// post-isel opcodes, see getMachineOpcode. + unsigned getOpcode() const { return (unsigned short)NodeType; } + + /// isTargetOpcode - Test if this node has a target-specific opcode (in the + /// <target>ISD namespace). bool isTargetOpcode() const { return NodeType >= ISD::BUILTIN_OP_END; } - unsigned getTargetOpcode() const { - assert(isTargetOpcode() && "Not a target opcode!"); - return NodeType - ISD::BUILTIN_OP_END; + + /// isMachineOpcode - Test if this node has a post-isel opcode, directly + /// corresponding to a MachineInstr opcode. + bool isMachineOpcode() const { return NodeType < 0; } + + /// getMachineOpcode - This may only be called if isMachineOpcode returns + /// true. It returns the MachineInstr opcode value that the node's opcode + /// corresponds to. + unsigned getMachineOpcode() const { + assert(isMachineOpcode() && "Not a target opcode!"); + return ~NodeType; } size_t use_size() const { return std::distance(use_begin(), use_end()); } @@ -1314,17 +1331,9 @@ protected: } /// DropOperands - Release the operands and set this node to have - /// zero operands. This should only be used by HandleSDNode to clear - /// its operand list. + /// zero operands. void DropOperands(); - /// MorphNodeTo - This frees the operands of the current node, resets the - /// opcode, types, and operands to the specified value. This should only be - /// used by the SelectionDAG class. - void MorphNodeTo(unsigned Opc, SDVTList L, - const SDOperand *Ops, unsigned NumOps, - SmallVectorImpl<SDNode *> &DeadNodes); - void addUser(unsigned i, SDNode *User) { assert(User->OperandList[i].getUser() && "Node without parent"); addUse(User->OperandList[i]); @@ -1358,8 +1367,11 @@ inline uint64_t SDOperand::getConstantOperandVal(unsigned i) const { inline bool SDOperand::isTargetOpcode() const { return Val->isTargetOpcode(); } -inline unsigned SDOperand::getTargetOpcode() const { - return Val->getTargetOpcode(); +inline bool SDOperand::isMachineOpcode() const { + return Val->isMachineOpcode(); +} +inline unsigned SDOperand::getMachineOpcode() const { + return Val->getMachineOpcode(); } inline bool SDOperand::hasOneUse() const { return Val->hasNUsesOfValue(1, ResNo); diff --git a/include/llvm/Support/Allocator.h b/include/llvm/Support/Allocator.h index eab6d332c4..bc3653503c 100644 --- a/include/llvm/Support/Allocator.h +++ b/include/llvm/Support/Allocator.h @@ -58,6 +58,11 @@ public: return static_cast<T*>(Allocate(sizeof(T),AlignOf<T>::Alignment)); } + template <typename T> + T *Allocate(size_t Num) { + return static_cast<T*>(Allocate(Num * sizeof(T), AlignOf<T>::Alignment)); + } + void Deallocate(void * /*Ptr*/) {} void PrintStats() const; diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp index 982bbab3cb..4f793a5341 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp @@ -63,8 +63,8 @@ static void CheckForPhysRegDependency(SDNode *Def, SDNode *Use, unsigned Op, return; unsigned ResNo = Use->getOperand(2).ResNo; - if (Def->isTargetOpcode()) { - const TargetInstrDesc &II = TII->get(Def->getTargetOpcode()); + if (Def->isMachineOpcode()) { + const TargetInstrDesc &II = TII->get(Def->getMachineOpcode()); if (ResNo >= II.getNumDefs() && II.ImplicitDefs[ResNo - II.getNumDefs()] == Reg) { PhysReg = Reg; @@ -167,8 +167,8 @@ void ScheduleDAG::BuildSchedUnits() { SUnit *SU = &SUnits[su]; SDNode *MainNode = SU->Node; - if (MainNode->isTargetOpcode()) { - unsigned Opc = MainNode->getTargetOpcode(); + if (MainNode->isMachineOpcode()) { + unsigned Opc = MainNode->getMachineOpcode(); const TargetInstrDesc &TID = TII->get(Opc); for (unsigned i = 0; i != TID.getNumOperands(); ++i) { if (TID.getOperandConstraint(i, TOI::TIED_TO) != -1) { @@ -186,9 +186,9 @@ void ScheduleDAG::BuildSchedUnits() { for (unsigned n = 0, e = SU->FlaggedNodes.size(); n != e; ++n) { SDNode *N = SU->FlaggedNodes[n]; - if (N->isTargetOpcode() && - TII->get(N->getTargetOpcode()).getImplicitDefs() && - CountResults(N) > TII->get(N->getTargetOpcode()).getNumDefs()) + if (N->isMachineOpcode() && + TII->get(N->getMachineOpcode()).getImplicitDefs() && + CountResults(N) > TII->get(N->getMachineOpcode()).getNumDefs()) SU->hasPhysRegDefs = true; for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { @@ -227,8 +227,8 @@ void ScheduleDAG::ComputeLatency(SUnit *SU) { } SU->Latency = 0; - if (SU->Node->isTargetOpcode()) { - unsigned SchedClass = TII->get(SU->Node->getTargetOpcode()).getSchedClass(); + if (SU->Node->isMachineOpcode()) { + unsigned SchedClass = TII->get(SU->Node->getMachineOpcode()).getSchedClass(); const InstrStage *S = InstrItins.begin(SchedClass); const InstrStage *E = InstrItins.end(SchedClass); for (; S != E; ++S) @@ -236,8 +236,8 @@ void ScheduleDAG::ComputeLatency(SUnit *SU) { } for (unsigned i = 0, e = SU->FlaggedNodes.size(); i != e; ++i) { SDNode *FNode = SU->FlaggedNodes[i]; - if (FNode->isTargetOpcode()) { - unsigned SchedClass = TII->get(FNode->getTargetOpcode()).getSchedClass(); + if (FNode->isMachineOpcode()) { + unsigned SchedClass = TII->get(FNode->getMachineOpcode()).getSchedClass(); const InstrStage *S = InstrItins.begin(SchedClass); const InstrStage *E = InstrItins.end(SchedClass); for (; S != E; ++S) @@ -501,7 +501,7 @@ unsigned ScheduleDAG::getDstOfOnlyCopyToRegUse(SDNode *Node, void ScheduleDAG::CreateVirtualRegisters(SDNode *Node, MachineInstr *MI, const TargetInstrDesc &II, DenseMap<SDOperand, unsigned> &VRBaseMap) { - assert(Node->getTargetOpcode() != TargetInstrInfo::IMPLICIT_DEF && + assert(Node->getMachineOpcode() != TargetInstrInfo::IMPLICIT_DEF && "IMPLICIT_DEF should have been handled as a special case elsewhere!"); for (unsigned i = 0; i < II.getNumDefs(); ++i) { @@ -544,8 +544,8 @@ void ScheduleDAG::CreateVirtualRegisters(SDNode *Node, MachineInstr *MI, /// of the specified node. unsigned ScheduleDAG::getVR(SDOperand Op, DenseMap<SDOperand, unsigned> &VRBaseMap) { - if (Op.isTargetOpcode() && - Op.getTargetOpcode() == TargetInstrInfo::IMPLICIT_DEF) { + if (Op.isMachineOpcode() && + Op.getMachineOpcode() == TargetInstrInfo::IMPLICIT_DEF) { // Add an IMPLICIT_DEF instruction before every use. unsigned VReg = getDstOfOnlyCopyToRegUse(Op.Val, Op.ResNo); // IMPLICIT_DEF can produce any type of result so its TargetInstrDesc @@ -572,7 +572,7 @@ void ScheduleDAG::AddOperand(MachineInstr *MI, SDOperand Op, unsigned IIOpNum, const TargetInstrDesc *II, DenseMap<SDOperand, unsigned> &VRBaseMap) { - if (Op.isTargetOpcode()) { + if (Op.isMachineOpcode()) { // Note that this case is redundant with the final else block, but we // include it because it is the most common and it makes the logic // simpler here. @@ -704,7 +704,7 @@ getSuperRegisterRegClass(const TargetRegisterClass *TRC, void ScheduleDAG::EmitSubregNode(SDNode *Node, DenseMap<SDOperand, unsigned> &VRBaseMap) { unsigned VRBase = 0; - unsigned Opc = Node->getTargetOpcode(); + unsigned Opc = Node->getMachineOpcode(); // If the node is only used by a CopyToReg and the dest reg is a vreg, use // the CopyToReg'd destination register instead of creating a new vreg. @@ -799,8 +799,8 @@ void ScheduleDAG::EmitSubregNode(SDNode *Node, void ScheduleDAG::EmitNode(SDNode *Node, bool IsClone, DenseMap<SDOperand, unsigned> &VRBaseMap) { // If machine instruction - if (Node->isTargetOpcode()) { - unsigned Opc = Node->getTargetOpcode(); + if (Node->isMachineOpcode()) { + unsigned Opc = Node->getMachineOpcode(); // Handle subreg insert/extract specially if (Opc == TargetInstrInfo::EXTRACT_SUBREG || diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp index 39aadd5279..4b09b7c263 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGList.cpp @@ -206,7 +206,7 @@ void ScheduleDAGList::ListScheduleTopDown() { // If this is a pseudo op, like copyfromreg, look to see if there is a // real target node flagged to it. If so, use the target node. for (unsigned i = 0, e = CurSUnit->FlaggedNodes.size(); - FoundNode->getOpcode() < ISD::BUILTIN_OP_END && i != e; ++i) + !FoundNode->isMachineOpcode() && i != e; ++i) FoundNode = CurSUnit->FlaggedNodes[i]; HazardRecognizer::HazardType HT = HazardRec->getHazardType(FoundNode); diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp index 098b7996d4..43fbd4b050 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp @@ -216,7 +216,7 @@ void ScheduleDAGRRList::CommuteNodesToReducePressure() { SUnit *SU = Sequence[i]; if (!SU || !SU->Node) continue; if (SU->isCommutable) { - unsigned Opc = SU->Node->getTargetOpcode(); + unsigned Opc = SU->Node->getMachineOpcode(); const TargetInstrDesc &TID = TII->get(Opc); unsigned NumRes = TID.getNumDefs(); unsigned NumOps = TID.getNumOperands() - NumRes; @@ -678,7 +678,7 @@ SUnit *ScheduleDAGRRList::CopyAndMoveSuccessors(SUnit *SU) { assert(N->getNodeId() == -1 && "Node already inserted!"); N->setNodeId(NewSU->NodeNum); - const TargetInstrDesc &TID = TII->get(N->getTargetOpcode()); + const TargetInstrDesc &TID = TII->get(N->getMachineOpcode()); for (unsigned i = 0; i != TID.getNumOperands(); ++i) { if (TID.getOperandConstraint(i, TOI::TIED_TO) != -1) { NewSU->isTwoAddress = true; @@ -872,7 +872,7 @@ void ScheduleDAGRRList::InsertCCCopiesAndMoveSuccs(SUnit *SU, unsigned Reg, /// FIXME: Move to SelectionDAG? static MVT getPhysicalRegisterVT(SDNode *N, unsigned Reg, const TargetInstrInfo *TII) { - const TargetInstrDesc &TID = TII->get(N->getTargetOpcode()); + const TargetInstrDesc &TID = TII->get(N->getMachineOpcode()); assert(TID.ImplicitDefs && "Physical reg def must be in implicit def list!"); unsigned NumRes = TID.getNumDefs(); for (const unsigned *ImpDef = TID.getImplicitDefs(); *ImpDef; ++ImpDef) { @@ -913,9 +913,9 @@ bool ScheduleDAGRRList::DelayForLiveRegsBottomUp(SUnit *SU, for (unsigned i = 0, e = SU->FlaggedNodes.size()+1; i != e; ++i) { SDNode *Node = (i == 0) ? SU->Node : SU->FlaggedNodes[i-1]; - if (!Node || !Node->isTargetOpcode()) + if (!Node || !Node->isMachineOpcode()) continue; - const TargetInstrDesc &TID = TII->get(Node->getTargetOpcode()); + const TargetInstrDesc &TID = TII->get(Node->getMachineOpcode()); if (!TID.ImplicitDefs) continue; for (const unsigned *Reg = TID.ImplicitDefs; *Reg; ++Reg) { @@ -1673,7 +1673,7 @@ bu_ls_rr_fast_sort::operator()(const SUnit *left, const SUnit *right) const { bool BURegReductionPriorityQueue::canClobber(const SUnit *SU, const SUnit *Op) { if (SU->isTwoAddress) { - unsigned Opc = SU->Node->getTargetOpcode(); + unsigned Opc = SU->Node->getMachineOpcode(); const TargetInstrDesc &TID = TII->get(Opc); unsigned NumRes = TID.getNumDefs(); unsigned NumOps = TID.getNumOperands() - NumRes; @@ -1709,11 +1709,11 @@ static bool canClobberPhysRegDefs(SUnit *SuccSU, SUnit *SU, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) { SDNode *N = SuccSU->Node; - unsigned NumDefs = TII->get(N->getTargetOpcode()).getNumDefs(); - const unsigned *ImpDefs = TII->get(N->getTargetOpcode()).getImplicitDefs(); + unsigned NumDefs = TII->get(N->getMachineOpcode()).getNumDefs(); + const unsigned *ImpDefs = TII->get(N->getMachineOpcode()).getImplicitDefs(); assert(ImpDefs && "Caller should check hasPhysRegDefs"); const unsigned *SUImpDefs = - TII->get(SU->Node->getTargetOpcode()).getImplicitDefs(); + TII->get(SU->Node->getMachineOpcode()).getImplicitDefs(); if (!SUImpDefs) return false; for (unsigned i = NumDefs, e = N->getNumValues(); i != e; ++i) { @@ -1744,10 +1744,10 @@ void BURegReductionPriorityQueue::AddPseudoTwoAddrDeps() { continue; SDNode *Node = SU->Node; - if (!Node || !Node->isTargetOpcode() || SU->FlaggedNodes.size() > 0) + if (!Node || !Node->isMachineOpcode() || SU->FlaggedNodes.size() > 0) continue; - unsigned Opc = Node->getTargetOpcode(); + unsigned Opc = Node->getMachineOpcode(); const TargetInstrDesc &TID = TII->get(Opc); unsigned NumRes = TID.getNumDefs(); unsigned NumOps = TID.getNumOperands() - NumRes; @@ -1768,7 +1768,7 @@ void BURegReductionPriorityQueue::AddPseudoTwoAddrDeps() { // depth and height. if (SuccSU->Height < SU->Height && (SU->Height - SuccSU->Height) > 1) continue; - if (!SuccSU->Node || !SuccSU->Node->isTargetOpcode()) + if (!SuccSU->Node || !SuccSU->Node->isMachineOpcode()) continue; // Don't constrain nodes with physical register defs if the // predecessor can clobber them. @@ -1778,7 +1778,7 @@ void BURegReductionPriorityQueue::AddPseudoTwoAddrDeps() { } // Don't constraint extract_subreg / insert_subreg these may be // coalesced away. We don't them close to their uses. - unsigned SuccOpc = SuccSU->Node->getTargetOpcode(); + unsigned SuccOpc = SuccSU->Node->getMachineOpcode(); if (SuccOpc == TargetInstrInfo::EXTRACT_SUBREG || SuccOpc == TargetInstrInfo::INSERT_SUBREG) continue; @@ -1836,8 +1836,8 @@ static unsigned LimitedSumOfUnscheduledPredsOfSuccs(const SUnit *SU, bool td_ls_rr_sort::operator()(const SUnit *left, const SUnit *right) const { unsigned LPriority = SPQ->getNodePriority(left); unsigned RPriority = SPQ->getNodePriority(right); - bool LIsTarget = left->Node && left->Node->isTargetOpcode(); - bool RIsTarget = right->Node && right->Node->isTargetOpcode(); + bool LIsTarget = left->Node && left->Node->isMachineOpcode(); + bool RIsTarget = right->Node && right->Node->isMachineOpcode(); bool LIsFloater = LIsTarget && left->NumPreds == 0; bool RIsFloater = RIsTarget && right->NumPreds == 0; unsigned LBonus = (LimitedSumOfUnscheduledPredsOfSuccs(left,1) == 1) ? 2 : 0; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index f7937137da..e757133f99 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -197,8 +197,8 @@ bool ISD::isDebugLabel(const SDNode *N) { SDOperand Zero; if (N->getOpcode() == ISD::DBG_LABEL) return true; - if (N->isTargetOpcode() && - N->getTargetOpcode() == TargetInstrInfo::DBG_LABEL) + if (N->isMachineOpcode() && + N->getMachineOpcode() == TargetInstrInfo::DBG_LABEL) return true; return false; } @@ -532,8 +532,7 @@ void SelectionDAG::RemoveDeadNodes(SmallVectorImpl<SDNode *> &DeadNodes, } void SelectionDAG::RemoveDeadNode(SDNode *N, DAGUpdateListener *UpdateListener){ - SmallVector<SDNode*, 16> DeadNodes; - DeadNodes.push_back(N); + SmallVector<SDNode*, 16> DeadNodes(1, N); RemoveDeadNodes(DeadNodes, UpdateListener); } @@ -3523,31 +3522,33 @@ SDVTList SelectionDAG::getVTList(MVT VT) { } SDVTList SelectionDAG::getVTList(MVT VT1, MVT VT2) { - for (std::list<std::vector<MVT> >::iterator I = VTList.begin(), - E = VTList.end(); I != E; ++I) { - if (I->size() == 2 && (*I)[0] == VT1 && (*I)[1] == VT2) - return makeVTList(&(*I)[0], 2); - } - std::vector<MVT> V; - V.push_back(VT1); - V.push_back(VT2); - VTList.push_front(V); - return makeVTList(&(*VTList.begin())[0], 2); -} -SDVTList SelectionDAG::getVTList(MVT VT1, MVT VT2, - MVT VT3) { - for (std::list<std::vector<MVT> >::iterator I = VTList.begin(), - E = VTList.end(); I != E; ++I) { - if (I->size() == 3 && (*I)[0] == VT1 && (*I)[1] == VT2 && - (*I)[2] == VT3) - return makeVTList(&(*I)[0], 3); - } - std::vector<MVT> V; - V.push_back(VT1); - V.push_back(VT2); - V.push_back(VT3); - VTList.push_front(V); - return makeVTList(&(*VTList.begin())[0], 3); + for (std::vector<SDVTList>::reverse_iterator I = VTList.rbegin(), + E = VTList.rend(); I != E; ++I) + if (I->NumVTs == 2 && I->VTs[0] == VT1 && I->VTs[1] == VT2) + return *I; + + MVT *Array = Allocator.Allocate<MVT>(2); + Array[0] = VT1; + Array[1] = VT2; + SDVTList Result = makeVTList(Array, 2); + VTList.push_back(Result); + return Result; +} + +SDVTList SelectionDAG::getVTList(MVT VT1, MVT VT2, MVT VT3) { + for (std::vector<SDVTList>::reverse_iterator I = VTList.rbegin(), + E = VTList.rend(); I != E; ++I) + if (I->NumVTs == 3 && I->VTs[0] == VT1 && I->VTs[1] == VT2 && + I->VTs[2] == VT3) + return *I; + + MVT *Array = Allocator.Allocate<MVT>(3); + Array[0] = VT1; + Array[1] = VT2; + Array[2] = VT3; + SDVTList Result = makeVTList(Array, 3); + VTList.push_back(Result); + return Result; } SDVTList SelectionDAG::getVTList(const MVT *VTs, unsigned NumVTs) { @@ -3559,22 +3560,26 @@ SDVTList SelectionDAG::getVTList(const MVT *VTs, unsigned NumVTs) { default: break; } - for (std::list<std::vector<MVT> >::iterator I = VTList.begin(), - E = VTList.end(); I != E; ++I) { - if (I->size() != NumVTs || VTs[0] != (*I)[0] || VTs[1] != (*I)[1]) continue; + for (std::vector<SDVTList>::reverse_iterator I = VTList.rbegin(), + E = VTList.rend(); I != E; ++I) { + if (I->NumVTs != NumVTs || VTs[0] != I->VTs[0] || VTs[1] != I->VTs[1]) + continue; bool NoMatch = false; for (unsigned i = 2; i != NumVTs; ++i) - if (VTs[i] != (*I)[i]) { + if (VTs[i] != I->VTs[i]) { NoMatch = true; break; } if (!NoMatch) - return makeVTList(&*I->begin(), NumVTs); + return *I; } - VTList.push_front(std::vector<MVT>(VTs, VTs+NumVTs)); - return makeVTList(&*VTList.begin()->begin(), NumVTs); + MVT *Array = Allocator.Allocate<MVT>(NumVTs); + std::copy(VTs, VTs+NumVTs, Array); + SDVTList Result = makeVTList(Array, NumVTs); + VTList.push_back(Result); + return Result; } @@ -3711,61 +3716,9 @@ UpdateNodeOperands(SDOperand InN, const SDOperand *Ops, unsigned NumOps) { return InN; } -/// MorphNodeTo - This frees the operands of the current node, resets the -/// opcode, types, and operands to the specified value. This should only be -/// used by the SelectionDAG class. -void SDNode::MorphNodeTo(unsigned Opc, SDVTList L, - const SDOperand *Ops, unsigned NumOps, - SmallVectorImpl<SDNode *> &DeadNodes) { - NodeType = Opc; - ValueList = L.VTs; - NumValues = L.NumVTs; - - // Clear the operands list, updating used nodes to remove this from their - // use list. Keep track of any operands that become dead as a result. - SmallPtrSet<SDNode*, 16> DeadNodeSet; - for (op_iterator I = op_begin(), E = op_end(); I != E; ++I) { - SDNode *N = I->getVal(); - N->removeUser(std::distance(op_begin(), I), this); - if (N->use_empty()) - DeadNodeSet.insert(N); - } - - // If NumOps is larger than the # of operands we currently have, reallocate - // the operand list. - if (NumOps > NumOperands) { - if (OperandsNeedDelete) { - delete [] OperandList; - } - OperandList = new SDUse[NumOps]; - OperandsNeedDelete = true; - } - - // Assign the new operands. - NumOperands = NumOps; - - for (unsigned i = 0, e = NumOps; i != e; ++i) { - OperandList[i] = Ops[i]; - OperandList[i].setUser(this); - SDNode *N = OperandList[i].getVal(); - N->addUser(i, this); - DeadNodeSet.erase(N); - } - - // Clean up any nodes that are still dead after adding the uses for the - // new operands. - for (SmallPtrSet<SDNode *, 16>::iterator I = DeadNodeSet.begin(), - E = DeadNodeSet.end(); I != E; ++I) - DeadNodes.push_back(*I); -} - /// DropOperands - Release the operands and set this node to have -/// zero operands. This should only be used by HandleSDNode to clear -/// its operand list. +/// zero operands. void SDNode::DropOperands() { - assert(NodeType == ISD::HANDLENODE && - "DropOperands is for HANDLENODE only!"); - // Unlike the code in MorphNodeTo that does this, we don't need to // watch for dead nodes here. for (op_iterator I = op_begin(), E = op_end(); I != E; ++I) @@ -3774,112 +3727,257 @@ void SDNode::DropOperands() { NumOperands = 0; } -/// SelectNodeTo - These are used for target selectors to *mutate* the -/// specified node to have the specified return type, Target opcode, and -/// operands. Note that target opcodes are stored as -/// ISD::BUILTIN_OP_END+TargetOpcode in the node opcode field. +/// SelectNodeTo - These are wrappers around MorphNodeTo that accept a +/// machine opcode. /// -/// Note that SelectNodeTo returns the resultant node. If there is already a -/// node of the specified opcode and operands, it returns that node instead of -/// the current one. -SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc, +SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc, MVT VT) { SDVTList VTs = getVTList(VT); - return SelectNodeTo(N, TargetOpc, VTs, 0, 0); + return SelectNodeTo(N, MachineOpc, VTs, 0, 0); } -SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc, +SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc, MVT VT, SDOperand Op1) { SDVTList VTs = getVTList(VT); SDOperand Ops[] = { Op1 }; - return SelectNodeTo(N, TargetOpc, VTs, Ops, 1); + return SelectNodeTo(N, MachineOpc, VTs, Ops, 1); } -SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc, +SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc, MVT VT, SDOperand Op1, SDOperand Op2) { SDVTList VTs = getVTList(VT); SDOperand Ops[] = { Op1, Op2 }; - return SelectNodeTo(N, TargetOpc, VTs, Ops, 2); + return SelectNodeTo(N, MachineOpc, VTs, Ops, 2); } -SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc, +SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc, MVT VT, SDOperand Op1, SDOperand Op2, SDOperand Op3) { SDVTList VTs = getVTList(VT); SDOperand Ops[] = { Op1, Op2, Op3 }; - return SelectNodeTo(N, TargetOpc, VTs, Ops, 3); + return SelectNodeTo(N, MachineOpc, VTs, Ops, 3); } -SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc, +SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc, MVT VT, const SDOperand *Ops, unsigned NumOps) { SDVTList VTs = getVTList(VT); - return SelectNodeTo(N, TargetOpc, VTs, Ops, NumOps); + return SelectNodeTo(N, MachineOpc, VTs, Ops, NumOps); } -SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc, +SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc, MVT VT1, MVT VT2, const SDOperand *Ops, unsigned NumOps) { SDVTList VTs = getVTList(VT1, VT2); - return SelectNodeTo(N, TargetOpc, VTs, Ops, NumOps); + return SelectNodeTo(N, MachineOpc, VTs, Ops, NumOps); } -SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc, +SDNode *SelectionDAG::SelectNodeTo(SDNode *N, unsigned MachineOpc, MVT VT1, MVT VT2) { SDVTList VTs = getVTList(VT1, VT2); - return SelectNodeTo(N, TargetOpc, VTs, (SDOperand *)0, 0); + return SelectNodeTo(N, MachineOpc, VTs, (SDOperand |