[PATCH] D84689: [OpenMPOpt][OldPM!] Most SCC's are uninteresting, don't waste time on them

Roman Lebedev via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 27 11:55:37 PDT 2020


lebedev.ri created this revision.
lebedev.ri added a reviewer: jdoerfert.
lebedev.ri added a project: LLVM.
Herald added subscribers: sstefan1, guansong, hiraditya, yaxunl.

This seems obvious in hindsight, but the result is surprising.
I've measured compile-time of `-openmpopt` pass standalone
on RawSpeed unity build, and while there are some OpenMP stuff,
most is not. But nonetheless the pass does a lot of costly
preparations before ever trying to look for OpenMP stuff in SCC.

Numbers (n=25): 0.093476s  ->  0.00642s, an -93.13% improvement, or ~15x

Sadly, right now this is OldPM only.
If the general approach is deemed worthy, NewPM can also be fixed,
but as the comment says, LazyCallGraph doesn't currently contain
declarations that are called, so this doesn't work out-of-the-box.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D84689

Files:
  llvm/include/llvm/Transforms/IPO/OpenMPOpt.h
  llvm/lib/Transforms/IPO/OpenMPOpt.cpp


Index: llvm/lib/Transforms/IPO/OpenMPOpt.cpp
===================================================================
--- llvm/lib/Transforms/IPO/OpenMPOpt.cpp
+++ llvm/lib/Transforms/IPO/OpenMPOpt.cpp
@@ -1342,6 +1342,10 @@
   for (LazyCallGraph::Node &N : C)
     SCC.push_back(&N.getFunction());
 
+  // FIXME: skip SCC's that don't contain calls to OpenMP functions.
+  // The problem is that those OpenMP functions are declarations,
+  // and LazyCallGraph currently does not track them.
+
   if (SCC.empty())
     return PreservedAnalyses::all();
 
@@ -1401,12 +1405,25 @@
       return false;
 
     SmallVector<Function *, 16> SCC;
-    for (CallGraphNode *CGN : CGSCC)
-      if (Function *Fn = CGN->getFunction())
-        if (!Fn->isDeclaration())
-          SCC.push_back(Fn);
+    bool InterestgingSCC = !OMPInModule.getKernels().empty();
+    for (CallGraphNode *CGN : CGSCC) {
+      Function *Fn = CGN->getFunction();
+      if (!Fn || Fn->isDeclaration())
+        continue;
+      SCC.push_back(Fn);
 
-    if (SCC.empty())
+      // Do we already know that the SCC contains kernels,
+      // or that OpenMP functions are called from this SCC?
+      if (InterestgingSCC)
+        continue;
+      // If not, let's check that.
+      InterestgingSCC |= any_of(*CGN, [&](CallGraphNode::CallRecord Callee) {
+        return OMPInModule.isOMPReferencedFunction(
+            Callee.second->getFunction());
+      });
+    }
+
+    if (!InterestgingSCC || SCC.empty())
       return false;
 
     CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph();
@@ -1472,9 +1489,9 @@
   // issues an error. Work around it..
   do {
 #define OMP_RTL(_Enum, _Name, ...)                                             \
-  if (M.getFunction(_Name)) {                                                  \
+  if (Function *F = M.getFunction(_Name)) {                                    \
+    OMPInModule.OMPFuncs.insert(F);                                            \
     OMPInModule = true;                                                        \
-    break;                                                                     \
   }
 #include "llvm/Frontend/OpenMP/OMPKinds.def"
   } while (false);
Index: llvm/include/llvm/Transforms/IPO/OpenMPOpt.h
===================================================================
--- llvm/include/llvm/Transforms/IPO/OpenMPOpt.h
+++ llvm/include/llvm/Transforms/IPO/OpenMPOpt.h
@@ -33,6 +33,12 @@
   bool isKnown() { return Value != OpenMP::UNKNOWN; }
   operator bool() { return Value != OpenMP::NOT_FOUND; }
 
+  /// Is this function \p F an OpenMP function that is known ot be called
+  /// in the module?
+  bool isOMPReferencedFunction(Function *F) const {
+    return OMPFuncs.contains(F);
+  }
+
   /// Return the known kernels (=GPU entry points) in the module.
   SmallPtrSetImpl<Kernel> &getKernels() { return Kernels; }
 
@@ -42,6 +48,11 @@
 private:
   enum class OpenMP { FOUND, NOT_FOUND, UNKNOWN } Value = OpenMP::UNKNOWN;
 
+  friend bool containsOpenMP(Module &M, OpenMPInModule &OMPInModule);
+
+  /// Which OpenMP functions are called in this module?
+  SmallPtrSet<Function *, 32> OMPFuncs;
+
   /// Collection of known kernels (=GPU entry points) in the module.
   SmallPtrSet<Kernel, 8> Kernels;
 };


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D84689.281002.patch
Type: text/x-patch
Size: 3270 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200727/4014f481/attachment.bin>


More information about the llvm-commits mailing list