Commit Graph

135 Commits

Author SHA1 Message Date
Alexey Bataev 76af433873 [OPENMP] Introduced type trait "__builtin_omp_required_simd_align" for default simd alignment.
Adds type trait "__builtin_omp_required_simd_align" after discussions here http://reviews.llvm.org/D9894
Differential Revision: http://reviews.llvm.org/D10597


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@241237 91177308-0d34-0410-b5e6-96231b3b80d8
2015-07-02 03:40:19 +00:00
Alexey Bataev a4233e1014 [OPENMP 4.0] Initial support for 'omp cancellation point' construct.
Add parsing and sema analysis for 'omp cancellation point' directive.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@241145 91177308-0d34-0410-b5e6-96231b3b80d8
2015-07-01 06:57:41 +00:00
Alexey Bataev 9653c7afaa [OPENMP] Codegen for 'depend' clause (OpenMP 4.0).
If task directive has associated 'depend' clause then function 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) must be called instead of __kmpc_omp_task().
If this directive has associated 'if' clause then also before a call of kmpc_omp_task_begin_if0() a function 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) must be called.
Array sections are not supported yet.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@240532 91177308-0d34-0410-b5e6-96231b3b80d8
2015-06-24 11:01:36 +00:00
Alexey Bataev a2891f255b [OPENMP] Initial support for 'depend' clause (4.0).
Parsing and sema analysis (without support for array sections in arguments) for 'depend' clause (used in 'task' directive, OpenMP 4.0).


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@240409 91177308-0d34-0410-b5e6-96231b3b80d8
2015-06-23 14:25:19 +00:00
Alexey Bataev 848f5c87e2 [OPENMP] Codegen for 'proc_bind' clause (4.0).
Adds emission of the code for 'proc_bind(master|close|spread)' clause:
call void @__kmpc_push_proc_bind(<loc>, i32 thread_id, i32 4|3|2)



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@240018 91177308-0d34-0410-b5e6-96231b3b80d8
2015-06-18 13:40:03 +00:00
Alexey Bataev 9080c07f6d [OPENMP] Support for '#pragma omp taskgroup' directive.
Added parsing, sema analysis and codegen for '#pragma omp taskgroup' directive (OpenMP 4.0).
The code for directive is generated the following way:
#pragma omp taskgroup
<body>

void __kmpc_taskgroup(<loc>, thread_id);
<body>
void __kmpc_end_taskgroup(<loc>, thread_id);


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@240011 91177308-0d34-0410-b5e6-96231b3b80d8
2015-06-18 12:14:09 +00:00
Alexey Bataev 6ccf1a9d0f [OPENMP] Add support for 'omp parallel for' directive.
Codegen for this directive is a combined codegen for 'omp parallel' region with 'omp for simd' region inside. Clauses are supported.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@240006 91177308-0d34-0410-b5e6-96231b3b80d8
2015-06-18 10:10:12 +00:00
Alexey Bataev 289b8ef73c [OPENMP] Add support for 'omp for simd' directive.
Added codegen for combined 'omp for simd' directives, that is a combination of 'omp for' directive followed by 'omp simd' directive. Includes support for all clauses.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@239990 91177308-0d34-0410-b5e6-96231b3b80d8
2015-06-18 04:45:29 +00:00
Alexey Bataev c9e5336db1 [OPENMP] Code reformatting for omp simd codegen, NFC.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@239889 91177308-0d34-0410-b5e6-96231b3b80d8
2015-06-17 07:45:51 +00:00
Alexey Bataev cfbe7677cd [OPENMP] Supported reduction clause in omp simd construct.
The following code is generated for reduction clause within 'omp simd' loop construct:
#pragma omp simd reduction(op:var)
for (...)
  <body>

