[llvm] 8855fec - [OpenMPOpt] Use a pointer value type in map

Johannes Doerfert via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 20 21:29:04 PDT 2020


Author: Johannes Doerfert
Date: 2020-04-20T23:27:08-05:00
New Revision: 8855fec37e7cabdfbfd9645c069a272545ba04d3

URL: https://github.com/llvm/llvm-project/commit/8855fec37e7cabdfbfd9645c069a272545ba04d3
DIFF: https://github.com/llvm/llvm-project/commit/8855fec37e7cabdfbfd9645c069a272545ba04d3.diff

LOG: [OpenMPOpt] Use a pointer value type in map

The value type was a set before which can easily lead to excessive
memory usage and copying. We use a pointer to a vector instead now.

Added: 
    

Modified: 
    llvm/lib/Transforms/IPO/OpenMPOpt.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/IPO/OpenMPOpt.cpp b/llvm/lib/Transforms/IPO/OpenMPOpt.cpp
index 36e39f0d982a..eb976efa512f 100644
--- a/llvm/lib/Transforms/IPO/OpenMPOpt.cpp
+++ b/llvm/lib/Transforms/IPO/OpenMPOpt.cpp
@@ -63,6 +63,8 @@ struct OpenMPOpt {
 
   /// Generic information that describes a runtime function
   struct RuntimeFunctionInfo {
+    ~RuntimeFunctionInfo() { DeleteContainerSeconds(UsesMap); }
+
     /// The kind, as described by the RuntimeFunction enum.
     RuntimeFunction Kind;
 
@@ -82,7 +84,24 @@ struct OpenMPOpt {
     Function *Declaration = nullptr;
 
     /// Uses of this runtime function per function containing the use.
-    DenseMap<Function *, SmallPtrSet<Use *, 16>> UsesMap;
+    using UseVector = SmallVector<Use *, 16>;
+
+    /// Return the vector of uses in function \p F.
+    UseVector &getOrCreateUseVector(Function *F) {
+      UseVector *&UV = UsesMap[F];
+      if (!UV)
+        UV = new UseVector();
+      return *UV;
+    }
+
+    /// Return the vector of uses in function \p F or `nullptr` if there are
+    /// none.
+    const UseVector *getUseVector(Function &F) const {
+      return UsesMap.lookup(&F);
+    }
+
+    /// Return how many functions contain uses of this runtime function.
+    size_t getNumFunctionsWithUses() const { return UsesMap.size(); }
 
     /// Return the number of arguments (or the minimal number for variadic
     /// functions).
@@ -92,16 +111,31 @@ struct OpenMPOpt {
     /// true. The callback will be fed the function in which the use was
     /// encountered as second argument.
     void foreachUse(function_ref<bool(Use &, Function &)> CB) {
-      SmallVector<Use *, 8> ToBeDeleted;
+      SmallVector<unsigned, 8> ToBeDeleted;
       for (auto &It : UsesMap) {
         ToBeDeleted.clear();
-        for (Use *U : It.second)
+        unsigned Idx = 0;
+        UseVector &UV = *It.second;
+        for (Use *U : UV) {
           if (CB(*U, *It.first))
-            ToBeDeleted.push_back(U);
-        for (Use *U : ToBeDeleted)
-          It.second.erase(U);
+            ToBeDeleted.push_back(Idx);
+          ++Idx;
+        }
+
+        // Remove the to-be-deleted indices in reverse order as prior
+        // modifcations will not modify the smaller indices.
+        while (!ToBeDeleted.empty()) {
+          unsigned Idx = ToBeDeleted.pop_back_val();
+          UV[Idx] = UV.back();
+          UV.pop_back();
+        }
       }
     }
+
+  private:
+    /// Map from functions to all uses of this runtime function contained in
+    /// them.
+    DenseMap<Function *, UseVector *> UsesMap;
   };
 
   /// Run all OpenMP optimizations on the underlying SCC/ModuleSlice.
@@ -248,15 +282,11 @@ struct OpenMPOpt {
   /// \p ReplVal if given.
   bool deduplicateRuntimeCalls(Function &F, RuntimeFunctionInfo &RFI,
                                Value *ReplVal = nullptr) {
-    auto UsesIt = RFI.UsesMap.find(&F);
-    if (UsesIt == RFI.UsesMap.end())
+    auto *UV = RFI.getUseVector(F);
+    if (!UV || UV->size() + (ReplVal != nullptr) < 2)
       return false;
 
-    auto &Uses = UsesIt->getSecond();
-    if (Uses.size() + (ReplVal != nullptr) < 2)
-      return false;
-
-    LLVM_DEBUG(dbgs() << TAG << "Deduplicate " << Uses.size() << " uses of "
+    LLVM_DEBUG(dbgs() << TAG << "Deduplicate " << UV->size() << " uses of "
                       << RFI.Name
                       << (ReplVal ? " with an existing value\n" : "\n")
                       << "\n");
@@ -278,7 +308,7 @@ struct OpenMPOpt {
     };
 
     if (!ReplVal) {
-      for (Use *U : Uses)
+      for (Use *U : *UV)
         if (CallInst *CI = getCallIfRegularCall(*U, &RFI)) {
           if (!CanBeMoved(*CI))
             continue;
@@ -357,10 +387,11 @@ struct OpenMPOpt {
     // The argument users of __kmpc_global_thread_num calls are GTIds.
     RuntimeFunctionInfo &GlobThreadNumRFI =
         RFIs[OMPRTL___kmpc_global_thread_num];
-    for (auto &It : GlobThreadNumRFI.UsesMap)
-      for (Use *U : It.second)
-        if (CallInst *CI = getCallIfRegularCall(*U, &GlobThreadNumRFI))
-          AddUserArgs(*CI);
+    GlobThreadNumRFI.foreachUse([&](Use &U, Function &F) {
+      if (CallInst *CI = getCallIfRegularCall(U, &GlobThreadNumRFI))
+        AddUserArgs(*CI);
+      return false;
+    });
 
     // Transitively search for more arguments by looking at the users of the
     // ones we know already. During the search the GTIdArgs vector is extended
@@ -432,11 +463,11 @@ struct OpenMPOpt {
       for (Use &U : RFI.Declaration->uses()) {
         if (Instruction *UserI = dyn_cast<Instruction>(U.getUser())) {
           if (ModuleSlice.count(UserI->getFunction())) {
-            RFI.UsesMap[UserI->getFunction()].insert(&U);
+            RFI.getOrCreateUseVector(UserI->getFunction()).push_back(&U);
             ++NumUses;
           }
         } else {
-          RFI.UsesMap[nullptr].insert(&U);
+          RFI.getOrCreateUseVector(nullptr).push_back(&U);
           ++NumUses;
         }
       }
@@ -447,7 +478,7 @@ struct OpenMPOpt {
   {                                                                            \
     SmallVector<Type *, 8> ArgsTypes({__VA_ARGS__});                           \
     Function *F = M.getFunction(_Name);                                        \
-    if (declMatchesRTFTypes(F, _ReturnType , ArgsTypes)) {                     \
+    if (declMatchesRTFTypes(F, _ReturnType, ArgsTypes)) {                      \
       auto &RFI = RFIs[_Enum];                                                 \
       RFI.Kind = _Enum;                                                        \
       RFI.Name = _Name;                                                        \
@@ -459,10 +490,11 @@ struct OpenMPOpt {
       (void)NumUses;                                                           \
       LLVM_DEBUG({                                                             \
         dbgs() << TAG << RFI.Name << (RFI.Declaration ? "" : " not")           \
-              << " found\n";                                                   \
+               << " found\n";                                                  \
         if (RFI.Declaration)                                                   \
           dbgs() << TAG << "-> got " << NumUses << " uses in "                 \
-                << RFI.UsesMap.size() << " 
diff erent functions.\n";            \
+                 << RFI.getNumFunctionsWithUses()                              \
+                 << " 
diff erent functions.\n";                                 \
       });                                                                      \
     }                                                                          \
   }


        


More information about the llvm-commits mailing list