[clang] 0a5cfbf - [OpenMP] Use the align clause value from 'omp allocate' for globals

Mike Rice via cfe-commits cfe-commits at lists.llvm.org
Thu May 26 09:52:17 PDT 2022


Author: Mike Rice
Date: 2022-05-26T09:51:48-07:00
New Revision: 0a5cfbf7b2e82e7980b66428e88b4e28e814d7bb

URL: https://github.com/llvm/llvm-project/commit/0a5cfbf7b2e82e7980b66428e88b4e28e814d7bb
DIFF: https://github.com/llvm/llvm-project/commit/0a5cfbf7b2e82e7980b66428e88b4e28e814d7bb.diff

LOG: [OpenMP] Use the align clause value from 'omp allocate' for globals

Refactor the code that handles the align clause of 'omp allocate' so
it can be used with globals as well as local variables.

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

Added: 
    clang/test/OpenMP/align_clause_global_codegen.cpp

Modified: 
    clang/lib/CodeGen/CGDecl.cpp
    clang/lib/CodeGen/CGOpenMPRuntime.cpp
    clang/lib/CodeGen/CodeGenModule.cpp
    clang/lib/CodeGen/CodeGenModule.h

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index 0f16c7f50a003..a16551e83f93b 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -2694,3 +2694,22 @@ void CodeGenModule::EmitOMPAllocateDecl(const OMPAllocateDecl *D) {
     DummyGV->eraseFromParent();
   }
 }
+
+llvm::Optional<CharUnits>
+CodeGenModule::getOMPAllocateAlignment(const VarDecl *VD) {
+  if (const auto *AA = VD->getAttr<OMPAllocateDeclAttr>()) {
+    if (Expr *Alignment = AA->getAlignment()) {
+      unsigned UserAlign =
+          Alignment->EvaluateKnownConstInt(getContext()).getExtValue();
+      CharUnits NaturalAlign =
+          getNaturalTypeAlignment(VD->getType().getNonReferenceType());
+
+      // OpenMP5.1 pg 185 lines 7-10
+      //   Each item in the align modifier list must be aligned to the maximum
+      //   of the specified alignment and the type's natural alignment.
+      return CharUnits::fromQuantity(
+          std::max<unsigned>(UserAlign, NaturalAlign.getQuantity()));
+    }
+  }
+  return llvm::None;
+}

diff  --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index 89e26b10dfae5..605d4fe76bc96 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -12185,25 +12185,15 @@ static llvm::Value *getAllocatorVal(CodeGenFunction &CGF,
   return AllocVal;
 }
 