alloca priv_var
priv_var = <initial reduction value>;
<loop_start>:
<body> // references to original 'var' are replaced by 'priv_var'
<loop_end>:
var op= priv_var;


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@239881 91177308-0d34-0410-b5e6-96231b3b80d8
2015-06-17 06:21:39 +00:00
Alexey Bataev 5b8e5c34b9 [OPENMP] Support lastprivate clause in omp simd directive.
Added codegen for lastprivate clauses within simd loop-based directives.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@239813 91177308-0d34-0410-b5e6-96231b3b80d8
2015-06-16 13:14:42 +00:00
Alexey Bataev 706a4b8212 [OPENMP] Remove last iteration separation for loop-based constructs.
Previously the last iteration for simd loop-based OpenMP constructs were generated as a separate code. This feature is not required and codegen is simplified.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@239810 91177308-0d34-0410-b5e6-96231b3b80d8
2015-06-16 11:59:36 +00:00
Alexey Bataev cba60c5899 [OPENMP] Fox for http://llvm.org/PR23663: OpenMP crash
Destroy RuntimeCleanupScope before generation of termination instruction in parallel loop precondition.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@239524 91177308-0d34-0410-b5e6-96231b3b80d8
2015-06-11 10:53:56 +00:00
Alexey Bataev 8f0271771b [OPENMP] Prepare codegen for privates in tasks for non-capturing of privates in CapturedStmt.
Reworked codegen for privates in tasks:

call @kmpc_omp_task_alloc();
...
call @kmpc_omp_task(task_proxy);

void map_privates(.privates_rec. *privs, type1 ** priv1_ref, ..., typen **privn_ref) {
  *priv1_ref = &privs->private1;
  ...
  *privn_ref = &privs->privaten;
  ret void
}

i32 task_entry(i32 ThreadId, i32 PartId, void* privs, void (void*, ...) map_privates, shareds* captures) {
  type1 **priv1;
  ...
  typen **privn;
  call map_privates(privs, priv1, ..., privn);
  <Task body with priv1, .., privn instead of the captured variables>.
  ret i32
}

i32 task_proxy(i32 ThreadId, kmp_task_t_with_privates *tt) {
  call task_entry(ThreadId, tt->task_data.PartId, &tt->privates, map_privates, tt->task_data.shareds);
}



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@238010 91177308-0d34-0410-b5e6-96231b3b80d8
2015-05-22 08:56:35 +00:00
Alexey Bataev 2f03fe35c5 [OPENMP] Fixed codegen for parameters privatization.
For parameters we shall take a derived type of parameters, not the original one.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@237882 91177308-0d34-0410-b5e6-96231b3b80d8
2015-05-21 09:47:46 +00:00
Alexey Bataev 5f55bfbbce [OPENMP] Fixed codegen for lastprivate LCV in worksharing constructs.
If loop control variable in a worksharing construct is marked as lastprivate, we should copy last calculated value of private counter back to original variable.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@237879 91177308-0d34-0410-b5e6-96231b3b80d8
2015-05-21 07:59:51 +00:00
Alexey Bataev f860d72ec3 [OPENMP] Fix codegen for ordered loop directives.
loops with ordered clause must be generated the same way as dynamic loops, but with static scheduleing.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@237788 91177308-0d34-0410-b5e6-96231b3b80d8
2015-05-20 13:12:48 +00:00
Alexey Bataev 8db3eab2a3 [OPENMP] Fixed codegen for copying/initialization of array variables/parameters.
This modification generates proper copyin/initialization sequences for array variables/parameters. Before they were considered as pointers, not arrays.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@237691 91177308-0d34-0410-b5e6-96231b3b80d8
2015-05-19 12:31:28 +00:00
Alexey Bataev 4fba977c95 [OPENMP] Fixed codegen for firstprivate variables, also marked as lastprivate.
In some rare cases shared copies of lastprivate/firstprivate variables were not updated after the loop directive.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@237243 91177308-0d34-0410-b5e6-96231b3b80d8
2015-05-13 10:23:02 +00:00
Alexey Bataev a9737f0072 [OPENMP] Fixed support for 'schedule' clause with non-constant chunk size.
'schedule' clause for combined directives requires additional processing. Special helper variable is generated, that is captured in the outlined parallel region for 'parallel for' region. This captured variable is used to store chunk expression from the 'schedule' clause in this 'parallel for' region.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@237100 91177308-0d34-0410-b5e6-96231b3b80d8
2015-05-12 08:35:28 +00:00
Alexey Bataev c31eea2ad3 [OPENMP] Fixed atomic construct with non-integer expressions.
Do not emit 'atomicrmw' instruction for simple atomic constructs with non-integer expressions.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@236828 91177308-0d34-0410-b5e6-96231b3b80d8
2015-05-08 11:47:16 +00:00
Alexey Bataev b17798acb1 [OPENMP] Code cleanup for capturing of variables in OpenMP regions.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@236821 91177308-0d34-0410-b5e6-96231b3b80d8
2015-05-08 10:41:21 +00:00
Alexey Bataev 4f5ae56045 [OPENMP] Generate !llvm.mem.loop_parallel_access metadata for loops with dynamic/guided scheduling.
Inner bodies of OpenMP worksharing loop-based constructs with dynamic or guided scheduling are allowed to be marked with !llvm.mem.parallel_loop_access metadata for better optimization. Worksharing constructs with static scheduling cannot be marked this way (according to OpenMP standard "A data dependence between the same logical iterations in two such loops is guaranteed").
Constructs with auto and runtime scheduling are also not marked because automatically chosen scheduling may be static also.
Differential Revision: http://reviews.llvm.org/D9518


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@236693 91177308-0d34-0410-b5e6-96231b3b80d8
2015-05-07 04:25:17 +00:00
Alexey Bataev 965084cb86 [OPENMP] Codegen for 'firstprivate' clause in 'task' directive.
For tasks codegen for private/firstprivate variables are different rather than for other directives.

