diff options
author | Duncan Sands <baldrick@free.fr> | 2007-11-21 16:43:19 +0000 |
---|---|---|
committer | Duncan Sands <baldrick@free.fr> | 2007-11-21 16:43:19 +0000 |
commit | baccd5872e87adb0431ae3ebfa83719b97880808 (patch) | |
tree | 8fc2c9d9030b7119ee82d8ef4a0f591810fd55f8 /lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp | |
parent | 79a2c4f7a9bc6d825fc3402ab81ad35e9c3aac67 (diff) |
Fix a bug in which node A is replaced by node B, but later
node A gets back into the DAG again because it was hiding in
one of the node maps: make sure that node replacement happens
in those maps too.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44263 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp')
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp index b63bd8f1de..bb65a67204 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp @@ -92,7 +92,11 @@ class VISIBILITY_HIDDEN DAGTypeLegalizer { /// ExpandedNodes - For nodes that need to be expanded this map indicates /// which operands are the expanded version of the input. DenseMap<SDOperand, std::pair<SDOperand, SDOperand> > ExpandedNodes; - + + /// ReplacedNodes - For nodes that have been replaced with another, + /// indicates the replacement node to use. + DenseMap<SDOperand, SDOperand> ReplacedNodes; + /// Worklist - This defines a worklist of nodes to process. In order to be /// pushed onto this worklist, all operands of a node must have already been /// processed. @@ -112,12 +116,15 @@ private: void MarkNewNodes(SDNode *N); void ReplaceLegalValueWith(SDOperand From, SDOperand To); - + + void RemapNode(SDOperand &N); + SDOperand GetPromotedOp(SDOperand Op) { - Op = PromotedNodes[Op]; - assert(Op.Val && "Operand wasn't promoted?"); - return Op; - } + SDOperand &PromotedOp = PromotedNodes[Op]; + RemapNode(PromotedOp); + assert(PromotedOp.Val && "Operand wasn't promoted?"); + return PromotedOp; + } void SetPromotedOp(SDOperand Op, SDOperand Result); /// GetPromotedZExtOp - Get a promoted operand and zero extend it to the final @@ -397,7 +404,11 @@ void DAGTypeLegalizer::ReplaceLegalValueWith(SDOperand From, SDOperand To) { // Anything that used the old node should now use the new one. Note that this // can potentially cause recursive merging. DAG.ReplaceAllUsesOfValueWith(From, To); - + + // The old node may still be present in ExpandedNodes or PromotedNodes. + // Inform them about the replacement. + ReplacedNodes[From] = To; + // Since we just made an unstructured update to the DAG, which could wreak // general havoc on anything that once used N and now uses Res, walk all users // of the result, updating their flags. @@ -414,6 +425,16 @@ void DAGTypeLegalizer::ReplaceLegalValueWith(SDOperand From, SDOperand To) { } } +/// RemapNode - If the specified value was already legalized to another value, +/// replace it by that value. +void DAGTypeLegalizer::RemapNode(SDOperand &N) { + DenseMap<SDOperand, SDOperand>::iterator I = ReplacedNodes.find(N); + if (I != ReplacedNodes.end()) { + RemapNode(I->second); + N = I->second; + } +} + void DAGTypeLegalizer::SetPromotedOp(SDOperand Op, SDOperand Result) { if (Result.Val->getNodeId() == NewNode) MarkNewNodes(Result.Val); @@ -426,6 +447,8 @@ void DAGTypeLegalizer::SetPromotedOp(SDOperand Op, SDOperand Result) { void DAGTypeLegalizer::GetExpandedOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi) { std::pair<SDOperand, SDOperand> &Entry = ExpandedNodes[Op]; + RemapNode(Entry.first); + RemapNode(Entry.second); assert(Entry.first.Val && "Operand isn't expanded"); Lo = Entry.first; Hi = Entry.second; |