[llvm] r236539 - [Inliner] Discard empty COMDAT groups

Rafael EspĂ­ndola rafael.espindola at gmail.com
Thu May 14 14:19:39 PDT 2015


Thanks!
On May 5, 2015 7:12 PM, "David Majnemer" <david.majnemer at gmail.com> wrote:

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


More information about the llvm-commits mailing list