aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2007-11-21 16:43:19 +0000
committerDuncan Sands <baldrick@free.fr>2007-11-21 16:43:19 +0000
commitbaccd5872e87adb0431ae3ebfa83719b97880808 (patch)
tree8fc2c9d9030b7119ee82d8ef4a0f591810fd55f8 /lib/CodeGen/SelectionDAG/LegalizeDAGTypes.cpp
parent79a2c4f7a9bc6d825fc3402ab81ad35e9c3aac67 (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.cpp37
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;