From 3f465c095b22400c1d08295b8890477fa4e6ffda Mon Sep 17 00:00:00 2001 From: Samuel Antao Date: Sat, 6 Feb 2016 02:12:34 +0000 Subject: [PATCH] [OpenMP] Reorganize code to allow specialized code generation for different devices. Summary: Different devices may in some cases require different code generation schemes in order to implement OpenMP. This is required not only for performance reasons, but also because it may not be possible to have the current (default) implementation working for these devices. E.g. GPU's cannot implement the same scheme a target such as powerpc or x86b would use, in the sense that it does not have the ability to fork threads, instead all the threads are always executing and need to be managed by the implementation. This patch proposes a reorganization of the code in the OpenMP code generation to pave the way to have specialized implementation of OpenMP support. More than a "real" patch this is more a request for comments in order to understand if what is proposed is acceptable or if there are better/easier ways to do it. In this patch part of the common OpenMP codegen infrastructure is moved to a new file under a new namespace (CGOpenMPCommon) so it can be shared between the default implementation and the specialized one. When CGOpenMPRuntime is created, an attempt to select a specialized implementation is done. In the patch a specialization for nvptx targets is done which currently checks if the target is an OpenMP device and trap if it is not. Let me know comments suggestions you may have. Reviewers: hfinkel, carlo.bertolli, arpith-jacob, kkwli0, ABataev Subscribers: Hahnfeld, cfe-commits, fraggamuffin, caomhin, jholewinski Differential Revision: http://reviews.llvm.org/D16784 llvm-svn: 259977 --- .../clang/Basic/DiagnosticDriverKinds.td | 4 ++- clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp | 21 +++++++++++++ clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.h | 31 +++++++++++++++++++ clang/lib/CodeGen/CMakeLists.txt | 1 + clang/lib/CodeGen/CodeGenModule.cpp | 16 +++++++++- clang/lib/Frontend/CompilerInvocation.cpp | 19 +++++++++++- clang/test/OpenMP/target_messages.cpp | 3 ++ 7 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp create mode 100644 clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.h diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index e84d80b7f021..a89ad20956e8 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -132,7 +132,9 @@ def err_drv_no_neon_modifier : Error<"[no]neon is not accepted as modifier, plea def err_drv_invalid_omp_target : Error<"OpenMP target is invalid: '%0'">; def err_drv_omp_host_ir_file_not_found : Error< "The provided host compiler IR file '%0' is required to generate code for OpenMP target regions but cannot be found.">; - +def err_drv_omp_host_target_not_supported : Error< + "The target '%0' is not a supported OpenMP host target.">; + def warn_O4_is_O3 : Warning<"-O4 is equivalent to -O3">, InGroup; def warn_drv_lto_libpath : Warning<"libLTO.dylib relative to clang installed dir not found; using 'ld' default search path instead">, InGroup; diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp new file mode 100644 index 000000000000..314a4b54494f --- /dev/null +++ b/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp @@ -0,0 +1,21 @@ +//===---- CGOpenMPRuntimeNVPTX.cpp - Interface to OpenMP NVPTX Runtimes ---===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This provides a class for OpenMP runtime code generation specialized to NVPTX +// targets. +// +//===----------------------------------------------------------------------===// + +#include "CGOpenMPRuntimeNVPTX.h" + +using namespace clang; +using namespace CodeGen; + +CGOpenMPRuntimeNVPTX::CGOpenMPRuntimeNVPTX(CodeGenModule &CGM) + : CGOpenMPRuntime(CGM) {} diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.h b/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.h new file mode 100644 index 000000000000..60bb9acbc7e9 --- /dev/null +++ b/clang/lib/CodeGen/CGOpenMPRuntimeNVPTX.h @@ -0,0 +1,31 @@ +//===----- CGOpenMPRuntimeNVPTX.h - Interface to OpenMP NVPTX Runtimes ----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This provides a class for OpenMP runtime code generation specialized to NVPTX +// targets. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_CODEGEN_CGOPENMPRUNTIMENVPTX_H +#define LLVM_CLANG_LIB_CODEGEN_CGOPENMPRUNTIMENVPTX_H + +#include "CGOpenMPRuntime.h" + +namespace clang { +namespace CodeGen { + +class CGOpenMPRuntimeNVPTX : public CGOpenMPRuntime { +public: + explicit CGOpenMPRuntimeNVPTX(CodeGenModule &CGM); +}; + +} // CodeGen namespace. +} // clang namespace. + +#endif // LLVM_CLANG_LIB_CODEGEN_CGOPENMPRUNTIMENVPTX_H diff --git a/clang/lib/CodeGen/CMakeLists.txt b/clang/lib/CodeGen/CMakeLists.txt index ed028ad4d219..353f60163172 100644 --- a/clang/lib/CodeGen/CMakeLists.txt +++ b/clang/lib/CodeGen/CMakeLists.txt @@ -57,6 +57,7 @@ add_clang_library(clangCodeGen CGObjCRuntime.cpp CGOpenCLRuntime.cpp CGOpenMPRuntime.cpp + CGOpenMPRuntimeNVPTX.cpp CGRecordLayoutBuilder.cpp CGStmt.cpp CGStmtOpenMP.cpp diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index a30e62499fad..aabcc524c931 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -20,6 +20,7 @@ #include "CGObjCRuntime.h" #include "CGOpenCLRuntime.h" #include "CGOpenMPRuntime.h" +#include "CGOpenMPRuntimeNVPTX.h" #include "CodeGenFunction.h" #include "CodeGenPGO.h" #include "CodeGenTBAA.h" @@ -200,7 +201,20 @@ void CodeGenModule::createOpenCLRuntime() { } void CodeGenModule::createOpenMPRuntime() { - OpenMPRuntime = new CGOpenMPRuntime(*this); + // Select a specialized code generation class based on the target, if any. + // If it does not exist use the default implementation. + switch (getTarget().getTriple().getArch()) { + + case llvm::Triple::nvptx: + case llvm::Triple::nvptx64: + assert(getLangOpts().OpenMPIsDevice && + "OpenMP NVPTX is only prepared to deal with device code."); + OpenMPRuntime = new CGOpenMPRuntimeNVPTX(*this); + break; + default: + OpenMPRuntime = new CGOpenMPRuntime(*this); + break; + } } void CodeGenModule::createCUDARuntime() { diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 2403385ca4a6..2b191ca8dc3b 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1446,6 +1446,7 @@ static Visibility parseVisibility(Arg *arg, ArgList &args, } static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, + const TargetOptions &TargetOpts, DiagnosticsEngine &Diags) { // FIXME: Cleanup per-file based stuff. LangStandard::Kind LangStd = LangStandard::lang_unspecified; @@ -1841,6 +1842,22 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.OpenMPIsDevice = Opts.OpenMP && Args.hasArg(options::OPT_fopenmp_is_device); + // Provide diagnostic when a given target is not expected to be an OpenMP + // device or host. + if (Opts.OpenMP && !Opts.OpenMPIsDevice) { + llvm::Triple T(TargetOpts.Triple); + switch (T.getArch()) { + default: + break; + // Add unsupported host targets here: + case llvm::Triple::nvptx: + case llvm::Triple::nvptx64: + Diags.Report(clang::diag::err_drv_omp_host_target_not_supported) + << TargetOpts.Triple; + break; + } + } + // Get the OpenMP target triples if any. if (Arg *A = Args.getLastArg(options::OPT_omptargets_EQ)) { @@ -2107,7 +2124,7 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, Diags, Res.getLangOpts()->Sanitize); } else { // Other LangOpts are only initialzed when the input is not AST or LLVM IR. - ParseLangArgs(*Res.getLangOpts(), Args, DashX, Diags); + ParseLangArgs(*Res.getLangOpts(), Args, DashX, Res.getTargetOpts(), Diags); if (Res.getFrontendOpts().ProgramAction == frontend::RewriteObjC) Res.getLangOpts()->ObjCExceptions = 1; } diff --git a/clang/test/OpenMP/target_messages.cpp b/clang/test/OpenMP/target_messages.cpp index 361da5f3819f..6e697416a814 100644 --- a/clang/test/OpenMP/target_messages.cpp +++ b/clang/test/OpenMP/target_messages.cpp @@ -1,6 +1,9 @@ // RUN: %clang_cc1 -verify -fopenmp -std=c++11 -o - %s // RUN: not %clang_cc1 -fopenmp -std=c++11 -omptargets=aaa-bbb-ccc-ddd -o - %s 2>&1 | FileCheck %s // CHECK: error: OpenMP target is invalid: 'aaa-bbb-ccc-ddd' +// RUN: not %clang_cc1 -fopenmp -std=c++11 -triple nvptx64-nvidia-cuda -o - %s 2>&1 | FileCheck --check-prefix CHECK-UNSUPPORTED-HOST-TARGET %s +// RUN: not %clang_cc1 -fopenmp -std=c++11 -triple nvptx-nvidia-cuda -o - %s 2>&1 | FileCheck --check-prefix CHECK-UNSUPPORTED-HOST-TARGET %s +// CHECK-UNSUPPORTED-HOST-TARGET: error: The target '{{nvptx64-nvidia-cuda|nvptx-nvidia-cuda}}' is not a supported OpenMP host target. void foo() { }