[llvm-commits] [llvm] r113105 - /llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp

Nick Lewycky nicholas at mxc.ca
Sun Sep 5 02:00:32 PDT 2010


Author: nicholas
Date: Sun Sep  5 04:00:32 2010
New Revision: 113105

URL: http://llvm.org/viewvc/llvm-project?rev=113105&view=rev
Log:
Switch FnSet to containing the ComparableFunction instead of a pointer to one.
This reduces malloc traffic (yay!) and removes MergeFunctionsEqualityInfo.

Modified:
    llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp

Modified: llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp?rev=113105&r1=113104&r2=113105&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/MergeFunctions.cpp Sun Sep  5 04:00:32 2010
@@ -86,28 +86,58 @@
 
 class ComparableFunction {
 public:
+  static const ComparableFunction EmptyKey;
+  static const ComparableFunction TombstoneKey;
+
   ComparableFunction(Function *Func, TargetData *TD)
     : Func(Func), Hash(ProfileFunction(Func)), TD(TD) {}
 
-  AssertingVH<Function> const Func;
-  const unsigned Hash;
-  TargetData * const TD;
-};
-
-struct MergeFunctionsEqualityInfo {
-  static ComparableFunction *getEmptyKey() {
-    return reinterpret_cast<ComparableFunction*>(0);
-  }
-  static ComparableFunction *getTombstoneKey() {
-    return reinterpret_cast<ComparableFunction*>(-1);
+  Function *getFunc() const { return Func; }
+  unsigned getHash() const { return Hash; }
+  TargetData *getTD() const { return TD; }
+
+  // Drops AssertingVH reference to the function. Outside of debug mode, this
+  // does nothing.
+  void release() {
+    assert(Func &&
+           "Attempted to release function twice, or release empty/tombstone!");
+    Func = NULL;
   }
-  static unsigned getHashValue(const ComparableFunction *CF) {
-    return CF->Hash;
-  }
-  static bool isEqual(const ComparableFunction *LHS,
-                      const ComparableFunction *RHS);
+
+private:
+  explicit ComparableFunction(unsigned Hash)
+    : Func(NULL), Hash(Hash), TD(NULL) {}
+
+  AssertingVH<Function> Func;
+  unsigned Hash;
+  TargetData *TD;
 };
 
+const ComparableFunction ComparableFunction::EmptyKey = ComparableFunction(0);
+const ComparableFunction ComparableFunction::TombstoneKey =
+    ComparableFunction(1);
+
+} // anonymous namespace
+
+namespace llvm {
+  template <>
+  struct DenseMapInfo<ComparableFunction> {
+    static ComparableFunction getEmptyKey() {
+      return ComparableFunction::EmptyKey;
+    }
+    static ComparableFunction getTombstoneKey() {
+      return ComparableFunction::TombstoneKey;
+    }
+    static unsigned getHashValue(const ComparableFunction &CF) {
+      return CF.getHash();
+    }
+    static bool isEqual(const ComparableFunction &LHS,
+                        const ComparableFunction &RHS);
+  };
+}
+
+namespace {
+
 /// MergeFunctions finds functions which will generate identical machine code,
 /// by considering all pointer types to be equivalent. Once identified,
 /// MergeFunctions will fold them by replacing a call to one to a call to a
@@ -121,12 +151,12 @@
   bool runOnModule(Module &M);
 
 private:
-  typedef DenseSet<ComparableFunction *, MergeFunctionsEqualityInfo> FnSetType;
+  typedef DenseSet<ComparableFunction> FnSetType;
 
 
   /// Insert a ComparableFunction into the FnSet, or merge it away if it's
   /// equal to one that's already present.
-  bool Insert(FnSetType &FnSet, ComparableFunction *NewF);
+  bool Insert(FnSetType &FnSet, ComparableFunction &NewF);
 
   /// MergeTwoFunctions - Merge two equivalent functions. Upon completion, G
   /// may be deleted, or may be converted into a thunk. In either case, it
@@ -602,23 +632,23 @@
 
 // Insert - Insert a ComparableFunction into the FnSet, or merge it away if
 // equal to one that's already inserted.
-bool MergeFunctions::Insert(FnSetType &FnSet, ComparableFunction *NewF) {
+bool MergeFunctions::Insert(FnSetType &FnSet, ComparableFunction &NewF) {
   std::pair<FnSetType::iterator, bool> Result = FnSet.insert(NewF);
   if (Result.second)
     return false;
 
-  ComparableFunction *OldF = *Result.first;
-  assert(OldF && "Expected a hash collision");
+  const ComparableFunction &OldF = *Result.first;
 
   // Never thunk a strong function to a weak function.
-  assert(!OldF->Func->isWeakForLinker() || NewF->Func->isWeakForLinker());
+  assert(!OldF.getFunc()->isWeakForLinker() ||
+         NewF.getFunc()->isWeakForLinker());
 
-  DEBUG(dbgs() << "  " << OldF->Func->getName() << " == "
-               << NewF->Func->getName() << '\n');
+  DEBUG(dbgs() << "  " << OldF.getFunc()->getName() << " == "
+               << NewF.getFunc()->getName() << '\n');
 
-  Function *DeleteF = NewF->Func;
-  delete NewF;
-  MergeTwoFunctions(OldF->Func, DeleteF);
+  Function *DeleteF = NewF.getFunc();
+  NewF.release();
+  MergeTwoFunctions(OldF.getFunc(), DeleteF);
   return true;
 }
 
@@ -701,7 +731,7 @@
       Function *F = I++;
       if (!F->isDeclaration() && !F->hasAvailableExternallyLinkage() &&
           !F->isWeakForLinker() && !IsThunk(F)) {
-        ComparableFunction *CF = new ComparableFunction(F, TD);
+        ComparableFunction CF = ComparableFunction(F, TD);
         LocalChanged |= Insert(FnSet, CF);
       }
     }
@@ -714,24 +744,25 @@
       Function *F = I++;
       if (!F->isDeclaration() && !F->hasAvailableExternallyLinkage() &&
           F->isWeakForLinker() && !IsThunk(F)) {
-        ComparableFunction *CF = new ComparableFunction(F, TD);
+        ComparableFunction CF = ComparableFunction(F, TD);
         LocalChanged |= Insert(FnSet, CF);
       }
     }
-    DeleteContainerPointers(FnSet);
     Changed |= LocalChanged;
   } while (LocalChanged);
 
   return Changed;
 }
 
-bool MergeFunctionsEqualityInfo::isEqual(const ComparableFunction *LHS,
-                                         const ComparableFunction *RHS) {
-  if (LHS == RHS)
+bool DenseMapInfo<ComparableFunction>::isEqual(const ComparableFunction &LHS,
+                                               const ComparableFunction &RHS) {
+  if (LHS.getFunc() == RHS.getFunc() &&
+      LHS.getHash() == RHS.getHash())
     return true;
-  if (LHS == getEmptyKey() || LHS == getTombstoneKey() ||
-      RHS == getEmptyKey() || RHS == getTombstoneKey())
+  if (!LHS.getFunc() || !RHS.getFunc())
     return false;
-  assert(LHS->TD == RHS->TD && "Comparing functions for different targets");
-  return FunctionComparator(LHS->TD, LHS->Func, RHS->Func).Compare();
+  assert(LHS.getTD() == RHS.getTD() &&
+         "Comparing functions for different targets");
+  return FunctionComparator(LHS.getTD(),
+                            LHS.getFunc(), RHS.getFunc()).Compare();
 }





More information about the llvm-commits mailing list