1. Build an internal structure of privates for each private variable:
struct .kmp_privates_t. {
  Ty1 var1;
  ...
  Tyn varn;
};
2. Add a new field to kmp_task_t type with list of privates.
struct kmp_task_t {
  void *              shareds;
  kmp_routine_entry_t routine;
  kmp_int32           part_id;
  kmp_routine_entry_t destructors;
  .kmp_privates_t.    privates;
};
3. Create a function with destructors calls for all privates after end of task region.
kmp_int32 .omp_task_destructor.(kmp_int32 gtid, kmp_task_t *tt) {
  ~Destructor(&tt->privates.var1);
  ...
  ~Destructor(&tt->privates.varn);
  return 0;
}
4. Perform initialization of all firstprivate fields (by simple copying for POD data, copy constructor calls for classes) + provide address of a destructor function after kmpc_omp_task_alloc() and before kmpc_omp_task() calls.
kmp_task_t *new_task = __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);

CopyConstructor(new_task->privates.var1, *new_task->shareds.var1_ref);
new_task->shareds.var1_ref = &new_task->privates.var1;
...
CopyConstructor(new_task->privates.varn, *new_task->shareds.varn_ref);
new_task->shareds.varn_ref = &new_task->privates.varn;

new_task->destructors = .omp_task_destructor.;
kmp_int32 __kmpc_omp_task(ident_t *, kmp_int32 gtid, kmp_task_t *new_task)
Differential Revision: http://reviews.llvm.org/D9370


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@236479 91177308-0d34-0410-b5e6-96231b3b80d8
2015-05-05 04:05:12 +00:00
Benjamin Kramer 12d6be0aa0 Make helper functions static. NFC.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@236315 91177308-0d34-0410-b5e6-96231b3b80d8
2015-05-01 13:59:53 +00:00
Alexey Bataev 1a1eb1e5f9 [OPENMP] Codegen for 'private' clause in 'task' directive.
For tasks codegen for private/firstprivate variables are different rather than for other directives.

1. Build an internal structure of privates for each private variable:
struct .kmp_privates_t. {
  Ty1 var1;
  ...
  Tyn varn;
};
2. Add a new field to kmp_task_t type with list of privates.
struct kmp_task_t {
  void *              shareds;
  kmp_routine_entry_t routine;
  kmp_int32           part_id;
  kmp_routine_entry_t destructors;
  .kmp_privates_t.    privates;
};
3. Create a function with destructors calls for all privates after end of task region.
kmp_int32 .omp_task_destructor.(kmp_int32 gtid, kmp_task_t *tt) {
  ~Destructor(&tt->privates.var1);
  ...
  ~Destructor(&tt->privates.varn);
  return 0;
}
4. Perform default initialization of all private fields (no initialization for POD data, default constructor calls for classes) + provide address of a destructor function after kmpc_omp_task_alloc() and before kmpc_omp_task() calls.
kmp_task_t *new_task = __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);

DefaultConstructor(new_task->privates.var1);
new_task->shareds.var1_ref = &new_task->privates.var1;
...
DefaultConstructor(new_task->privates.varn);
new_task->shareds.varn_ref = &new_task->privates.varn;

