[llvm] r266132 - Add a pass to name anonymous/nameless function

Mehdi Amini via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 12 14:35:29 PDT 2016


Author: mehdi_amini
Date: Tue Apr 12 16:35:28 2016
New Revision: 266132

URL: http://llvm.org/viewvc/llvm-project?rev=266132&view=rev
Log:
Add a pass to name anonymous/nameless function

Summary:
For correct handling of alias to nameless
function, we need to be able to refer them through a GUID in the summary.
Here we name them using a hash of the non-private global names in the module.

Reviewers: tejohnson

Subscribers: joker.eph, llvm-commits

Differential Revision: http://reviews.llvm.org/D18883

From: Mehdi Amini <mehdi.amini at apple.com>

Added:
    llvm/trunk/lib/Transforms/Utils/NameAnonFunctions.cpp
    llvm/trunk/test/Transforms/NameAnonFunctions/
    llvm/trunk/test/Transforms/NameAnonFunctions/rename.ll
Modified:
    llvm/trunk/include/llvm/InitializePasses.h
    llvm/trunk/include/llvm/Transforms/Scalar.h
    llvm/trunk/include/llvm/Transforms/Utils/ModuleUtils.h
    llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp
    llvm/trunk/lib/Transforms/Utils/CMakeLists.txt
    llvm/trunk/lib/Transforms/Utils/Utils.cpp

Modified: llvm/trunk/include/llvm/InitializePasses.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=266132&r1=266131&r2=266132&view=diff
==============================================================================
--- llvm/trunk/include/llvm/InitializePasses.h (original)
+++ llvm/trunk/include/llvm/InitializePasses.h Tue Apr 12 16:35:28 2016
@@ -221,6 +221,7 @@ void initializeMergedLoadStoreMotionPass
 void initializeMetaRenamerPass(PassRegistry&);
 void initializeMergeFunctionsPass(PassRegistry&);
 void initializeModuleDebugInfoPrinterPass(PassRegistry&);
+void initializeNameAnonFunctionPass(PassRegistry &);
 void initializeNaryReassociatePass(PassRegistry&);
 void initializeNoAAPass(PassRegistry&);
 void initializeObjCARCAAWrapperPassPass(PassRegistry&);

Modified: llvm/trunk/include/llvm/Transforms/Scalar.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar.h?rev=266132&r1=266131&r2=266132&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Scalar.h (original)
+++ llvm/trunk/include/llvm/Transforms/Scalar.h Tue Apr 12 16:35:28 2016
@@ -503,6 +503,9 @@ FunctionPass *createLoopVersioningPass()
 //
 FunctionPass *createLoopDataPrefetchPass();
 
+///===---------------------------------------------------------------------===//
+ModulePass *createNameAnonFunctionPass();
+
 } // End llvm namespace
 
 #endif

Modified: llvm/trunk/include/llvm/Transforms/Utils/ModuleUtils.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/ModuleUtils.h?rev=266132&r1=266131&r2=266132&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/ModuleUtils.h (original)
+++ llvm/trunk/include/llvm/Transforms/Utils/ModuleUtils.h Tue Apr 12 16:35:28 2016
@@ -61,6 +61,11 @@ std::pair<Function *, Function *> create
     Module &M, StringRef CtorName, StringRef InitName,
     ArrayRef<Type *> InitArgTypes, ArrayRef<Value *> InitArgs,
     StringRef VersionCheckName = StringRef());
+
+/// Rename all the anon functions in the module using a hash computed from
+/// the list of public globals in the module.
+bool nameUnamedFunctions(Module &M);
+
 } // End llvm namespace
 
 #endif //  LLVM_TRANSFORMS_UTILS_MODULEUTILS_H

Modified: llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp?rev=266132&r1=266131&r2=266132&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp Tue Apr 12 16:35:28 2016
@@ -247,6 +247,8 @@ void PassManagerBuilder::addFunctionSimp
   if (PrepareForThinLTO) {
     MPM.add(createAggressiveDCEPass());        // Delete dead instructions
     addInstructionCombiningPass(MPM);          // Combine silly seq's
+    // Rename anon function to export them
+    MPM.add(createNameAnonFunctionPass());
     return;
   }
   // Rotate Loop - disable header duplication at -Oz

