]> xenbits.xensource.com Git - people/julieng/freebsd.git/commitdiff
Pull in r221709 from upstream llvm trunk (by Frédéric Riss):
authordim <dim@FreeBSD.org>
Wed, 12 Nov 2014 20:01:10 +0000 (20:01 +0000)
committerdim <dim@FreeBSD.org>
Wed, 12 Nov 2014 20:01:10 +0000 (20:01 +0000)
  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
MFC after: 1 week

contrib/llvm/include/llvm/CodeGen/SelectionDAG.h
contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

index 82becca315a1497ee8ffbd953377b503eb5b2877..9e1115b117ce3163c1c0d4e6ff60b8326547b0de 100644 (file)
@@ -127,6 +127,10 @@ public:
       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 45d5a4fa69e8384dece2c9f82bdba59805234a05..a702bee3d687657e778f9692c587e10c02fcb934 100644 (file)
@@ -625,6 +625,15 @@ void SelectionDAG::DeleteNodeNotInCSEMaps(SDNode *N) {
   DeallocateNode(N);
 }
 
+void SDDbgInfo::erase(const SDNode *Node) {
+  DbgValMapType::iterator I = DbgValMap.find(Node);
+  if (I == DbgValMap.end())
+    return;
+  for (auto &Val: I->second)
+    Val->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