diff --git a/llvm/include/llvm/Transforms/IPO/OpenMPOpt.h b/llvm/include/llvm/Transforms/IPO/OpenMPOpt.h --- a/llvm/include/llvm/Transforms/IPO/OpenMPOpt.h +++ b/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 &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 OMPFuncs; + /// Collection of known kernels (=GPU entry points) in the module. SmallPtrSet Kernels; }; diff --git a/llvm/lib/Transforms/IPO/OpenMPOpt.cpp b/llvm/lib/Transforms/IPO/OpenMPOpt.cpp --- a/llvm/lib/Transforms/IPO/OpenMPOpt.cpp +++ b/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 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().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);