aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2008-06-11 11:42:12 +0000
committerDuncan Sands <baldrick@free.fr>2008-06-11 11:42:12 +0000
commitedfcf598faab9ce294712551ecf67093acd1c66e (patch)
tree8dd77c804dd27fe778fa46ee4d5b511d1eda91a7 /lib/CodeGen/SelectionDAG/SelectionDAG.cpp
parenta068fd32e25b1eee3ad50636b169b0b06a0eb4c5 (diff)
Sometimes (rarely) nodes held in LegalizeTypes
maps can be deleted. This happens when RAUW replaces a node N with another equivalent node E, deleting the first node. Solve this by adding (N, E) to ReplacedNodes, which is already used to remap nodes to replacements. This means that deleted nodes are being allowed in maps, which can be delicate: the memory may be reused for a new node which might get confused with the old deleted node pointer hanging around in the maps, so detect this and flush out maps if it occurs (ExpungeNode). The expunging operation is expensive, however it never occurs during a llvm-gcc bootstrap or anywhere in the nightly testsuite. It occurs three times in "make check": Alpha/illegal-element-type.ll, PowerPC/illegal-element-type.ll and X86/mmx-shift.ll. If expunging proves to be too expensive then there are other more complicated ways of solving the problem. In the normal case this patch adds the overhead of a few more map lookups, which is hopefully negligable. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@52214 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/SelectionDAG.cpp')
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp14
1 files changed, 7 insertions, 7 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index b3acc9a39e..4f577fc269 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -495,7 +495,7 @@ void SelectionDAG::RemoveDeadNode(SDNode *N, DAGUpdateListener *UpdateListener){
DeadNodes.pop_back();
if (UpdateListener)
- UpdateListener->NodeDeleted(N);
+ UpdateListener->NodeDeleted(N, 0);
// Take the node out of the appropriate CSE map.
RemoveNodeFromCSEMaps(N);
@@ -3886,7 +3886,7 @@ void SelectionDAG::ReplaceAllUsesWith(SDOperand FromN, SDOperand To,
ReplaceAllUsesWith(U, Existing, UpdateListener);
// U is now dead. Inform the listener if it exists and delete it.
if (UpdateListener)
- UpdateListener->NodeDeleted(U);
+ UpdateListener->NodeDeleted(U, Existing);
DeleteNodeNotInCSEMaps(U);
} else {
// If the node doesn't already exist, we updated it. Inform a listener if
@@ -3933,7 +3933,7 @@ void SelectionDAG::ReplaceAllUsesWith(SDNode *From, SDNode *To,
ReplaceAllUsesWith(U, Existing, UpdateListener);
// U is now dead. Inform the listener if it exists and delete it.
if (UpdateListener)
- UpdateListener->NodeDeleted(U);
+ UpdateListener->NodeDeleted(U, Existing);
DeleteNodeNotInCSEMaps(U);
} else {
// If the node doesn't already exist, we updated it. Inform a listener if
@@ -3978,7 +3978,7 @@ void SelectionDAG::ReplaceAllUsesWith(SDNode *From,
ReplaceAllUsesWith(U, Existing, UpdateListener);
// U is now dead. Inform the listener if it exists and delete it.
if (UpdateListener)
- UpdateListener->NodeDeleted(U);
+ UpdateListener->NodeDeleted(U, Existing);
DeleteNodeNotInCSEMaps(U);
} else {
// If the node doesn't already exist, we updated it. Inform a listener if
@@ -4002,9 +4002,9 @@ namespace {
SelectionDAG::DAGUpdateListener *chain)
: Set(set), Chain(chain) {}
- virtual void NodeDeleted(SDNode *N) {
+ virtual void NodeDeleted(SDNode *N, SDNode *E) {
Set.remove(N);
- if (Chain) Chain->NodeDeleted(N);
+ if (Chain) Chain->NodeDeleted(N, E);
}
virtual void NodeUpdated(SDNode *N) {
if (Chain) Chain->NodeUpdated(N);
@@ -4086,7 +4086,7 @@ void SelectionDAG::ReplaceAllUsesOfValueWith(SDOperand From, SDOperand To,
ReplaceAllUsesWith(User, Existing, &CSUL);
// User is now dead. Notify a listener if present.
- if (UpdateListener) UpdateListener->NodeDeleted(User);
+ if (UpdateListener) UpdateListener->NodeDeleted(User, Existing);
DeleteNodeNotInCSEMaps(User);
}
}