-/// Given the allocate directive list item type and align clause value,
-/// return appropriate alignment.
-static llvm::Value *getAlignmentValue(CodeGenFunction &CGF, QualType ListItemTy,
-                                      const Expr *Alignment) {
-  if (!Alignment)
-    return nullptr;
+/// Return the alignment from an allocate directive if present.
+static llvm::Value *getAlignmentValue(CodeGenModule &CGM, const VarDecl *VD) {
+  llvm::Optional<CharUnits> AllocateAlignment = CGM.getOMPAllocateAlignment(VD);
 
-  unsigned UserAlign =
-      Alignment->EvaluateKnownConstInt(CGF.getContext()).getExtValue();
-  CharUnits NaturalAlign = CGF.CGM.getNaturalTypeAlignment(ListItemTy);
+  if (!AllocateAlignment)
+    return nullptr;
 
-  // OpenMP5.1 pg 185 lines 7-10
-  //   Each item in the align modifier list must be aligned to the maximum
-  //   of the specified alignment and the type's natural alignment.
-  //
-  // If no alignment specified then use the natural alignment.
-  return llvm::ConstantInt::get(
-      CGF.CGM.SizeTy,
-      std::max<unsigned>(UserAlign, NaturalAlign.getQuantity()));
+  return llvm::ConstantInt::get(CGM.SizeTy,
+                                AllocateAlignment.getValue().getQuantity());
 }
 
 Address CGOpenMPRuntime::getAddressOfLocalVariable(CodeGenFunction &CGF,
@@ -12244,8 +12234,7 @@ Address CGOpenMPRuntime::getAddressOfLocalVariable(CodeGenFunction &CGF,
     const auto *AA = CVD->getAttr<OMPAllocateDeclAttr>();
     const Expr *Allocator = AA->getAllocator();
     llvm::Value *AllocVal = getAllocatorVal(CGF, Allocator);
-    llvm::Value *Alignment = getAlignmentValue(
-        CGF, VD->getType().getNonReferenceType(), AA->getAlignment());
+    llvm::Value *Alignment = getAlignmentValue(CGM, CVD);
     SmallVector<llvm::Value *, 4> Args;
     Args.push_back(ThreadID);
     if (Alignment)

diff  --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index a035e5ddd9e6d..b4ae266f89881 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -4738,7 +4738,12 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
       GV->setConstant(true);
   }
 
-  GV->setAlignment(getContext().getDeclAlign(D).getAsAlign());
+  CharUnits AlignVal = getContext().getDeclAlign(D);
+  // Check for alignment specifed in an 'omp allocate' directive.
+  if (llvm::Optional<CharUnits> AlignValFromAllocate =
+          getOMPAllocateAlignment(D))
+    AlignVal = AlignValFromAllocate.getValue();
+  GV->setAlignment(AlignVal.getAsAlign());
 
   // On Darwin, unlike other Itanium C++ ABI platforms, the thread-wrapper
   // function is only defined alongside the variable, not also alongside

diff  --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index a5ec4c8f988d6..0ac476dd6dbcc 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -1365,6 +1365,9 @@ class CodeGenModule : public CodeGenTypeCache {
   /// \param D The allocate declaration
   void EmitOMPAllocateDecl(const OMPAllocateDecl *D);
 
+  /// Return the alignment specified in an allocate directive, if present.
+  llvm::Optional<CharUnits> getOMPAllocateAlignment(const VarDecl *VD);
+
   /// Returns whether the given record has hidden LTO visibility and therefore
   /// may participate in (single-module) CFI and whole-program vtable
   /// optimization.

diff  --git a/clang/test/OpenMP/align_clause_global_codegen.cpp b/clang/test/OpenMP/align_clause_global_codegen.cpp
new file mode 100644
index 0000000000000..3be8e87cf87aa
--- /dev/null
+++ b/clang/test/OpenMP/align_clause_global_codegen.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -emit-llvm -o - -fopenmp \
+// RUN:  -triple i386-unknown-unknown -fopenmp-version=51 %s \
+// RUN:  | FileCheck %s --check-prefixes=CHECK,CHECK-32
+
+// RUN: %clang_cc1 -emit-llvm -o - -fopenmp \
+// RUN:  -triple x86_64-unknown-linux-gnu -fopenmp-version=51 %s \
+// RUN:  | FileCheck %s --check-prefixes=CHECK,CHECK-64
+
+typedef enum omp_allocator_handle_t {
+  omp_null_allocator = 0,
+  omp_default_mem_alloc = 1,
+  omp_large_cap_mem_alloc = 2,
+  omp_const_mem_alloc = 3,
+  omp_high_bw_mem_alloc = 4,
+  omp_low_lat_mem_alloc = 5,
+  omp_cgroup_mem_alloc = 6,
+  omp_pteam_mem_alloc = 7,
+  omp_thread_mem_alloc = 8,
+  KMP_ALLOCATOR_MAX_HANDLE = __UINTPTR_MAX__
+} omp_allocator_handle_t;
+
+//
+// Should allow larger alignment.
+//
+
+// CHECK: @foo_global1 = global float 0.000000e+00, align 16
+float foo_global1;
+#pragma omp allocate(foo_global1) align(16)
+
+// CHECK: @foo_global2 = global float 0.000000e+00, align 16
+float foo_global2;
+#pragma omp allocate(foo_global2) allocator(omp_default_mem_alloc) align(16)
+
+// CHECK: @foo_global3 = global float 0.000000e+00, align 16
+float foo_global3;
+#pragma omp allocate(foo_global3) allocator(omp_large_cap_mem_alloc) align(16)
+
+// CHECK: @foop_global1 = global ptr null, align 16
+int *foop_global1;
+#pragma omp allocate(foop_global1) align(16)
+
+//
+// Should use natural alignment when alignment specified is too small.
+//
+
+// CHECK: @foo_global4 = global float 0.000000e+00, align 4
+float foo_global4;
+#pragma omp allocate(foo_global4) align(2)
+
+// CHECK: @foo_global5 = global float 0.000000e+00, align 4
+float foo_global5;
+#pragma omp allocate(foo_global5) allocator(omp_default_mem_alloc) align(2)
+
+// CHECK: @foo_global6 = global float 0.000000e+00, align 4
+float foo_global6;
+#pragma omp allocate(foo_global6) allocator(omp_large_cap_mem_alloc) align(2)
+
+// CHECK-32: @foop_global2 = global ptr null, align 4
+// CHECK-64: @foop_global2 = global ptr null, align 8
+int *foop_global2;
+#pragma omp allocate(foop_global2) align(2)


        


More information about the cfe-commits mailing list