new_task->destructors = .omp_task_destructor.;
kmp_int32 __kmpc_omp_task(ident_t *, kmp_int32 gtid, kmp_task_t *new_task)


Differential Revision: http://reviews.llvm.org/D9322


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@236207 91177308-0d34-0410-b5e6-96231b3b80d8
2015-04-30 06:51:57 +00:00
Alexey Bataev 7e8c486a45 [OPENMP] Fix crash on loop control vars explicitly marked as private.
It is allowed to mark loop control vars as private in 'private' or 'lastprivate' clause, so no need to assert here.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@235985 91177308-0d34-0410-b5e6-96231b3b80d8
2015-04-28 13:20:05 +00:00
Alexey Bataev e9fda6420c [OPENMP] Simplified iteration over clauses, NFC.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@235838 91177308-0d34-0410-b5e6-96231b3b80d8
2015-04-27 08:00:32 +00:00
Alexey Bataev 4c83c827f2 [OPENMP] Codegen for 'taskwait' directive.
Emit the following code for 'taskwait' directive within tied task:
call i32 @__kmpc_omp_taskwait(<loc>, i32 <thread_id>);
Differential Revision: http://reviews.llvm.org/D9245


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@235836 91177308-0d34-0410-b5e6-96231b3b80d8
2015-04-27 05:22:09 +00:00
Alexey Bataev 05856ab832 [OPENMP] Codegen for 'reduction' clause in 'sections' directive.
Emit a code for reduction clause. Next code should be emitted for reductions:

static kmp_critical_name lock = { 0 };

void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
    *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]);
      ...
        *(Type<n>-1*)lhs[<n>-1] =
          ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1],
            *(Type<n>-1*)rhs[<n>-1]);
}

...
void *RedList[<n>] = {&<RHSExprs>[0], ..., &<RHSExprs>[<n>-1]};
switch (__kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>)) {
case 1:
  <LHSExprs>[0] = ReductionOperation0(*<LHSExprs>[0], *<RHSExprs>[0]);
  ...
  <LHSExprs>[<n>-1] = ReductionOperation<n>-1(*<LHSExprs>[<n>-1], *<RHSExprs>[<n>-1]);
  __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
  break;
case 2:
  Atomic(<LHSExprs>[0] = ReductionOperation0(*<LHSExprs>[0], *<RHSExprs>[0]));
  ...
  Atomic(<LHSExprs>[<n>-1] = ReductionOperation<n>-1(*<LHSExprs>[<n>-1], *<RHSExprs>[<n>-1]));
  break;
default:;
}
Reduction variables are a kind of a private variables, they have private copies, but initial values are chosen in accordance with the reduction operation.
If sections directive has only single section, then original shared variables are used instead with barrier at the end of the directive.
Differential Revision: http://reviews.llvm.org/D9242



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@235835 91177308-0d34-0410-b5e6-96231b3b80d8
2015-04-27 05:04:13 +00:00
Alexey Bataev 7b00e6cfc2 [OPENMP] Codegen for 'lastprivate' clause in 'sections' directive.
#pragma omp sections lastprivate(<var>)
<BODY>;
This construct is translated into something like:

<last_iter> = alloca i32
<init for lastprivates>;
<last_iter> = 0
; No initializer for simple variables or a default constructor is called for objects.
; For arrays perform element by element initialization by the call of the default constructor.
...
OMP_FOR_START(...,<last_iter>, ..); sets <last_iter> to 1 if this is the last iteration.
<BODY>
...
OMP_FOR_END
if (<last_iter> != 0) {
  <final copy for lastprivate>; Update original variable with the lastprivate value.
}
call __kmpc_cancel_barrier() ; an implicit barrier to avoid possible data race.
If there is only one section, there is no special code generation, original shared variables are used + barrier is emitted at the end of the directive.
Differential Revision: http://reviews.llvm.org/D9240


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@235834 91177308-0d34-0410-b5e6-96231b3b80d8
2015-04-27 04:34:03 +00:00
Alexey Bataev 47709fb992 [OPENMP] Codegen for 'private' clause in 'sections' directive.
If there are 2 or more sections in a 'section' directive the following code is generated:

<default init for privates>
@__kmpc_for_static_init_4();
<BODY for sections directive>
@__kmpc_for_static_fini()
If there is only one section, the following code is generated:

