diff options
author | Evan Cheng <evan.cheng@apple.com> | 2008-04-03 03:13:16 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2008-04-03 03:13:16 +0000 |
commit | 6397c64441ddce3822ab0e712f224a11bd75811c (patch) | |
tree | 80c3634a388b0c9cb821782f8ec90bbdb0762282 /lib/CodeGen/SelectionDAG/SelectionDAG.cpp | |
parent | ee4fa1977dd3a495a8857eef924ee5961db765c6 (diff) |
Backing out 48222 temporarily.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@49124 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/SelectionDAG.cpp')
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 169 |
1 files changed, 70 insertions, 99 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 1a12432859..f259b2b60d 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -10,6 +10,7 @@ // This implements the SelectionDAG class. // //===----------------------------------------------------------------------===// + #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/Constants.h" #include "llvm/GlobalAlias.h" @@ -464,15 +465,14 @@ void SelectionDAG::RemoveDeadNodes() { // no cycles in the graph. for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) { SDNode *Operand = I->Val; - Operand->removeUser(std::distance(N->op_begin(), I), N); + Operand->removeUser(N); // Now that we removed this operand, see if there are no uses of it left. if (Operand->use_empty()) DeadNodes.push_back(Operand); } - if (N->OperandsNeedDelete) { + if (N->OperandsNeedDelete) delete[] N->OperandList; - } N->OperandList = 0; N->NumOperands = 0; @@ -504,15 +504,14 @@ void SelectionDAG::RemoveDeadNode(SDNode *N, DAGUpdateListener *UpdateListener){ // no cycles in the graph. for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) { SDNode *Operand = I->Val; - Operand->removeUser(std::distance(N->op_begin(), I), N); + Operand->removeUser(N); // Now that we removed this operand, see if there are no uses of it left. if (Operand->use_empty()) DeadNodes.push_back(Operand); } - if (N->OperandsNeedDelete) { + if (N->OperandsNeedDelete) delete[] N->OperandList; - } N->OperandList = 0; N->NumOperands = 0; @@ -539,10 +538,9 @@ void SelectionDAG::DeleteNodeNotInCSEMaps(SDNode *N) { // Drop all of the operands and decrement used nodes use counts. for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) - I->Val->removeUser(std::distance(N->op_begin(), I), N); - if (N->OperandsNeedDelete) { + I->Val->removeUser(N); + if (N->OperandsNeedDelete) delete[] N->OperandList; - } N->OperandList = 0; N->NumOperands = 0; @@ -703,9 +701,8 @@ SelectionDAG::~SelectionDAG() { while (!AllNodes.empty()) { SDNode *N = AllNodes.begin(); N->SetNextInBucket(0); - if (N->OperandsNeedDelete) { + if (N->OperandsNeedDelete) delete [] N->OperandList; - } N->OperandList = 0; N->NumOperands = 0; AllNodes.pop_front(); @@ -2897,10 +2894,9 @@ UpdateNodeOperands(SDOperand InN, SDOperand Op) { RemoveNodeFromCSEMaps(N); // Now we update the operands. - N->OperandList[0].Val->removeUser(0, N); + N->OperandList[0].Val->removeUser(N); + Op.Val->addUser(N); N->OperandList[0] = Op; - N->OperandList[0].setUser(N); - Op.Val->addUser(0, N); // If this gets put into a CSE map, add it. if (InsertPos) CSEMap.InsertNode(N, InsertPos); @@ -2927,16 +2923,14 @@ UpdateNodeOperands(SDOperand InN, SDOperand Op1, SDOperand Op2) { // Now we update the operands. if (N->OperandList[0] != Op1) { - N->OperandList[0].Val->removeUser(0, N); + N->OperandList[0].Val->removeUser(N); + Op1.Val->addUser(N); N->OperandList[0] = Op1; - N->OperandList[0].setUser(N); - Op1.Val->addUser(0, N); } if (N->OperandList[1] != Op2) { - N->OperandList[1].Val->removeUser(1, N); + N->OperandList[1].Val->removeUser(N); + Op2.Val->addUser(N); N->OperandList[1] = Op2; - N->OperandList[1].setUser(N); - Op2.Val->addUser(1, N); } // If this gets put into a CSE map, add it. @@ -2964,6 +2958,7 @@ UpdateNodeOperands(SDOperand N, SDOperand Op1, SDOperand Op2, return UpdateNodeOperands(N, Ops, 5); } + SDOperand SelectionDAG:: UpdateNodeOperands(SDOperand InN, SDOperand *Ops, unsigned NumOps) { SDNode *N = InN.Val; @@ -2994,10 +2989,9 @@ UpdateNodeOperands(SDOperand InN, SDOperand *Ops, unsigned NumOps) { // Now we update the operands. for (unsigned i = 0; i != NumOps; ++i) { if (N->OperandList[i] != Ops[i]) { - N->OperandList[i].Val->removeUser(i, N); + N->OperandList[i].Val->removeUser(N); + Ops[i].Val->addUser(N); N->OperandList[i] = Ops[i]; - N->OperandList[i].setUser(N); - Ops[i].Val->addUser(i, N); } } @@ -3006,6 +3000,7 @@ UpdateNodeOperands(SDOperand InN, 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. @@ -3018,14 +3013,13 @@ void SDNode::MorphNodeTo(unsigned Opc, SDVTList L, // Clear the operands list, updating used nodes to remove this from their // use list. for (op_iterator I = op_begin(), E = op_end(); I != E; ++I) - I->Val->removeUser(std::distance(op_begin(), I), this); + I->Val->removeUser(this); // If NumOps is larger than the # of operands we currently have, reallocate // the operand list. if (NumOps > NumOperands) { - if (OperandsNeedDelete) { + if (OperandsNeedDelete) delete [] OperandList; - } OperandList = new SDOperand[NumOps]; OperandsNeedDelete = true; } @@ -3035,10 +3029,8 @@ void SDNode::MorphNodeTo(unsigned Opc, SDVTList L, for (unsigned i = 0, e = NumOps; i != e; ++i) { OperandList[i] = Ops[i]; - OperandList[i].setUser(this); SDNode *N = OperandList[i].Val; - N->addUser(i, this); - ++N->UsesSize; + N->Uses.push_back(this); } } @@ -3306,27 +3298,21 @@ void SelectionDAG::ReplaceAllUsesWith(SDOperand FromN, SDOperand To, assert(From->getNumValues() == 1 && FromN.ResNo == 0 && "Cannot replace with this method!"); assert(From != To.Val && "Cannot replace uses of with self"); - - SmallSetVector<SDNode*, 16> Users; + while (!From->use_empty()) { - SDNode::use_iterator UI = From->use_begin(); - SDNode *U = UI->getUser(); - - // Remember that this node is about to morph. - if (Users.count(U)) - continue; - Users.insert(U); + // Process users until they are all gone. + SDNode *U = *From->use_begin(); + // This node is about to morph, remove its old self from the CSE maps. RemoveNodeFromCSEMaps(U); - int operandNum = 0; - for (SDNode::op_iterator I = U->op_begin(), E = U->op_end(); - I != E; ++I, ++operandNum) + + for (SDOperand *I = U->OperandList, *E = U->OperandList+U->NumOperands; + I != E; ++I) if (I->Val == From) { - From->removeUser(operandNum, U); + From->removeUser(U); *I = To; - I->setUser(U); - To.Val->addUser(operandNum, U); - } + To.Val->addUser(U); + } // Now that we have modified U, add it back to the CSE maps. If it already // exists there, recursively merge the results together. @@ -3360,26 +3346,21 @@ void SelectionDAG::ReplaceAllUsesWith(SDNode *From, SDNode *To, return ReplaceAllUsesWith(SDOperand(From, 0), SDOperand(To, 0), UpdateListener); - SmallSetVector<SDNode*, 16> Users; while (!From->use_empty()) { - SDNode::use_iterator UI = From->use_begin(); - SDNode *U = UI->getUser(); - - // Remember that this node is about to morph. - if (Users.count(U)) - continue; - Users.insert(U); + // Process users until they are all gone. + SDNode *U = *From->use_begin(); + // This node is about to morph, remove its old self from the CSE maps. RemoveNodeFromCSEMaps(U); - int operandNum = 0; - for (SDNode::op_iterator I = U->op_begin(), E = U->op_end(); - I != E; ++I, ++operandNum) + + for (SDOperand *I = U->OperandList, *E = U->OperandList+U->NumOperands; + I != E; ++I) if (I->Val == From) { - From->removeUser(operandNum, U); + From->removeUser(U); I->Val = To; - To->addUser(operandNum, U); + To->addUser(U); } - + // Now that we have modified U, add it back to the CSE maps. If it already // exists there, recursively merge the results together. if (SDNode *Existing = AddNonLeafNodeToCSEMaps(U)) { @@ -3408,28 +3389,22 @@ void SelectionDAG::ReplaceAllUsesWith(SDNode *From, if (From->getNumValues() == 1) // Handle the simple case efficiently. return ReplaceAllUsesWith(SDOperand(From, 0), To[0], UpdateListener); - SmallSetVector<SDNode*, 16> Users; while (!From->use_empty()) { - SDNode::use_iterator UI = From->use_begin(); - SDNode *U = UI->getUser(); - - // Remember that this node is about to morph. - if (Users.count(U)) - continue; - Users.insert(U); + // Process users until they are all gone. + SDNode *U = *From->use_begin(); + // This node is about to morph, remove its old self from the CSE maps. RemoveNodeFromCSEMaps(U); - int operandNum = 0; - for (SDNode::op_iterator I = U->op_begin(), E = U->op_end(); - I != E; ++I, ++operandNum) + + for (SDOperand *I = U->OperandList, *E = U->OperandList+U->NumOperands; + I != E; ++I) if (I->Val == From) { const SDOperand &ToOp = To[I->ResNo]; - From->removeUser(operandNum, U); + From->removeUser(U); *I = ToOp; - I->setUser(U); - ToOp.Val->addUser(operandNum, U); + ToOp.Val->addUser(U); } - + // Now that we have modified U, add it back to the CSE maps. If it already // exists there, recursively merge the results together. if (SDNode *Existing = AddNonLeafNodeToCSEMaps(U)) { @@ -3459,7 +3434,7 @@ namespace { ChainedSetUpdaterListener(SmallSetVector<SDNode*, 16> &set, SelectionDAG::DAGUpdateListener *chain) : Set(set), Chain(chain) {} - + virtual void NodeDeleted(SDNode *N) { Set.remove(N); if (Chain) Chain->NodeDeleted(N); @@ -3487,13 +3462,7 @@ void SelectionDAG::ReplaceAllUsesOfValueWith(SDOperand From, SDOperand To, // Get all of the users of From.Val. We want these in a nice, // deterministically ordered and uniqued set, so we use a SmallSetVector. - SmallSetVector<SDNode*, 16> Users; - for (SDNode::use_iterator UI = From.Val->use_begin(), - E = From.Val->use_end(); UI != E; ++UI) { - SDNode *User = UI->getUser(); - if (!Users.count(User)) - Users.insert(User); - } + SmallSetVector<SDNode*, 16> Users(From.Val->use_begin(), From.Val->use_end()); // When one of the recursive merges deletes nodes from the graph, we need to // make sure that UpdateListener is notified *and* that the node is removed @@ -3507,7 +3476,7 @@ void SelectionDAG::ReplaceAllUsesOfValueWith(SDOperand From, SDOperand To, Users.pop_back(); // Scan for an operand that matches From. - SDNode::op_iterator Op = User->op_begin(), E = User->op_end(); + SDOperand *Op = User->OperandList, *E = User->OperandList+User->NumOperands; for (; Op != E; ++Op) if (*Op == From) break; @@ -3521,10 +3490,9 @@ void SelectionDAG::ReplaceAllUsesOfValueWith(SDOperand From, SDOperand To, // Update all operands that match "From" in case there are multiple uses. for (; Op != E; ++Op) { if (*Op == From) { - From.Val->removeUser(Op-User->op_begin(), User); - *Op = To; - Op->setUser(User); - To.Val->addUser(Op-User->op_begin(), User); + From.Val->removeUser(User); + *Op = To; + To.Val->addUser(User); } } @@ -3704,13 +3672,16 @@ bool SDNode::hasNUsesOfValue(unsigned NUses, unsigned Value) const { SmallPtrSet<SDNode*, 32> UsersHandled; - // TODO: Only iterate over uses of a given value of the node - for (SDNode::use_iterator UI = use_begin(), E = use_end(); UI != E; ++UI) { - if (*UI == TheValue) { - if (NUses == 0) - return false; - --NUses; - } + for (SDNode::use_iterator UI = Uses.begin(), E = Uses.end(); UI != E; ++UI) { + SDNode *User = *UI; + if (User->getNumOperands() == 1 || + UsersHandled.insert(User)) // First time we've seen this? + for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i) + if (User->getOperand(i) == TheValue) { + if (NUses == 0) + return false; // too many uses + --NUses; + } } // Found exactly the right number of uses? @@ -3729,8 +3700,8 @@ bool SDNode::hasAnyUseOfValue(unsigned Value) const { SmallPtrSet<SDNode*, 32> UsersHandled; - for (SDNode::use_iterator UI = use_begin(), E = use_end(); UI != E; ++UI) { - SDNode *User = UI->getUser(); + for (SDNode::use_iterator UI = Uses.begin(), E = Uses.end(); UI != E; ++UI) { + SDNode *User = *UI; if (User->getNumOperands() == 1 || UsersHandled.insert(User)) // First time we've seen this? for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i) @@ -3748,7 +3719,7 @@ bool SDNode::hasAnyUseOfValue(unsigned Value) const { bool SDNode::isOnlyUseOf(SDNode *N) const { bool Seen = false; for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) { - SDNode *User = I->getUser(); + SDNode *User = *I; if (User == this) Seen = true; else @@ -3760,7 +3731,7 @@ bool SDNode::isOnlyUseOf(SDNode *N) const { /// isOperand - Return true if this node is an operand of N. /// -bool SDOperandImpl::isOperandOf(SDNode *N) const { +bool SDOperand::isOperandOf(SDNode *N) const { for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) if (*this == N->getOperand(i)) return true; @@ -3779,7 +3750,7 @@ bool SDNode::isOperandOf(SDNode *N) const { /// side-effecting instructions. In practice, this looks through token /// factors and non-volatile loads. In order to remain efficient, this only /// looks a couple of nodes in, it does not do an exhaustive search. -bool SDOperandImpl::reachesChainWithoutSideEffects(SDOperandImpl Dest, +bool SDOperand::reachesChainWithoutSideEffects(SDOperand Dest, unsigned Depth) const { if (*this == Dest) return true; |