[OpenMP] Introduce RAII to protect certain RTL calls from DCE
authorJoseph Huber <jhuber6@vols.utk.edu>
Fri, 23 Jul 2021 20:32:47 +0000 (16:32 -0400)
committerHuber, Joseph <huberjn@ornl.gov>
Sun, 25 Jul 2021 18:15:47 +0000 (14:15 -0400)
This patch introduces a new RAII struct that will temporarily make an OpenMP
RTL function have external linkage. This is done before the attributor is
invoked to prevent it from incorrectly removing some function definitions that
we will use later. For example, if we determine all calls to one function are
dead, because it has internal linkage it can safely be removed. Later when we
try to get an instance to that function to modify the source using
`getOrCreateRuntimeFunction` we will then get an empty declaration for that
function that won't be defined anywhere. This patch prevents this from
occurring.

Reviewed By: jdoerfert

Differential Revision: https://reviews.llvm.org/D106707

llvm/lib/Transforms/IPO/OpenMPOpt.cpp

index 1031a55..3d03fc5 100644 (file)
@@ -1760,6 +1760,32 @@ private:
           [&]() { return RemarkCB(RemarkKind(DEBUG_TYPE, RemarkName, F)); });
   }
 
+  /// RAII struct to temporarily change an RTL function's linkage to external.
+  /// This prevents it from being mistakenly removed by other optimizations.
+  struct ExternalizationRAII {
+    ExternalizationRAII(OMPInformationCache &OMPInfoCache,
+                        RuntimeFunction RFKind)
+        : OMPInfoCache(OMPInfoCache),
+          Declaration(OMPInfoCache.RFIs[RFKind].Declaration) {
+      if (!Declaration)
+        return;
+
+      LinkageType = Declaration->getLinkage();
+      Declaration->setLinkage(GlobalValue::ExternalLinkage);
+    }
+
+    ~ExternalizationRAII() {
+      if (!Declaration)
+        return;
+
+      Declaration->setLinkage(LinkageType);
+    }
+
+    OMPInformationCache &OMPInfoCache;
+    Function *Declaration;
+    GlobalValue::LinkageTypes LinkageType;
+  };
+
   /// The underlying module.
   Module &M;
 
@@ -1784,6 +1810,14 @@ private:
     if (SCC.empty())
       return false;
 
+    // Temporarily make these function have external linkage so the Attributor
+    // doesn't remove them when we try to look them up later.
+    ExternalizationRAII Parallel(OMPInfoCache, OMPRTL___kmpc_kernel_parallel);
+    ExternalizationRAII EndParallel(OMPInfoCache,
+                                    OMPRTL___kmpc_kernel_end_parallel);
+    ExternalizationRAII BarrierSPMD(OMPInfoCache,
+                                    OMPRTL___kmpc_barrier_simple_spmd);
+
     registerAAs(IsModulePass);
 
     ChangeStatus Changed = A.run();