if (@__kmpc_single()) {
  <default init for privates>
  @__kmpc_end_single();
}
Differential Revision: http://reviews.llvm.org/D9239


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@235833 91177308-0d34-0410-b5e6-96231b3b80d8
2015-04-27 04:12:12 +00:00
Alexey Bataev f22d311eea [OPENMP] Codegen for 'private' clause in 'single' directive.
Emit the following code for 'single' directive with 'private' clause:

if (@__kmpc_single()) {
  <default init for privates>
  @__kmpc_end_single();
}
Differential Revision: http://reviews.llvm.org/D9238


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@235832 91177308-0d34-0410-b5e6-96231b3b80d8
2015-04-27 03:48:52 +00:00
Alexey Bataev e1bb920752 [OPENMP] Codegen for 'firstprivate' clause in 'single' directive.
Emit the following code for 'single' directive with 'firtstprivate' clause:

if (@__kmpc_single()) {
  <init for firstprivates>
  @__kmpc_end_single();
}
@__kmpc_cancel_barrier(); // To avoid data race in firstprivate init
Differential Revision: http://reviews.llvm.org/D9223


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@235694 91177308-0d34-0410-b5e6-96231b3b80d8
2015-04-24 04:21:15 +00:00
Alexey Bataev b44793c0f7 [OPENMP] Do not emit implicit barrier for single directive with 'copyprivate' clause(s).
Runtime function for 'copyprivate' directive generates implicit barriers, so no need to emit it.
Differential Revision: http://reviews.llvm.org/D9215


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@235692 91177308-0d34-0410-b5e6-96231b3b80d8
2015-04-24 04:00:39 +00:00
Alexey Bataev 8cd5527740 [OPENMP] Codegen for 'firstprivate' clause in 'sections' directive.
If there are 2 or more sections in a 'section' directive the following code is generated:

<init for firstprivates>
@__kmpc_cancel_barrier();// To avoid data race in firstprivate init
@__kmpc_for_static_init_4();
<BODY for sections directive>
@__kmpc_for_static_fini()
If there is only one section, the following code is generated:

if (@__kmpc_single()) {
  <init for firstprivates>
  @__kmpc_end_single();
}
@__kmpc_cancel_barrier(); // To avoid data race in firstprivate init
Differential Revision: http://reviews.llvm.org/D9214


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@235691 91177308-0d34-0410-b5e6-96231b3b80d8
2015-04-24 03:37:03 +00:00
Justin Bogner aa53a4f2ee InstrProf: Stop using RegionCounter outside of CodeGenPGO (NFC)
The RegionCounter type does a lot of legwork, but most of it is only
meaningful within the implementation of CodeGenPGO. The uses elsewhere
in CodeGen generally just want to increment or read counters, so do
that directly.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@235664 91177308-0d34-0410-b5e6-96231b3b80d8
2015-04-23 23:06:47 +00:00
Alexey Bataev 98cb5a7c84 [OPENMP] Codegen for 'atomic capture'.
Adds codegen for 'atomic capture' constructs with the following forms of expressions/statements:

v = x binop= expr;
v = x++;
v = ++x;
v = x--;
v = --x;
v = x = x binop expr;
v = x = expr binop x;
{v = x; x = binop= expr;}
{v = x; x++;}
{v = x; ++x;}
{v = x; x--;}
{v = x; --x;}
{x = x binop expr; v = x;}
{x binop= expr; v = x;}
{x++; v = x;}
{++x; v = x;}
{x--; v = x;}
{--x; v = x;}
{x = x binop expr; v = x;}
{x = expr binop x; v = x;}
{v = x; x = expr;}
If x and expr are integer and binop is associative or x is a LHS in a RHS of the assignment expression, and atomics are allowed for type of x on the target platform atomicrmw instruction is emitted.
Otherwise compare-and-swap sequence is emitted.
Update of 'v' is not required to be be atomic with respect to the read or write of the 'x'.

bb:
...
atomic load <x>
cont:
<expected> = phi [ <x>, label %bb ], [ <new_failed>, %cont ]
<desired> = <expected> binop <expr>
<res> = cmpxchg atomic &<x>, desired, expected
<new_failed> = <res>.field1;
br <res>field2, label %exit, label %cont
exit:
atomic store <old/new x>, <v>
...
Differential Revision: http://reviews.llvm.org/D9049


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@235573 91177308-0d34-0410-b5e6-96231b3b80d8
2015-04-23 06:35:10 +00:00
Alexey Bataev 16029dac5f [OPENMP] Codegen for 'if' clause in 'task' directive.
If condition evaluates to true, the code executes task by calling @__kmpc_omp_task() runtime function.
If condition evaluates to false, the code executes serial version of the code by executing the following code:

