summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.h')
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.h567
1 files changed, 316 insertions, 251 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.h b/contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.h
index b325637..270de8d 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.h
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.h
@@ -14,18 +14,19 @@
#ifndef LLVM_CLANG_LIB_CODEGEN_CGOPENMPRUNTIME_H
#define LLVM_CLANG_LIB_CODEGEN_CGOPENMPRUNTIME_H
+#include "CGValue.h"
#include "clang/AST/Type.h"
#include "clang/Basic/OpenMPKinds.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/IR/Function.h"
#include "llvm/IR/ValueHandle.h"
namespace llvm {
class ArrayType;
class Constant;
-class Function;
class FunctionType;
class GlobalVariable;
class StructType;
@@ -36,222 +37,116 @@ class Value;
namespace clang {
class Expr;
class GlobalDecl;
+class OMPDependClause;
class OMPExecutableDirective;
+class OMPLoopDirective;
class VarDecl;
+class OMPDeclareReductionDecl;
+class IdentifierInfo;
namespace CodeGen {
class Address;
class CodeGenFunction;
class CodeGenModule;
-typedef llvm::function_ref<void(CodeGenFunction &)> RegionCodeGenTy;
+/// A basic class for pre|post-action for advanced codegen sequence for OpenMP
+/// region.
+class PrePostActionTy {
+public:
+ explicit PrePostActionTy() {}
+ virtual void Enter(CodeGenFunction &CGF) {}
+ virtual void Exit(CodeGenFunction &CGF) {}
+ virtual ~PrePostActionTy() {}
+};
-class CGOpenMPRuntime {
-private:
- enum OpenMPRTLFunction {
- /// \brief Call to void __kmpc_fork_call(ident_t *loc, kmp_int32 argc,
- /// kmpc_micro microtask, ...);
- OMPRTL__kmpc_fork_call,
- /// \brief Call to void *__kmpc_threadprivate_cached(ident_t *loc,
- /// kmp_int32 global_tid, void *data, size_t size, void ***cache);
- OMPRTL__kmpc_threadprivate_cached,
- /// \brief Call to void __kmpc_threadprivate_register( ident_t *,
- /// void *data, kmpc_ctor ctor, kmpc_cctor cctor, kmpc_dtor dtor);
- OMPRTL__kmpc_threadprivate_register,
- // Call to __kmpc_int32 kmpc_global_thread_num(ident_t *loc);
- OMPRTL__kmpc_global_thread_num,
- // Call to void __kmpc_critical(ident_t *loc, kmp_int32 global_tid,
- // kmp_critical_name *crit);
- OMPRTL__kmpc_critical,
- // Call to void __kmpc_critical_with_hint(ident_t *loc, kmp_int32
- // global_tid, kmp_critical_name *crit, uintptr_t hint);
- OMPRTL__kmpc_critical_with_hint,
- // Call to void __kmpc_end_critical(ident_t *loc, kmp_int32 global_tid,
- // kmp_critical_name *crit);
- OMPRTL__kmpc_end_critical,
- // Call to kmp_int32 __kmpc_cancel_barrier(ident_t *loc, kmp_int32
- // global_tid);
- OMPRTL__kmpc_cancel_barrier,
- // Call to void __kmpc_barrier(ident_t *loc, kmp_int32 global_tid);
- OMPRTL__kmpc_barrier,
- // Call to void __kmpc_for_static_fini(ident_t *loc, kmp_int32 global_tid);
- OMPRTL__kmpc_for_static_fini,
- // Call to void __kmpc_serialized_parallel(ident_t *loc, kmp_int32
- // global_tid);
- OMPRTL__kmpc_serialized_parallel,
- // Call to void __kmpc_end_serialized_parallel(ident_t *loc, kmp_int32
- // global_tid);
- OMPRTL__kmpc_end_serialized_parallel,
- // Call to void __kmpc_push_num_threads(ident_t *loc, kmp_int32 global_tid,
- // kmp_int32 num_threads);
- OMPRTL__kmpc_push_num_threads,
- // Call to void __kmpc_flush(ident_t *loc);
- OMPRTL__kmpc_flush,
- // Call to kmp_int32 __kmpc_master(ident_t *, kmp_int32 global_tid);
- OMPRTL__kmpc_master,
- // Call to void __kmpc_end_master(ident_t *, kmp_int32 global_tid);
- OMPRTL__kmpc_end_master,
- // Call to kmp_int32 __kmpc_omp_taskyield(ident_t *, kmp_int32 global_tid,
- // int end_part);
- OMPRTL__kmpc_omp_taskyield,
- // Call to kmp_int32 __kmpc_single(ident_t *, kmp_int32 global_tid);
- OMPRTL__kmpc_single,
- // Call to void __kmpc_end_single(ident_t *, kmp_int32 global_tid);
- OMPRTL__kmpc_end_single,
- // Call to kmp_task_t * __kmpc_omp_task_alloc(ident_t *, kmp_int32 gtid,
- // kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
- // kmp_routine_entry_t *task_entry);
- OMPRTL__kmpc_omp_task_alloc,
- // Call to kmp_int32 __kmpc_omp_task(ident_t *, kmp_int32 gtid, kmp_task_t *
- // new_task);
- OMPRTL__kmpc_omp_task,
- // Call to void __kmpc_copyprivate(ident_t *loc, kmp_int32 global_tid,
- // size_t cpy_size, void *cpy_data, void(*cpy_func)(void *, void *),
- // kmp_int32 didit);
- OMPRTL__kmpc_copyprivate,
- // Call to kmp_int32 __kmpc_reduce(ident_t *loc, kmp_int32 global_tid,
- // kmp_int32 num_vars, size_t reduce_size, void *reduce_data, void
- // (*reduce_func)(void *lhs_data, void *rhs_data), kmp_critical_name *lck);
- OMPRTL__kmpc_reduce,
- // Call to kmp_int32 __kmpc_reduce_nowait(ident_t *loc, kmp_int32
- // global_tid, kmp_int32 num_vars, size_t reduce_size, void *reduce_data,
- // void (*reduce_func)(void *lhs_data, void *rhs_data), kmp_critical_name
- // *lck);
- OMPRTL__kmpc_reduce_nowait,
- // Call to void __kmpc_end_reduce(ident_t *loc, kmp_int32 global_tid,
- // kmp_critical_name *lck);
- OMPRTL__kmpc_end_reduce,
- // Call to void __kmpc_end_reduce_nowait(ident_t *loc, kmp_int32 global_tid,
- // kmp_critical_name *lck);
- OMPRTL__kmpc_end_reduce_nowait,
- // Call to void __kmpc_omp_task_begin_if0(ident_t *, kmp_int32 gtid,
- // kmp_task_t * new_task);
- OMPRTL__kmpc_omp_task_begin_if0,
- // Call to void __kmpc_omp_task_complete_if0(ident_t *, kmp_int32 gtid,
- // kmp_task_t * new_task);
- OMPRTL__kmpc_omp_task_complete_if0,
- // Call to void __kmpc_ordered(ident_t *loc, kmp_int32 global_tid);
- OMPRTL__kmpc_ordered,
- // Call to void __kmpc_end_ordered(ident_t *loc, kmp_int32 global_tid);
- OMPRTL__kmpc_end_ordered,
- // Call to kmp_int32 __kmpc_omp_taskwait(ident_t *loc, kmp_int32
- // global_tid);
- OMPRTL__kmpc_omp_taskwait,
- // Call to void __kmpc_taskgroup(ident_t *loc, kmp_int32 global_tid);
- OMPRTL__kmpc_taskgroup,
- // Call to void __kmpc_end_taskgroup(ident_t *loc, kmp_int32 global_tid);
- OMPRTL__kmpc_end_taskgroup,
- // Call to void __kmpc_push_proc_bind(ident_t *loc, kmp_int32 global_tid,
- // int proc_bind);
- OMPRTL__kmpc_push_proc_bind,
- // Call to kmp_int32 __kmpc_omp_task_with_deps(ident_t *loc_ref, kmp_int32
- // gtid, kmp_task_t * new_task, kmp_int32 ndeps, kmp_depend_info_t
- // *dep_list, kmp_int32 ndeps_noalias, kmp_depend_info_t *noalias_dep_list);
- OMPRTL__kmpc_omp_task_with_deps,
- // Call to void __kmpc_omp_wait_deps(ident_t *loc_ref, kmp_int32
- // gtid, kmp_int32 ndeps, kmp_depend_info_t *dep_list, kmp_int32
- // ndeps_noalias, kmp_depend_info_t *noalias_dep_list);
- OMPRTL__kmpc_omp_wait_deps,
- // Call to kmp_int32 __kmpc_cancellationpoint(ident_t *loc, kmp_int32
- // global_tid, kmp_int32 cncl_kind);
- OMPRTL__kmpc_cancellationpoint,
- // Call to kmp_int32 __kmpc_cancel(ident_t *loc, kmp_int32 global_tid,
- // kmp_int32 cncl_kind);
- OMPRTL__kmpc_cancel,
-
- //
- // Offloading related calls
- //
- // Call to int32_t __tgt_target(int32_t device_id, void *host_ptr, int32_t
- // arg_num, void** args_base, void **args, size_t *arg_sizes, int32_t
- // *arg_types);
- OMPRTL__tgt_target,
- // Call to void __tgt_register_lib(__tgt_bin_desc *desc);
- OMPRTL__tgt_register_lib,
- // Call to void __tgt_unregister_lib(__tgt_bin_desc *desc);
- OMPRTL__tgt_unregister_lib,
- };
+/// Class provides a way to call simple version of codegen for OpenMP region, or
+/// an advanced with possible pre|post-actions in codegen.
+class RegionCodeGenTy final {
+ intptr_t CodeGen;
+ typedef void (*CodeGenTy)(intptr_t, CodeGenFunction &, PrePostActionTy &);
+ CodeGenTy Callback;
+ mutable PrePostActionTy *PrePostAction;
+ RegionCodeGenTy() = delete;
+ RegionCodeGenTy &operator=(const RegionCodeGenTy &) = delete;
+ template <typename Callable>
+ static void CallbackFn(intptr_t CodeGen, CodeGenFunction &CGF,
+ PrePostActionTy &Action) {
+ return (*reinterpret_cast<Callable *>(CodeGen))(CGF, Action);
+ }
- /// \brief Values for bit flags used in the ident_t to describe the fields.
- /// All enumeric elements are named and described in accordance with the code
- /// from http://llvm.org/svn/llvm-project/openmp/trunk/runtime/src/kmp.h
- enum OpenMPLocationFlags {
- /// \brief Use trampoline for internal microtask.
- OMP_IDENT_IMD = 0x01,
- /// \brief Use c-style ident structure.
- OMP_IDENT_KMPC = 0x02,
- /// \brief Atomic reduction option for kmpc_reduce.
- OMP_ATOMIC_REDUCE = 0x10,
- /// \brief Explicit 'barrier' directive.
- OMP_IDENT_BARRIER_EXPL = 0x20,
- /// \brief Implicit barrier in code.
- OMP_IDENT_BARRIER_IMPL = 0x40,
- /// \brief Implicit barrier in 'for' directive.
- OMP_IDENT_BARRIER_IMPL_FOR = 0x40,
- /// \brief Implicit barrier in 'sections' directive.
- OMP_IDENT_BARRIER_IMPL_SECTIONS = 0xC0,
- /// \brief Implicit barrier in 'single' directive.
- OMP_IDENT_BARRIER_IMPL_SINGLE = 0x140
- };
+public:
+ template <typename Callable>
+ RegionCodeGenTy(
+ Callable &&CodeGen,
+ typename std::enable_if<
+ !std::is_same<typename std::remove_reference<Callable>::type,
+ RegionCodeGenTy>::value>::type * = nullptr)
+ : CodeGen(reinterpret_cast<intptr_t>(&CodeGen)),
+ Callback(CallbackFn<typename std::remove_reference<Callable>::type>),
+ PrePostAction(nullptr) {}
+ void setAction(PrePostActionTy &Action) const { PrePostAction = &Action; }
+ void operator()(CodeGenFunction &CGF) const;
+};
+
+struct OMPTaskDataTy final {
+ SmallVector<const Expr *, 4> PrivateVars;
+ SmallVector<const Expr *, 4> PrivateCopies;
+ SmallVector<const Expr *, 4> FirstprivateVars;
+ SmallVector<const Expr *, 4> FirstprivateCopies;
+ SmallVector<const Expr *, 4> FirstprivateInits;
+ SmallVector<const Expr *, 4> LastprivateVars;
+ SmallVector<const Expr *, 4> LastprivateCopies;
+ SmallVector<std::pair<OpenMPDependClauseKind, const Expr *>, 4> Dependences;
+ llvm::PointerIntPair<llvm::Value *, 1, bool> Final;
+ llvm::PointerIntPair<llvm::Value *, 1, bool> Schedule;
+ llvm::PointerIntPair<llvm::Value *, 1, bool> Priority;
+ unsigned NumberOfParts = 0;
+ bool Tied = true;
+ bool Nogroup = false;
+};
+
+class CGOpenMPRuntime {
+protected:
CodeGenModule &CGM;
+
+ /// \brief Creates offloading entry for the provided entry ID \a ID,
+ /// address \a Addr and size \a Size.
+ virtual void createOffloadEntry(llvm::Constant *ID, llvm::Constant *Addr,
+ uint64_t Size);
+
+ /// \brief Helper to emit outlined function for 'target' directive.
+ /// \param D Directive to emit.
+ /// \param ParentName Name of the function that encloses the target region.
+ /// \param OutlinedFn Outlined function value to be defined by this call.
+ /// \param OutlinedFnID Outlined function ID value to be defined by this call.
+ /// \param IsOffloadEntry True if the outlined function is an offload entry.
+ /// \param CodeGen Lambda codegen specific to an accelerator device.
+ /// An oulined function may not be an entry if, e.g. the if clause always
+ /// evaluates to false.
+ virtual void emitTargetOutlinedFunctionHelper(const OMPExecutableDirective &D,
+ StringRef ParentName,
+ llvm::Function *&OutlinedFn,
+ llvm::Constant *&OutlinedFnID,
+ bool IsOffloadEntry,
+ const RegionCodeGenTy &CodeGen);
+
+private:
/// \brief Default const ident_t object used for initialization of all other
/// ident_t objects.
- llvm::Constant *DefaultOpenMPPSource;
+ llvm::Constant *DefaultOpenMPPSource = nullptr;
/// \brief Map of flags and corresponding default locations.
typedef llvm::DenseMap<unsigned, llvm::Value *> OpenMPDefaultLocMapTy;
OpenMPDefaultLocMapTy OpenMPDefaultLocMap;
- Address getOrCreateDefaultLocation(OpenMPLocationFlags Flags);
+ Address getOrCreateDefaultLocation(unsigned Flags);
-public:
- /// \brief Describes ident structure that describes a source location.
- /// All descriptions are taken from
- /// http://llvm.org/svn/llvm-project/openmp/trunk/runtime/src/kmp.h
- /// Original structure:
- /// typedef struct ident {
- /// kmp_int32 reserved_1; /**< might be used in Fortran;
- /// see above */
- /// kmp_int32 flags; /**< also f.flags; KMP_IDENT_xxx flags;
- /// KMP_IDENT_KMPC identifies this union
- /// member */
- /// kmp_int32 reserved_2; /**< not really used in Fortran any more;
- /// see above */
- ///#if USE_ITT_BUILD
- /// /* but currently used for storing
- /// region-specific ITT */
- /// /* contextual information. */
- ///#endif /* USE_ITT_BUILD */
- /// kmp_int32 reserved_3; /**< source[4] in Fortran, do not use for
- /// C++ */
- /// char const *psource; /**< String describing the source location.
- /// The string is composed of semi-colon separated
- // fields which describe the source file,
- /// the function and a pair of line numbers that
- /// delimit the construct.
- /// */
- /// } ident_t;
- enum IdentFieldIndex {
- /// \brief might be used in Fortran
- IdentField_Reserved_1,
- /// \brief OMP_IDENT_xxx flags; OMP_IDENT_KMPC identifies this union member.
- IdentField_Flags,
- /// \brief Not really used in Fortran any more
- IdentField_Reserved_2,
- /// \brief Source[4] in Fortran, do not use for C++
- IdentField_Reserved_3,
- /// \brief String describing the source location. The string is composed of
- /// semi-colon separated fields which describe the source file, the function
- /// and a pair of line numbers that delimit the construct.
- IdentField_PSource
- };
-private:
- llvm::StructType *IdentTy;
+ llvm::StructType *IdentTy = nullptr;
/// \brief Map for SourceLocation and OpenMP runtime library debug locations.
typedef llvm::DenseMap<unsigned, llvm::Value *> OpenMPDebugLocMapTy;
OpenMPDebugLocMapTy OpenMPDebugLocMap;
/// \brief The type for a microtask which gets passed to __kmpc_fork_call().
/// Original representation is:
/// typedef void (kmpc_micro)(kmp_int32 global_tid, kmp_int32 bound_tid,...);
- llvm::FunctionType *Kmpc_MicroTy;
+ llvm::FunctionType *Kmpc_MicroTy = nullptr;
/// \brief Stores debug location and ThreadID for the function.
struct DebugLocThreadIdTy {
llvm::Value *DebugLoc;
@@ -261,6 +156,20 @@ private:
typedef llvm::DenseMap<llvm::Function *, DebugLocThreadIdTy>
OpenMPLocThreadIDMapTy;
OpenMPLocThreadIDMapTy OpenMPLocThreadIDMap;
+ /// Map of UDRs and corresponding combiner/initializer.
+ typedef llvm::DenseMap<const OMPDeclareReductionDecl *,
+ std::pair<llvm::Function *, llvm::Function *>>
+ UDRMapTy;
+ UDRMapTy UDRMap;
+ /// Map of functions and locally defined UDRs.
+ typedef llvm::DenseMap<llvm::Function *,
+ SmallVector<const OMPDeclareReductionDecl *, 4>>
+ FunctionUDRMapTy;
+ FunctionUDRMapTy FunctionUDRMap;
+ IdentifierInfo *In = nullptr;
+ IdentifierInfo *Out = nullptr;
+ IdentifierInfo *Priv = nullptr;
+ IdentifierInfo *Orig = nullptr;
/// \brief Type kmp_critical_name, originally defined as typedef kmp_int32
/// kmp_critical_name[8];
llvm::ArrayType *KmpCriticalNameTy;
@@ -272,7 +181,7 @@ private:
llvm::StringMap<llvm::AssertingVH<llvm::Constant>, llvm::BumpPtrAllocator>
InternalVars;
/// \brief Type typedef kmp_int32 (* kmp_routine_entry_t)(kmp_int32, void *);
- llvm::Type *KmpRoutineEntryPtrTy;
+ llvm::Type *KmpRoutineEntryPtrTy = nullptr;
QualType KmpRoutineEntryPtrQTy;
/// \brief Type typedef struct kmp_task {
/// void * shareds; /**< pointer to block of pointers to
@@ -293,6 +202,12 @@ private:
/// } flags;
/// } kmp_depend_info_t;
QualType KmpDependInfoTy;
+ /// struct kmp_dim { // loop bounds info casted to kmp_int64
+ /// kmp_int64 lo; // lower
+ /// kmp_int64 up; // upper
+ /// kmp_int64 st; // stride
+ /// };
+ QualType KmpDimTy;
/// \brief Type struct __tgt_offload_entry{
/// void *addr; // Pointer to the offload entry info.
/// // (function or global)
@@ -402,30 +317,27 @@ private:
/// \brief Initialize target region entry.
void initializeTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID,
StringRef ParentName, unsigned LineNum,
- unsigned ColNum, unsigned Order);
+ unsigned Order);
/// \brief Register target region entry.
void registerTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID,
StringRef ParentName, unsigned LineNum,
- unsigned ColNum, llvm::Constant *Addr,
+ llvm::Constant *Addr,
llvm::Constant *ID);
/// \brief Return true if a target region entry with the provided
/// information exists.
bool hasTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID,
- StringRef ParentName, unsigned LineNum,
- unsigned ColNum) const;
+ StringRef ParentName, unsigned LineNum) const;
/// brief Applies action \a Action on all registered entries.
typedef llvm::function_ref<void(unsigned, unsigned, StringRef, unsigned,
- unsigned, OffloadEntryInfoTargetRegion &)>
+ OffloadEntryInfoTargetRegion &)>
OffloadTargetRegionEntryInfoActTy;
void actOnTargetRegionEntriesInfo(
const OffloadTargetRegionEntryInfoActTy &Action);
private:
// Storage for target region entries kind. The storage is to be indexed by
- // file ID, device ID, parent function name, lane number, and column number.
+ // file ID, device ID, parent function name and line number.
typedef llvm::DenseMap<unsigned, OffloadEntryInfoTargetRegion>
- OffloadEntriesTargetRegionPerColumn;
- typedef llvm::DenseMap<unsigned, OffloadEntriesTargetRegionPerColumn>
OffloadEntriesTargetRegionPerLine;
typedef llvm::StringMap<OffloadEntriesTargetRegionPerLine>
OffloadEntriesTargetRegionPerParentName;
@@ -442,10 +354,6 @@ private:
/// compilation unit. The function that does the registration is returned.
llvm::Function *createOffloadingBinaryDescriptorRegistration();
- /// \brief Creates offloading entry for the provided address \a Addr,
- /// name \a Name and size \a Size.
- void createOffloadEntry(llvm::Constant *Addr, StringRef Name, uint64_t Size);
-
/// \brief Creates all the offload entries in the current compilation unit
/// along with the associated metadata.
void createOffloadEntriesAndInfoMetadata();
@@ -476,7 +384,7 @@ private:
/// \param Flags Flags for OpenMP location.
///
llvm::Value *emitUpdateLocation(CodeGenFunction &CGF, SourceLocation Loc,
- OpenMPLocationFlags Flags = OMP_IDENT_KMPC);
+ unsigned Flags = 0);
/// \brief Returns pointer to ident_t type.
llvm::Type *getIdentTyPointerTy();
@@ -487,7 +395,7 @@ private:
/// \brief Returns specified OpenMP runtime function.
/// \param Function OpenMP runtime function.
/// \return Specified function.
- llvm::Constant *createRuntimeFunction(OpenMPRTLFunction Function);
+ llvm::Constant *createRuntimeFunction(unsigned Function);
/// \brief Returns __kmpc_for_static_init_* runtime function for the specified
/// size \a IVSize and sign \a IVSigned.
@@ -530,7 +438,7 @@ private:
const llvm::Twine &Name);
/// \brief Set of threadprivate variables with the generated initializer.
- llvm::DenseSet<const VarDecl *> ThreadPrivateWithDefinition;
+ llvm::SmallPtrSet<const VarDecl *, 4> ThreadPrivateWithDefinition;
/// \brief Emits initialization code for the threadprivate variables.
/// \param VDAddr Address of the global variable \a VD.
@@ -549,11 +457,52 @@ private:
///
llvm::Value *getCriticalRegionLock(StringRef CriticalName);
+ struct TaskResultTy {
+ llvm::Value *NewTask = nullptr;
+ llvm::Value *TaskEntry = nullptr;
+ llvm::Value *NewTaskNewTaskTTy = nullptr;
+ LValue TDBase;
+ RecordDecl *KmpTaskTQTyRD = nullptr;
+ llvm::Value *TaskDupFn = nullptr;
+ };
+ /// Emit task region for the task directive. The task region is emitted in
+ /// several steps:
+ /// 1. Emit a call to kmp_task_t *__kmpc_omp_task_alloc(ident_t *, kmp_int32
+ /// gtid, kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
+ /// kmp_routine_entry_t *task_entry). Here task_entry is a pointer to the
+ /// function:
+ /// kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) {
+ /// TaskFunction(gtid, tt->part_id, tt->shareds);
+ /// return 0;
+ /// }
+ /// 2. Copy a list of shared variables to field shareds of the resulting
+ /// structure kmp_task_t returned by the previous call (if any).
+ /// 3. Copy a pointer to destructions function to field destructions of the
+ /// resulting structure kmp_task_t.
+ /// \param D Current task directive.
+ /// \param TaskFunction An LLVM function with type void (*)(i32 /*gtid*/, i32
+ /// /*part_id*/, captured_struct */*__context*/);
+ /// \param SharedsTy A type which contains references the shared variables.
+ /// \param Shareds Context with the list of shared variables from the \p
+ /// TaskFunction.
+ /// \param Data Additional data for task generation like tiednsee, final
+ /// state, list of privates etc.
+ TaskResultTy emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc,
+ const OMPExecutableDirective &D,
+ llvm::Value *TaskFunction, QualType SharedsTy,
+ Address Shareds, const OMPTaskDataTy &Data);
+
public:
explicit CGOpenMPRuntime(CodeGenModule &CGM);
virtual ~CGOpenMPRuntime() {}
virtual void clear();
+ /// Emit code for the specified user defined reduction construct.
+ virtual void emitUserDefinedReduction(CodeGenFunction *CGF,
+ const OMPDeclareReductionDecl *D);
+ /// Get combiner/initializer for the specified user-defined reduction, if any.
+ virtual std::pair<llvm::Function *, llvm::Function *>
+ getUserDefinedReduction(const OMPDeclareReductionDecl *D);
/// \brief Emits outlined function for the specified OpenMP parallel directive
/// \a D. This outlined function has type void(*)(kmp_int32 *ThreadID,
/// kmp_int32 BoundID, struct context_vars*).
@@ -562,22 +511,30 @@ public:
/// \param InnermostKind Kind of innermost directive (for simple directives it
/// is a directive itself, for combined - its innermost directive).
/// \param CodeGen Code generation sequence for the \a D directive.
- virtual llvm::Value *emitParallelOutlinedFunction(
+ virtual llvm::Value *emitParallelOrTeamsOutlinedFunction(
const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen);
/// \brief Emits outlined function for the OpenMP task directive \a D. This
- /// outlined function has type void(*)(kmp_int32 ThreadID, kmp_int32
- /// PartID, struct context_vars*).
+ /// outlined function has type void(*)(kmp_int32 ThreadID, struct task_t*
+ /// TaskT).
/// \param D OpenMP directive.
/// \param ThreadIDVar Variable for thread id in the current OpenMP region.
+ /// \param PartIDVar Variable for partition id in the current OpenMP untied
+ /// task region.
+ /// \param TaskTVar Variable for task_t argument.
/// \param InnermostKind Kind of innermost directive (for simple directives it
/// is a directive itself, for combined - its innermost directive).
/// \param CodeGen Code generation sequence for the \a D directive.
+ /// \param Tied true if task is generated for tied task, false otherwise.
+ /// \param NumberOfParts Number of parts in untied task. Ignored for tied
+ /// tasks.
///
virtual llvm::Value *emitTaskOutlinedFunction(
const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
- OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen);
+ const VarDecl *PartIDVar, const VarDecl *TaskTVar,
+ OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen,
+ bool Tied, unsigned &NumberOfParts);
/// \brief Cleans up references to the objects in finished function.
///
@@ -664,6 +621,14 @@ public:
virtual bool isStaticNonchunked(OpenMPScheduleClauseKind ScheduleKind,
bool Chunked) const;
+ /// \brief Check if the specified \a ScheduleKind is static non-chunked.
+ /// This kind of distribute directive is emitted without outer loop.
+ /// \param ScheduleKind Schedule kind specified in the 'dist_schedule' clause.
+ /// \param Chunked True if chunk is specified in the clause.
+ ///
+ virtual bool isStaticNonchunked(OpenMPDistScheduleClauseKind ScheduleKind,
+ bool Chunked) const;
+
/// \brief Check if the specified \a ScheduleKind is dynamic.
/// This kind of worksharing directive is emitted without outer loop.
/// \param ScheduleKind Schedule Kind specified in the 'schedule' clause.
@@ -671,9 +636,9 @@ public:
virtual bool isDynamic(OpenMPScheduleClauseKind ScheduleKind) const;
virtual void emitForDispatchInit(CodeGenFunction &CGF, SourceLocation Loc,
- OpenMPScheduleClauseKind SchedKind,
- unsigned IVSize, bool IVSigned,
- bool Ordered, llvm::Value *UB,
+ const OpenMPScheduleTy &ScheduleKind,
+ unsigned IVSize, bool IVSigned, bool Ordered,
+ llvm::Value *UB,
llvm::Value *Chunk = nullptr);
/// \brief Call the appropriate runtime routine to initialize it before start
@@ -685,7 +650,7 @@ public:
///
/// \param CGF Reference to current CodeGenFunction.
/// \param Loc Clang source location.
- /// \param SchedKind Schedule kind, specified by the 'schedule' clause.
+ /// \param ScheduleKind Schedule kind, specified by the 'schedule' clause.
/// \param IVSize Size of the iteration variable in bits.
/// \param IVSigned Sign of the interation variable.
/// \param Ordered true if loop is ordered, false otherwise.
@@ -701,12 +666,36 @@ public:
/// For the default (nullptr) value, the chunk 1 will be used.
///
virtual void emitForStaticInit(CodeGenFunction &CGF, SourceLocation Loc,
- OpenMPScheduleClauseKind SchedKind,
+ const OpenMPScheduleTy &ScheduleKind,
unsigned IVSize, bool IVSigned, bool Ordered,
- Address IL, Address LB,
- Address UB, Address ST,
+ Address IL, Address LB, Address UB, Address ST,
llvm::Value *Chunk = nullptr);
+ ///
+ /// \param CGF Reference to current CodeGenFunction.
+ /// \param Loc Clang source location.
+ /// \param SchedKind Schedule kind, specified by the 'dist_schedule' clause.
+ /// \param IVSize Size of the iteration variable in bits.
+ /// \param IVSigned Sign of the interation variable.
+ /// \param Ordered true if loop is ordered, false otherwise.
+ /// \param IL Address of the output variable in which the flag of the
+ /// last iteration is returned.
+ /// \param LB Address of the output variable in which the lower iteration
+ /// number is returned.
+ /// \param UB Address of the output variable in which the upper iteration
+ /// number is returned.
+ /// \param ST Address of the output variable in which the stride value is
+ /// returned nesessary to generated the static_chunked scheduled loop.
+ /// \param Chunk Value of the chunk for the static_chunked scheduled loop.
+ /// For the default (nullptr) value, the chunk 1 will be used.
+ ///
+ virtual void emitDistributeStaticInit(CodeGenFunction &CGF, SourceLocation Loc,
+ OpenMPDistScheduleClauseKind SchedKind,
+ unsigned IVSize, bool IVSigned,
+ bool Ordered, Address IL, Address LB,
+ Address UB, Address ST,
+ llvm::Value *Chunk = nullptr);
+
/// \brief Call the appropriate runtime routine to notify that we finished
/// iteration of the ordered loop with the dynamic scheduling.
///
@@ -807,12 +796,6 @@ public:
/// kmp_task_t *new_task), where new_task is a resulting structure from
/// previous items.
/// \param D Current task directive.
- /// \param Tied true if the task is tied (the task is tied to the thread that
- /// can suspend its task region), false - untied (the task is not tied to any
- /// thread).
- /// \param Final Contains either constant bool value, or llvm::Value * of i1
- /// type for final clause. If the value is true, the task forces all of its
- /// child tasks to become final and included tasks.
/// \param TaskFunction An LLVM function with type void (*)(i32 /*gtid*/, i32
/// /*part_id*/, captured_struct */*__context*/);
/// \param SharedsTy A type which contains references the shared variables.
@@ -820,29 +803,47 @@ public:
/// TaskFunction.
/// \param IfCond Not a nullptr if 'if' clause was specified, nullptr
/// otherwise.
- /// \param PrivateVars List of references to private variables for the task
- /// directive.
- /// \param PrivateCopies List of private copies for each private variable in
- /// \p PrivateVars.
- /// \param FirstprivateVars List of references to private variables for the
- /// task directive.
- /// \param FirstprivateCopies List of private copies for each private variable
- /// in \p FirstprivateVars.
- /// \param FirstprivateInits List of references to auto generated variables
- /// used for initialization of a single array element. Used if firstprivate
- /// variable is of array type.
- /// \param Dependences List of dependences for the 'task' construct, including
- /// original expression and dependency type.
- virtual void emitTaskCall(
- CodeGenFunction &CGF, SourceLocation Loc, const OMPExecutableDirective &D,
- bool Tied, llvm::PointerIntPair<llvm::Value *, 1, bool> Final,
+ /// \param Data Additional data for task generation like tiednsee, final
+ /// state, list of privates etc.
+ virtual void emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
+ const OMPExecutableDirective &D,
+ llvm::Value *TaskFunction, QualType SharedsTy,
+ Address Shareds, const Expr *IfCond,
+ const OMPTaskDataTy &Data);
+
+ /// Emit task region for the taskloop directive. The taskloop region is
+ /// emitted in several steps:
+ /// 1. Emit a call to kmp_task_t *__kmpc_omp_task_alloc(ident_t *, kmp_int32
+ /// gtid, kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
+ /// kmp_routine_entry_t *task_entry). Here task_entry is a pointer to the
+ /// function:
+ /// kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) {
+ /// TaskFunction(gtid, tt->part_id, tt->shareds);
+ /// return 0;
+ /// }
+ /// 2. Copy a list of shared variables to field shareds of the resulting
+ /// structure kmp_task_t returned by the previous call (if any).
+ /// 3. Copy a pointer to destructions function to field destructions of the
+ /// resulting structure kmp_task_t.
+ /// 4. Emit a call to void __kmpc_taskloop(ident_t *loc, int gtid, kmp_task_t
+ /// *task, int if_val, kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st, int
+ /// nogroup, int sched, kmp_uint64 grainsize, void *task_dup ), where new_task
+ /// is a resulting structure from
+ /// previous items.
+ /// \param D Current task directive.
+ /// \param TaskFunction An LLVM function with type void (*)(i32 /*gtid*/, i32
+ /// /*part_id*/, captured_struct */*__context*/);
+ /// \param SharedsTy A type which contains references the shared variables.
+ /// \param Shareds Context with the list of shared variables from the \p
+ /// TaskFunction.
+ /// \param IfCond Not a nullptr if 'if' clause was specified, nullptr
+ /// otherwise.
+ /// \param Data Additional data for task generation like tiednsee, final
+ /// state, list of privates etc.
+ virtual void emitTaskLoopCall(
+ CodeGenFunction &CGF, SourceLocation Loc, const OMPLoopDirective &D,
llvm::Value *TaskFunction, QualType SharedsTy, Address Shareds,
- const Expr *IfCond, ArrayRef<const Expr *> PrivateVars,
- ArrayRef<const Expr *> PrivateCopies,
- ArrayRef<const Expr *> FirstprivateVars,
- ArrayRef<const Expr *> FirstprivateCopies,
- ArrayRef<const Expr *> FirstprivateInits,
- ArrayRef<std::pair<OpenMPDependClauseKind, const Expr *>> Dependences);
+ const Expr *IfCond, const OMPTaskDataTy &Data);
/// \brief Emit code for the directive that does not require outlining.
///
@@ -926,13 +927,15 @@ public:
/// \param OutlinedFn Outlined function value to be defined by this call.
/// \param OutlinedFnID Outlined function ID value to be defined by this call.
/// \param IsOffloadEntry True if the outlined function is an offload entry.
+ /// \param CodeGen Code generation sequence for the \a D directive.
/// An oulined function may not be an entry if, e.g. the if clause always
/// evaluates to false.
virtual void emitTargetOutlinedFunction(const OMPExecutableDirective &D,
StringRef ParentName,
llvm::Function *&OutlinedFn,
llvm::Constant *&OutlinedFnID,
- bool IsOffloadEntry);
+ bool IsOffloadEntry,
+ const RegionCodeGenTy &CodeGen);
/// \brief Emit the target offloading code associated with \a D. The emitted
/// code attempts offloading the execution to the device, an the event of
@@ -972,6 +975,68 @@ public:
/// was emitted in the current module and return the function that registers
/// it.
virtual llvm::Function *emitRegistrationFunction();
+
+ /// \brief Emits code for teams call of the \a OutlinedFn with
+ /// variables captured in a record which address is stored in \a
+ /// CapturedStruct.
+ /// \param OutlinedFn Outlined function to be run by team masters. Type of
+ /// this function is void(*)(kmp_int32 *, kmp_int32, struct context_vars*).
+ /// \param CapturedVars A pointer to the record with the references to
+ /// variables used in \a OutlinedFn function.
+ ///
+ virtual void emitTeamsCall(CodeGenFunction &CGF,
+ const OMPExecutableDirective &D,
+ SourceLocation Loc, llvm::Value *OutlinedFn,
+ ArrayRef<llvm::Value *> CapturedVars);
+
+ /// \brief Emits call to void __kmpc_push_num_teams(ident_t *loc, kmp_int32
+ /// global_tid, kmp_int32 num_teams, kmp_int32 thread_limit) to generate code
+ /// for num_teams clause.
+ /// \param NumTeams An integer expression of teams.
+ /// \param ThreadLimit An integer expression of threads.
+ virtual void emitNumTeamsClause(CodeGenFunction &CGF, const Expr *NumTeams,
+ const Expr *ThreadLimit, SourceLocation Loc);
+
+ /// \brief Emit the target data mapping code associated with \a D.
+ /// \param D Directive to emit.
+ /// \param IfCond Expression evaluated in if clause associated with the target
+ /// directive, or null if no if clause is used.
+ /// \param Device Expression evaluated in device clause associated with the
+ /// target directive, or null if no device clause is used.
+ /// \param CodeGen Function that emits the enclosed region.
+ virtual void emitTargetDataCalls(CodeGenFunction &CGF,
+ const OMPExecutableDirective &D,
+ const Expr *IfCond, const Expr *Device,
+ const RegionCodeGenTy &CodeGen);
+
+ /// \brief Emit the data mapping/movement code associated with the directive
+ /// \a D that should be of the form 'target [{enter|exit} data | update]'.
+ /// \param D Directive to emit.
+ /// \param IfCond Expression evaluated in if clause associated with the target
+ /// directive, or null if no if clause is used.
+ /// \param Device Expression evaluated in device clause associated with the
+ /// target directive, or null if no device clause is used.
+ virtual void emitTargetDataStandAloneCall(CodeGenFunction &CGF,
+ const OMPExecutableDirective &D,
+ const Expr *IfCond,
+ const Expr *Device);
+
+ /// Marks function \a Fn with properly mangled versions of vector functions.
+ /// \param FD Function marked as 'declare simd'.
+ /// \param Fn LLVM function that must be marked with 'declare simd'
+ /// attributes.
+ virtual void emitDeclareSimdFunction(const FunctionDecl *FD,
+ llvm::Function *Fn);
+
+ /// Emit initialization for doacross loop nesting support.
+ /// \param D Loop-based construct used in doacross nesting construct.
+ virtual void emitDoacrossInit(CodeGenFunction &CGF,
+ const OMPLoopDirective &D);
+
+ /// Emit code for doacross ordered directive with 'depend' clause.
+ /// \param C 'depend' clause with 'sink|source' dependency kind.
+ virtual void emitDoacrossOrdered(CodeGenFunction &CGF,
+ const OMPDependClause *C);
};
} // namespace CodeGen
OpenPOWER on IntegriCloud