106f32e7eSjoerg //===---- CGOpenMPRuntimeNVPTX.cpp - Interface to OpenMP NVPTX Runtimes ---===//
206f32e7eSjoerg //
306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information.
506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606f32e7eSjoerg //
706f32e7eSjoerg //===----------------------------------------------------------------------===//
806f32e7eSjoerg //
906f32e7eSjoerg // This provides a class for OpenMP runtime code generation specialized to NVPTX
10*13fbcb42Sjoerg // targets from generalized CGOpenMPRuntimeGPU class.
1106f32e7eSjoerg //
1206f32e7eSjoerg //===----------------------------------------------------------------------===//
1306f32e7eSjoerg 
1406f32e7eSjoerg #include "CGOpenMPRuntimeNVPTX.h"
15*13fbcb42Sjoerg #include "CGOpenMPRuntimeGPU.h"
1606f32e7eSjoerg #include "CodeGenFunction.h"
17*13fbcb42Sjoerg #include "clang/AST/Attr.h"
1806f32e7eSjoerg #include "clang/AST/DeclOpenMP.h"
1906f32e7eSjoerg #include "clang/AST/StmtOpenMP.h"
2006f32e7eSjoerg #include "clang/AST/StmtVisitor.h"
2106f32e7eSjoerg #include "clang/Basic/Cuda.h"
2206f32e7eSjoerg #include "llvm/ADT/SmallPtrSet.h"
23*13fbcb42Sjoerg #include "llvm/IR/IntrinsicsNVPTX.h"
2406f32e7eSjoerg 
2506f32e7eSjoerg using namespace clang;
2606f32e7eSjoerg using namespace CodeGen;
27*13fbcb42Sjoerg using namespace llvm::omp;
2806f32e7eSjoerg 
CGOpenMPRuntimeNVPTX(CodeGenModule & CGM)29*13fbcb42Sjoerg CGOpenMPRuntimeNVPTX::CGOpenMPRuntimeNVPTX(CodeGenModule &CGM)
30*13fbcb42Sjoerg     : CGOpenMPRuntimeGPU(CGM) {
31*13fbcb42Sjoerg   if (!CGM.getLangOpts().OpenMPIsDevice)
32*13fbcb42Sjoerg     llvm_unreachable("OpenMP NVPTX can only handle device code.");
3306f32e7eSjoerg }
3406f32e7eSjoerg 
getGPUWarpSize(CodeGenFunction & CGF)35*13fbcb42Sjoerg llvm::Value *CGOpenMPRuntimeNVPTX::getGPUWarpSize(CodeGenFunction &CGF) {
3606f32e7eSjoerg   return CGF.EmitRuntimeCall(
3706f32e7eSjoerg       llvm::Intrinsic::getDeclaration(
3806f32e7eSjoerg           &CGF.CGM.getModule(), llvm::Intrinsic::nvvm_read_ptx_sreg_warpsize),
3906f32e7eSjoerg       "nvptx_warp_size");
4006f32e7eSjoerg }
4106f32e7eSjoerg 
getGPUThreadID(CodeGenFunction & CGF)42*13fbcb42Sjoerg llvm::Value *CGOpenMPRuntimeNVPTX::getGPUThreadID(CodeGenFunction &CGF) {
4306f32e7eSjoerg   CGBuilderTy &Bld = CGF.Builder;
44*13fbcb42Sjoerg   llvm::Function *F;
45*13fbcb42Sjoerg   F = llvm::Intrinsic::getDeclaration(
46*13fbcb42Sjoerg       &CGF.CGM.getModule(), llvm::Intrinsic::nvvm_read_ptx_sreg_tid_x);
47*13fbcb42Sjoerg   return Bld.CreateCall(F, llvm::None, "nvptx_tid");
4806f32e7eSjoerg }
4906f32e7eSjoerg 
getGPUNumThreads(CodeGenFunction & CGF)50*13fbcb42Sjoerg llvm::Value *CGOpenMPRuntimeNVPTX::getGPUNumThreads(CodeGenFunction &CGF) {
5106f32e7eSjoerg   CGBuilderTy &Bld = CGF.Builder;
52*13fbcb42Sjoerg   llvm::Function *F;
53*13fbcb42Sjoerg   F = llvm::Intrinsic::getDeclaration(
54*13fbcb42Sjoerg       &CGF.CGM.getModule(), llvm::Intrinsic::nvvm_read_ptx_sreg_ntid_x);
55*13fbcb42Sjoerg   return Bld.CreateCall(F, llvm::None, "nvptx_num_threads");
5606f32e7eSjoerg }
57