call void @__kmpc_omp_task_begin_if0(<loc>, <threadid>, <task_t_ptr, returned by @__kmpc_omp_task_alloc()>);
proxy_task_entry(<gtid>, <task_t_ptr, returned by @__kmpc_omp_task_alloc()>);
call void @__kmpc_omp_task_complete_if0(<loc>, <threadid>, <task_t_ptr, returned by @__kmpc_omp_task_alloc()>);
Also it checks if the condition is constant and if it is constant it evaluates its value and then generates either parallel version of the code (if the condition evaluates to true), or the serial version of the code (if the condition evaluates to false).
Differential Revision: http://reviews.llvm.org/D9143


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@235507 91177308-0d34-0410-b5e6-96231b3b80d8
2015-04-22 13:57:31 +00:00
Alexey Bataev 7d7afee099 [OPENMP] Codegen for 'reduction' clause in 'for' directive.
Emit a code for reduction clause. Next code should be emitted for reductions:

static kmp_critical_name lock = { 0 };

void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
    *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]);
      ...
        *(Type<n>-1*)lhs[<n>-1] =
          ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1],
            *(Type<n>-1*)rhs[<n>-1]);
}

 ...
  void *RedList[<n>] = {&<RHSExprs>[0], ..., &<RHSExprs>[<n>-1]};
   switch (__kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>)) {
      case 1:
        <LHSExprs>[0] = ReductionOperation0(*<LHSExprs>[0], *<RHSExprs>[0]);
          ...
            <LHSExprs>[<n>-1] = ReductionOperation<n>-1(*<LHSExprs>[<n>-1], *<RHSExprs>[<n>-1]);
             __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
              break;
               case 2:
                 Atomic(<LHSExprs>[0] = ReductionOperation0(*<LHSExprs>[0], *<RHSExprs>[0]));
                   ...
                     Atomic(<LHSExprs>[<n>-1] = ReductionOperation<n>-1(*<LHSExprs>[<n>-1], *<RHSExprs>[<n>-1]));
                      break;
                       default:;
                        }
                        Reduction variables are a kind of a private variables, they have private copies, but initial values are chosen in accordance with the reduction operation.
Differential Revision: http://reviews.llvm.org/D9139


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@235506 91177308-0d34-0410-b5e6-96231b3b80d8
2015-04-22 13:43:03 +00:00
Alexey Bataev 45360e9df6 [OPENMP] Codegen for 'private' clause in 'for' directive.
This patch generates helper variables which used as a private copies of the corresponding original variables inside an OpenMP 'for' directive. These generated variables are initialized by default (with the default constructor, if any). In OpenMP region references to original variables are replaced by the references to these private helper variables.
Differential Revision: http://reviews.llvm.org/D9106


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@235503 91177308-0d34-0410-b5e6-96231b3b80d8
2015-04-22 12:24:45 +00:00
Alexey Bataev a7d758fea5 [OPENMP] Fix use of unsigned counters in loops with zero trip count.
Patch fixes bugs in codegen for loops with unsigned counters and zero trip count. Previously preconditions for all loops were built using logic (Upper - Lower) > 0. But if the loop is a loop with zero trip count, then Upper - Lower is < 0 only for signed integer, for unsigned we're running into an underflow situation.
In this patch we're using original Lower<Upper condition to check that loop body can be executed at least once. Also this allows to skip code generation for loops, if it is known that preconditions for the loop are always false.
Differential Revision: http://reviews.llvm.org/D9103


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@235500 91177308-0d34-0410-b5e6-96231b3b80d8
2015-04-22 11:59:37 +00:00
Alexey Bataev b3a8f2f537 [OPENMP] Codegen for 'ordered' directive.
Add codegen for 'ordered' directive:

__kmpc_ordered(ident_t *, gtid);
<associated statement>;
__kmpc_end_ordered(ident_t *, gtid);
Also for 'for' directives with the dynamic scheduling and an 'ordered' clause added a call to '__kmpc_dispatch_fini_(4|8)[u]()' function after increment expression for loop control variable:

