forked from OSchip/llvm-project
[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
This commit is contained in:
parent
aada85c5f7
commit
3f465c095b
|
@ -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<Deprecated>;
|
||||
def warn_drv_lto_libpath : Warning<"libLTO.dylib relative to clang installed dir not found; using 'ld' default search path instead">,
|
||||
InGroup<LibLTO>;
|
||||
|
|
|
@ -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) {}
|
|
@ -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
|
|
@ -57,6 +57,7 @@ add_clang_library(clangCodeGen
|
|||
CGObjCRuntime.cpp
|
||||
CGOpenCLRuntime.cpp
|
||||
CGOpenMPRuntime.cpp
|
||||
CGOpenMPRuntimeNVPTX.cpp
|
||||
CGRecordLayoutBuilder.cpp
|
||||
CGStmt.cpp
|
||||
CGStmtOpenMP.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() {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue