aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/patches
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/patches')
-rw-r--r--contrib/llvm/patches/patch-r274442-llvm-r221709-debug-oom.diff73
1 files changed, 73 insertions, 0 deletions
diff --git a/contrib/llvm/patches/patch-r274442-llvm-r221709-debug-oom.diff b/contrib/llvm/patches/patch-r274442-llvm-r221709-debug-oom.diff
new file mode 100644
index 000000000000..f70ddcef8940
--- /dev/null
+++ b/contrib/llvm/patches/patch-r274442-llvm-r221709-debug-oom.diff
@@ -0,0 +1,73 @@
+Pull in r221709 from upstream llvm trunk (by Frédéric Riss):
+
+ Totally forget deallocated SDNodes in SDDbgInfo.
+
+ What would happen before that commit is that the SDDbgValues associated with
+ a deallocated SDNode would be marked Invalidated, but SDDbgInfo would keep
+ a map entry keyed by the SDNode pointer pointing to this list of invalidated
+ SDDbgNodes. As the memory gets reused, the list might get wrongly associated
+ with another new SDNode. As the SDDbgValues are cloned when they are transfered,
+ this can lead to an exponential number of SDDbgValues being produced during
+ DAGCombine like in http://llvm.org/bugs/show_bug.cgi?id=20893
+
+ Note that the previous behavior wasn't really buggy as the invalidation made
+ sure that the SDDbgValues won't be used. This commit can be considered a
+ memory optimization and as such is really hard to validate in a unit-test.
+
+This should fix abnormally large memory usage and resulting OOM crashes
+when compiling certain ports with debug information.
+
+Reported by: Dmitry Marakasov <amdmi3@amdmi3.ru>
+Upstream PRs: http://llvm.org/PR19031 http://llvm.org/PR20893
+
+Introduced here: http://svnweb.freebsd.org/changeset/base/274442
+
+Index: include/llvm/CodeGen/SelectionDAG.h
+===================================================================
+--- include/llvm/CodeGen/SelectionDAG.h
++++ include/llvm/CodeGen/SelectionDAG.h
+@@ -127,6 +127,10 @@ class SDDbgInfo {
+ DbgValMap[Node].push_back(V);
+ }
+
++ /// \brief Invalidate all DbgValues attached to the node and remove
++ /// it from the Node-to-DbgValues map.
++ void erase(const SDNode *Node);
++
+ void clear() {
+ DbgValMap.clear();
+ DbgValues.clear();
+Index: lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+===================================================================
+--- lib/CodeGen/SelectionDAG/SelectionDAG.cpp
++++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+@@ -625,6 +625,15 @@ void SelectionDAG::DeleteNodeNotInCSEMaps(SDNode *
+ DeallocateNode(N);
+ }
+
++void SDDbgInfo::erase(const SDNode *Node) {
++ DbgValMapType::iterator I = DbgValMap.find(Node);
++ if (I == DbgValMap.end())
++ return;
++ for (unsigned J = 0, N = I->second.size(); J != N; ++J)
++ I->second[J]->setIsInvalidated();
++ DbgValMap.erase(I);
++}
++
+ void SelectionDAG::DeallocateNode(SDNode *N) {
+ if (N->OperandsNeedDelete)
+ delete[] N->OperandList;
+@@ -635,10 +644,9 @@ void SelectionDAG::DeallocateNode(SDNode *N) {
+
+ NodeAllocator.Deallocate(AllNodes.remove(N));
+
+- // If any of the SDDbgValue nodes refer to this SDNode, invalidate them.
+- ArrayRef<SDDbgValue*> DbgVals = DbgInfo->getSDDbgValues(N);
+- for (unsigned i = 0, e = DbgVals.size(); i != e; ++i)
+- DbgVals[i]->setIsInvalidated();
++ // If any of the SDDbgValue nodes refer to this SDNode, invalidate
++ // them and forget about that node.
++ DbgInfo->erase(N);
+ }
+
+ /// RemoveNodeFromCSEMaps - Take the specified node out of the CSE map that