diff options
author | Duncan Sands <baldrick@free.fr> | 2008-06-11 11:42:12 +0000 |
---|---|---|
committer | Duncan Sands <baldrick@free.fr> | 2008-06-11 11:42:12 +0000 |
commit | edfcf598faab9ce294712551ecf67093acd1c66e (patch) | |
tree | 8dd77c804dd27fe778fa46ee4d5b511d1eda91a7 /lib/CodeGen/SelectionDAG/SelectionDAG.cpp | |
parent | a068fd32e25b1eee3ad50636b169b0b06a0eb4c5 (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.cpp | 14 |
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); } } |