<p dir="ltr">Thanks! </p>
<div class="gmail_quote">On May 5, 2015 7:12 PM, "David Majnemer" <<a href="mailto:david.majnemer@gmail.com">david.majnemer@gmail.com</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: majnemer<br>
Date: Tue May  5 15:14:22 2015<br>
New Revision: 236539<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=236539&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=236539&view=rev</a><br>
Log:<br>
[Inliner] Discard empty COMDAT groups<br>
<br>
COMDAT groups which have become rendered unused because of inline are<br>
discardable if we can prove that we've made the group empty.<br>
<br>
This fixes PR22285.<br>
<br>
Added:<br>
    llvm/trunk/test/Transforms/Inline/pr22285.ll<br>
Modified:<br>
    llvm/trunk/lib/Transforms/IPO/Inliner.cpp<br>
<br>
Modified: llvm/trunk/lib/Transforms/IPO/Inliner.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/Inliner.cpp?rev=236539&r1=236538&r2=236539&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/Inliner.cpp?rev=236539&r1=236538&r2=236539&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Transforms/IPO/Inliner.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/IPO/Inliner.cpp Tue May  5 15:14:22 2015<br>
@@ -625,6 +625,21 @@ bool Inliner::doFinalization(CallGraph &<br>
 /// Remove dead functions that are not included in DNR (Do Not Remove) list.<br>
 bool Inliner::removeDeadFunctions(CallGraph &CG, bool AlwaysInlineOnly) {<br>
   SmallVector<CallGraphNode*, 16> FunctionsToRemove;<br>
+  SmallVector<CallGraphNode *, 16> DeadFunctionsInComdats;<br>
+  SmallDenseMap<const Comdat *, int, 16> ComdatEntriesAlive;<br>
+<br>
+  auto RemoveCGN = [&](CallGraphNode *CGN) {<br>
+    // Remove any call graph edges from the function to its callees.<br>
+    CGN->removeAllCalledFunctions();<br>
+<br>
+    // Remove any edges from the external node to the function's call graph<br>
+    // node.  These edges might have been made irrelegant due to<br>
+    // optimization of the program.<br>
+    CG.getExternalCallingNode()->removeAnyCallEdgeTo(CGN);<br>
+<br>
+    // Removing the node for callee from the call graph and delete it.<br>
+    FunctionsToRemove.push_back(CGN);<br>
+  };<br>
<br>
   // Scan for all of the functions, looking for ones that should now be removed<br>
   // from the program.  Insert the dead ones in the FunctionsToRemove set.<br>
@@ -651,20 +666,45 @@ bool Inliner::removeDeadFunctions(CallGr<br>
     // without also dropping the other members of the COMDAT.<br>
     // The inliner doesn't visit non-function entities which are in COMDAT<br>
     // groups so it is unsafe to do so *unless* the linkage is local.<br>
-    if (!F->hasLocalLinkage() && F->hasComdat())<br>
-      continue;<br>
-<br>
-    // Remove any call graph edges from the function to its callees.<br>
-    CGN->removeAllCalledFunctions();<br>
+    if (!F->hasLocalLinkage()) {<br>
+      if (const Comdat *C = F->getComdat()) {<br>
+        --ComdatEntriesAlive[C];<br>
+        DeadFunctionsInComdats.push_back(CGN);<br>
+        continue;<br>
+      }<br>
+    }<br>
<br>
-    // Remove any edges from the external node to the function's call graph<br>
-    // node.  These edges might have been made irrelegant due to<br>
-    // optimization of the program.<br>
-    CG.getExternalCallingNode()->removeAnyCallEdgeTo(CGN);<br>
+    RemoveCGN(CGN);<br>
+  }<br>
+  if (!DeadFunctionsInComdats.empty()) {<br>
+    // Count up all the entities in COMDAT groups<br>
+    auto ComdatGroupReferenced = [&](const Comdat *C) {<br>
+      auto I = ComdatEntriesAlive.find(C);<br>
+      if (I != ComdatEntriesAlive.end())<br>
+        ++(I->getSecond());<br>
+    };<br>
+    for (const Function &F : CG.getModule())<br>
+      if (const Comdat *C = F.getComdat())<br>
+        ComdatGroupReferenced(C);<br>
+    for (const GlobalVariable &GV : CG.getModule().globals())<br>
+      if (const Comdat *C = GV.getComdat())<br>
+        ComdatGroupReferenced(C);<br>
+    for (const GlobalAlias &GA : CG.getModule().aliases())<br>
+      if (const Comdat *C = GA.getComdat())<br>
+        ComdatGroupReferenced(C);<br>
+    for (CallGraphNode *CGN : DeadFunctionsInComdats) {<br>
+      Function *F = CGN->getFunction();<br>
+      const Comdat *C = F->getComdat();<br>
+      int NumAlive = ComdatEntriesAlive[C];<br>
+      // We can remove functions in a COMDAT group if the entire group is dead.<br>
+      assert(NumAlive >= 0);<br>
+      if (NumAlive > 0)<br>
+        continue;<br>
<br>
-    // Removing the node for callee from the call graph and delete it.<br>
-    FunctionsToRemove.push_back(CGN);<br>
+      RemoveCGN(CGN);<br>
+    }<br>
   }<br>
+<br>
   if (FunctionsToRemove.empty())<br>
     return false;<br>
<br>
<br>
Added: llvm/trunk/test/Transforms/Inline/pr22285.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Inline/pr22285.ll?rev=236539&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Inline/pr22285.ll?rev=236539&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/Transforms/Inline/pr22285.ll (added)<br>
+++ llvm/trunk/test/Transforms/Inline/pr22285.ll Tue May  5 15:14:22 2015<br>
@@ -0,0 +1,15 @@<br>
+; RUN: opt < %s -inline -S | FileCheck %s<br>
+<br>
+$f1 = comdat any<br>
+; CHECK-NOT: $f1 = comdat any<br>
+<br>
+define void @f2() {<br>
+  call void @f1()<br>
+  ret void<br>
+}<br>
+; CHECK-LABEL: define void @f2<br>
+<br>
+define linkonce_odr void @f1() comdat {<br>
+  ret void<br>
+}<br>
+; CHECK-NOT: define linkonce_odr void @f1() comdat<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div>