Modified: llvm/trunk/lib/Transforms/Utils/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CMakeLists.txt?rev=266132&r1=266131&r2=266132&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/CMakeLists.txt (original)
+++ llvm/trunk/lib/Transforms/Utils/CMakeLists.txt Tue Apr 12 16:35:28 2016
@@ -31,6 +31,7 @@ add_llvm_library(LLVMTransformUtils
   MemorySSA.cpp
   MetaRenamer.cpp
   ModuleUtils.cpp
+  NameAnonFunctions.cpp
   PromoteMemoryToRegister.cpp
   SSAUpdater.cpp
   SanitizerStats.cpp

Added: llvm/trunk/lib/Transforms/Utils/NameAnonFunctions.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/NameAnonFunctions.cpp?rev=266132&view=auto
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/NameAnonFunctions.cpp (added)
+++ llvm/trunk/lib/Transforms/Utils/NameAnonFunctions.cpp Tue Apr 12 16:35:28 2016
@@ -0,0 +1,102 @@
+//===- NameAnonFunctions.cpp - ThinLTO Summary-based Function Import ------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements naming anonymous function to make sure they can be
+// refered to by ThinLTO.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/MD5.h"
+#include "llvm/Transforms/Utils/ModuleUtils.h"
+
+using namespace llvm;
+
+// Compute a "unique" hash for the module based on the name of the public
+// functions.
+class ModuleHasher {
+  Module &TheModule;
+  std::string TheHash;
+
+public:
+  ModuleHasher(Module &M) : TheModule(M) {}
+
+  /// Return the lazily computed hash.
+  std::string &get() {
+    if (!TheHash.empty())
+      // Cache hit :)
+      return TheHash;
+
+    MD5 Hasher;
+    for (auto &F : TheModule) {
+      if (F.isDeclaration() || F.hasLocalLinkage() || !F.hasName())
+        continue;
+      auto Name = F.getName();
+      Hasher.update(Name);
+    }
+    for (auto &GV : TheModule.globals()) {
+      if (GV.isDeclaration() || GV.hasLocalLinkage() || !GV.hasName())
+        continue;
+      auto Name = GV.getName();
+      Hasher.update(Name);
+    }
+
+    // Now return the result.
+    MD5::MD5Result Hash;
+    Hasher.final(Hash);
+    SmallString<32> Result;
+    MD5::stringifyResult(Hash, Result);
+    TheHash = Result.str();
+    return TheHash;
+  }
+};
+
+// Rename all the anon functions in the module
+bool llvm::nameUnamedFunctions(Module &M) {
+  bool Changed = false;
+  ModuleHasher ModuleHash(M);
+  int count = 0;
+  for (auto &F : M) {
+    if (F.hasName())
+      continue;
+    F.setName(Twine("anon.") + ModuleHash.get() + "." + Twine(count++));
+    Changed = true;
+  }
+  return Changed;
+}
+
+namespace {
+
+// Simple pass that provides a name to every anon function.
+class NameAnonFunction : public ModulePass {
+
+public:
+  /// Pass identification, replacement for typeid
+  static char ID;
+
+  /// Specify pass name for debug output
+  const char *getPassName() const override { return "Name Anon Functions"; }
+
+  explicit NameAnonFunction() : ModulePass(ID) {}
+
+  bool runOnModule(Module &M) override { return nameUnamedFunctions(M); }
+};
+char NameAnonFunction::ID = 0;
+
+} // anonymous namespace
+
+INITIALIZE_PASS_BEGIN(NameAnonFunction, "name-anon-functions",
+                      "Provide a name to nameless functions", false, false)
+INITIALIZE_PASS_END(NameAnonFunction, "name-anon-functions",
+                    "Provide a name to nameless functions", false, false)
+
+namespace llvm {
+Pass *createNameAnonFunctionPass() { return new NameAnonFunction(); }
+}

Modified: llvm/trunk/lib/Transforms/Utils/Utils.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/Utils.cpp?rev=266132&r1=266131&r2=266132&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/Utils.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/Utils.cpp Tue Apr 12 16:35:28 2016
@@ -28,6 +28,7 @@ void llvm::initializeTransformUtils(Pass
   initializeLoopSimplifyPass(Registry);
   initializeLowerInvokePass(Registry);
   initializeLowerSwitchPass(Registry);
+  initializeNameAnonFunctionPass(Registry);
   initializePromotePassPass(Registry);
   initializeUnifyFunctionExitNodesPass(Registry);
   initializeInstSimplifierPass(Registry);

Added: llvm/trunk/test/Transforms/NameAnonFunctions/rename.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/NameAnonFunctions/rename.ll?rev=266132&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/NameAnonFunctions/rename.ll (added)
+++ llvm/trunk/test/Transforms/NameAnonFunctions/rename.ll Tue Apr 12 16:35:28 2016
@@ -0,0 +1,27 @@
+; RUN: opt -S -name-anon-functions < %s | FileCheck %s
+
+
+; foo contribute to the unique hash for the module
+define void @foo() {
+    ret void
+}
+
+; bar is internal, and does not contribute to the unique hash for the module
+define internal void @bar() {
+    ret void
+}
+
+; CHECK: define void @anon.acbd18db4cc2f85cedef654fccc4a4d8.0()
+; CHECK: define void @anon.acbd18db4cc2f85cedef654fccc4a4d8.1()
+; CHECK: define void @anon.acbd18db4cc2f85cedef654fccc4a4d8.2()
+
+define void @0() {
+    ret void
+}
+define void @1() {
+    ret void
+}
+define void @2() {
+    ret void
+}
+




More information about the llvm-commits mailing list