while(__kmpc_dispatch_next(&LB, &UB)) {
  idx = LB;
  while (idx <= UB) { BODY; ++idx;
    __kmpc_dispatch_fini_(4|8)[u](); // For ordered loops only.
  } // inner loop
}
Differential Revision: http://reviews.llvm.org/D9070


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@235496 91177308-0d34-0410-b5e6-96231b3b80d8
2015-04-22 11:15:40 +00:00
Benjamin Kramer 3750ce3e5b Make helper function static. NFC.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@235253 91177308-0d34-0410-b5e6-96231b3b80d8
2015-04-18 10:00:10 +00:00
Alexey Bataev 6ff3f69756 [OPENMP] Codegen for 'copyin' clause in 'parallel' directive.
Emits the following code for the clause at the beginning of the outlined function for implicit threads:

if (<not a master thread>) {
  ...
  <thread local copy of var> = <master thread local copy of var>;
  ...
}
<sync point>;
Checking for a non-master thread is performed by comparing of the address of the thread local variable with the address of the master's variable. Master thread always uses original variables, so you always know the address of the variable in the master thread.
Differential Revision: http://reviews.llvm.org/D9026


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@235075 91177308-0d34-0410-b5e6-96231b3b80d8
2015-04-16 05:39:01 +00:00
Alexey Bataev 5a78b2480c [OPENMP] Codegen for 'lastprivate' clause in 'for' directive.
#pragma omp for lastprivate(<var>)
for (i = a; i < b; ++b)
  <BODY>;

This construct is translated into something like:

  <last_iter> = alloca i32
  <lastprivate_var> = alloca <type>
  <last_iter> = 0
  ; No initializer for simple variables or a default constructor is called for objects.
  ; For arrays perform element by element initialization by the call of the default constructor.
  ...
  OMP_FOR_START(...,<last_iter>, ..); sets <last_iter> to 1 if this is the last iteration.
  <BODY>
  ...
  OMP_FOR_END
  if (<last_iter> != 0) {
    <var> = <lastprivate_var> ; Update original variable with the lastprivate value.
  }
  call __kmpc_cancel_barrier() ; an implicit barrier to avoid possible data race.

Differential Revision: http://reviews.llvm.org/D8658


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@235074 91177308-0d34-0410-b5e6-96231b3b80d8
2015-04-16 04:54:05 +00:00
Alexey Bataev 4fe8cb2873 [OPENMP] Codegen for 'firstprivate' clause in 'for' directive.
Adds proper codegen for 'firstprivate' clause in for directive. Initially codegen for 'firstprivate' clause was implemented for 'parallel' directive only.
Also this patch emits sync point only after initialization of firstprivate variables, not all private variables. This sync point is not required for privates, lastprivates etc., only for initialization of firstprivate variables.
Differential Revision: http://reviews.llvm.org/D8660


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@234978 91177308-0d34-0410-b5e6-96231b3b80d8
2015-04-15 04:52:20 +00:00
Alexey Bataev 36c516f1fa [OPENMP] Fixed codegen for arrays in 'copyprivate' clause.
Fixed a bug with codegen of variables with array types specified in 'copyprivate' clause of 'single' directive.
Differential Revision: http://reviews.llvm.org/D8914


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@234856 91177308-0d34-0410-b5e6-96231b3b80d8
2015-04-14 05:11:24 +00:00
Alexey Bataev eeb951c67e [OPENMP] Initial codegen for 'parallel sections' directive.
Emits code for outlined 'parallel' directive with the implicitly inlined 'sections' directive:

...
call __kmpc_fork_call(..., outlined_function, ...);
...

define internal void outlined_function(...) {
    <code for implicit sections directive>;
}
Differential Revision: http://reviews.llvm.org/D8997


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@234849 91177308-0d34-0410-b5e6-96231b3b80d8
2015-04-14 03:29:22 +00:00
Alexey Bataev e9435ceae7 [OPENMP] Initial codegen for 'parallel for' directive.
Allows generation of combined 'parallel for' directive that represents 'parallel' region with internal implicit 'for' worksharing region.
Differential Revision: http://reviews.llvm.org/D8631


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@234722 91177308-0d34-0410-b5e6-96231b3b80d8
2015-04-13 05:28:11 +00:00