summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGOpenMPRuntime.cpp
diff options
context:
space:
mode:
authorGheorghe-Teodor Bercea <gheorghe-teod.bercea@ibm.com>2019-05-21 19:42:01 +0000
committerGheorghe-Teodor Bercea <gheorghe-teod.bercea@ibm.com>2019-05-21 19:42:01 +0000
commit66cdbb47d2f83c41f774d3063bb0112b75d86277 (patch)
treeee9054f835a3ec37156e581ec09f97fb9885f28e /clang/lib/CodeGen/CGOpenMPRuntime.cpp
parent32591ca4e29db3128036fb33ad5cc8ccde67aeb3 (diff)
downloadbcm5719-llvm-66cdbb47d2f83c41f774d3063bb0112b75d86277.tar.gz
bcm5719-llvm-66cdbb47d2f83c41f774d3063bb0112b75d86277.zip
[OpenMP] Add support for registering requires directives with the runtime
Summary: This patch adds support for the registration of the requires directives with the runtime. Each requires directive clause will enable a particular flag to be set. The set of flags is passed to the runtime to be checked for compatibility with other such flags coming from other object files. The registration function is called whenever OpenMP is present even if a requires directive is not present. This helps detect cases in which requires directives are used inconsistently. Reviewers: ABataev, AlexEichenberger, caomhin Reviewed By: ABataev, AlexEichenberger Subscribers: jholewinski, guansong, jfb, jdoerfert, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D60568 llvm-svn: 361298
Diffstat (limited to 'clang/lib/CodeGen/CGOpenMPRuntime.cpp')
-rw-r--r--clang/lib/CodeGen/CGOpenMPRuntime.cpp90
1 files changed, 89 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index eb21bbde8d9..0897b4765e2 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -457,6 +457,26 @@ enum OpenMPLocationFlags : unsigned {
LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/OMP_IDENT_WORK_DISTRIBUTE)
};
+namespace {
+LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
+/// Values for bit flags for marking which requires clauses have been used.
+enum OpenMPOffloadingRequiresDirFlags : int64_t {
+ /// flag undefined.
+ OMP_REQ_UNDEFINED = 0x000,
+ /// no requires clause present.
+ OMP_REQ_NONE = 0x001,
+ /// reverse_offload clause.
+ OMP_REQ_REVERSE_OFFLOAD = 0x002,
+ /// unified_address clause.
+ OMP_REQ_UNIFIED_ADDRESS = 0x004,
+ /// unified_shared_memory clause.
+ OMP_REQ_UNIFIED_SHARED_MEMORY = 0x008,
+ /// dynamic_allocators clause.
+ OMP_REQ_DYNAMIC_ALLOCATORS = 0x010,
+ LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/OMP_REQ_DYNAMIC_ALLOCATORS)
+};
+} // anonymous namespace
+
/// Describes ident structure that describes a source location.
/// All descriptions are taken from
/// https://github.com/llvm/llvm-project/blob/master/openmp/runtime/src/kmp.h
@@ -694,6 +714,8 @@ enum OpenMPRTLFunction {
// *host_ptr, int32_t arg_num, void** args_base, void **args, size_t
// *arg_sizes, int64_t *arg_types, int32_t num_teams, int32_t thread_limit);
OMPRTL__tgt_target_teams_nowait,
+ // Call to void __tgt_register_requires(int64_t flags);
+ OMPRTL__tgt_register_requires,
// Call to void __tgt_register_lib(__tgt_bin_desc *desc);
OMPRTL__tgt_register_lib,
// Call to void __tgt_unregister_lib(__tgt_bin_desc *desc);
@@ -2296,6 +2318,14 @@ llvm::FunctionCallee CGOpenMPRuntime::createRuntimeFunction(unsigned Function) {
RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_teams_nowait");
break;
}
+ case OMPRTL__tgt_register_requires: {
+ // Build void __tgt_register_requires(int64_t flags);
+ llvm::Type *TypeParams[] = {CGM.Int64Ty};
+ auto *FnTy =
+ llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
+ RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_register_requires");
+ break;
+ }
case OMPRTL__tgt_register_lib: {
// Build void __tgt_register_lib(__tgt_bin_desc *desc);
QualType ParamTy =
@@ -6405,6 +6435,7 @@ void CGOpenMPRuntime::emitTargetOutlinedFunction(
llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID,
bool IsOffloadEntry, const RegionCodeGenTy &CodeGen) {
assert(!ParentName.empty() && "Invalid target region parent name!");
+ HasEmittedTargetRegion = true;
emitTargetOutlinedFunctionHelper(D, ParentName, OutlinedFn, OutlinedFnID,
IsOffloadEntry, CodeGen);
}
@@ -8225,7 +8256,7 @@ public:
MapValuesArrayTy &Sizes,
MapFlagsArrayTy &Types) const {
// Map other list items in the map clause which are not captured variables
- // but "declare target link" global variables.,
+ // but "declare target link" global variables.
for (const auto *C : this->CurDir.getClausesOfKind<OMPMapClause>()) {
for (const auto &L : C->component_lists()) {
if (!L.first)
@@ -9186,6 +9217,16 @@ void CGOpenMPRuntime::adjustTargetSpecificDataForLambdas(
" Expected target-based directive.");
}
+void CGOpenMPRuntime::checkArchForUnifiedAddressing(
+ const OMPRequiresDecl *D) {
+ for (const OMPClause *Clause : D->clauselists()) {
+ if (Clause->getClauseKind() == OMPC_unified_shared_memory) {
+ HasRequiresUnifiedSharedMemory = true;
+ break;
+ }
+ }
+}
+
bool CGOpenMPRuntime::hasAllocateAttributeForGlobalVar(const VarDecl *VD,
LangAS &AS) {
if (!VD || !VD->hasAttr<OMPAllocateDeclAttr>())
@@ -9244,6 +9285,47 @@ bool CGOpenMPRuntime::markAsGlobalTarget(GlobalDecl GD) {
return !AlreadyEmittedTargetFunctions.insert(Name).second;
}
+llvm::Function *CGOpenMPRuntime::emitRequiresDirectiveRegFun() {
+ // If we don't have entries or if we are emitting code for the device, we
+ // don't need to do anything.
+ if (CGM.getLangOpts().OMPTargetTriples.empty() ||
+ CGM.getLangOpts().OpenMPSimd || CGM.getLangOpts().OpenMPIsDevice ||
+ (OffloadEntriesInfoManager.empty() &&
+ !HasEmittedDeclareTargetRegion &&
+ !HasEmittedTargetRegion))
+ return nullptr;
+
+ // Create and register the function that handles the requires directives.
+ ASTContext &C = CGM.getContext();
+
+ llvm::Function *RequiresRegFn;
+ {
+ CodeGenFunction CGF(CGM);
+ const auto &FI = CGM.getTypes().arrangeNullaryFunction();
+ llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
+ std::string ReqName = getName({"omp_offloading", "requires_reg"});
+ RequiresRegFn = CGM.CreateGlobalInitOrDestructFunction(FTy, ReqName, FI);
+ CGF.StartFunction(GlobalDecl(), C.VoidTy, RequiresRegFn, FI, {});
+ OpenMPOffloadingRequiresDirFlags Flags = OMP_REQ_NONE;
+ // TODO: check for other requires clauses.
+ // The requires directive takes effect only when a target region is
+ // present in the compilation unit. Otherwise it is ignored and not
+ // passed to the runtime. This avoids the runtime from throwing an error
+ // for mismatching requires clauses across compilation units that don't
+ // contain at least 1 target region.
+ assert((HasEmittedTargetRegion ||
+ HasEmittedDeclareTargetRegion ||
+ !OffloadEntriesInfoManager.empty()) &&
+ "Target or declare target region expected.");
+ if (HasRequiresUnifiedSharedMemory)
+ Flags = OMP_REQ_UNIFIED_SHARED_MEMORY;
+ CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__tgt_register_requires),
+ llvm::ConstantInt::get(CGM.Int64Ty, Flags));
+ CGF.FinishFunction();
+ }
+ return RequiresRegFn;
+}
+
llvm::Function *CGOpenMPRuntime::emitRegistrationFunction() {
// If we have offloading in the current module, we need to emit the entries
// now and register the offloading descriptor.
@@ -10284,6 +10366,12 @@ void CGOpenMPRuntime::emitOutlinedFunctionCall(
emitCall(CGF, Loc, OutlinedFn, Args);
}
+void CGOpenMPRuntime::emitFunctionProlog(CodeGenFunction &CGF, const Decl *D) {
+ if (const auto *FD = dyn_cast<FunctionDecl>(D))
+ if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD))
+ HasEmittedDeclareTargetRegion = true;
+}
+
Address CGOpenMPRuntime::getParameterAddress(CodeGenFunction &CGF,
const VarDecl *NativeParam,
const VarDecl *TargetParam) const {
OpenPOWER on IntegriCloud