Commit Graph

286 Commits

Author SHA1 Message Date
Alexey Bataev 0f34da12e4 [OPENMP 4.0] Codegen for 'cancellation point' directive.
The next code is generated for this construct:
```
if (__kmpc_cancellationpoint(ident_t *loc, kmp_int32 global_tid, kmp_int32 cncl_kind) != 0)
  <exit from outer innermost construct>;
```

llvm-svn: 241239
2015-07-02 04:17:07 +00:00
Alexey Bataev 0039651304 [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

llvm-svn: 241237
2015-07-02 03:40:19 +00:00
Alexey Bataev 6d4ed05830 [OPENMP 4.0] Initial support for 'omp cancellation point' construct.
Add parsing and sema analysis for 'omp cancellation point' directive.

llvm-svn: 241145
2015-07-01 06:57:41 +00:00
Alexey Bataev 1d2353d4f3 [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.

llvm-svn: 240532
2015-06-24 11:01:36 +00:00
Alexey Bataev 1c2cfbc3ea [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).

llvm-svn: 240409
2015-06-23 14:25:19 +00:00
Alexey Bataev 7f210c6dab [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)

llvm-svn: 240018
2015-06-18 13:40:03 +00:00
Alexey Bataev c30dd2daf9 [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);

llvm-svn: 240011
2015-06-18 12:14:09 +00:00
Alexey Bataev 3b5b5c492e [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.

llvm-svn: 240006
2015-06-18 10:10:12 +00:00
Alexey Bataev 58e5bdb091 [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.

llvm-svn: 239990
2015-06-18 04:45:29 +00:00
Alexey Bataev cbdcbb7690 [OPENMP] Code reformatting for omp simd codegen, NFC.
llvm-svn: 239889
2015-06-17 07:45:51 +00:00
Alexey Bataev 89e7e8eb0e [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;

llvm-svn: 239881
2015-06-17 06:21:39 +00:00
Alexey Bataev fc087ecc05 [OPENMP] Support lastprivate clause in omp simd directive.
Added codegen for lastprivate clauses within simd loop-based directives.

llvm-svn: 239813
2015-06-16 13:14:42 +00:00
Alexey Bataev ae05c29ab5 [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.

llvm-svn: 239810
2015-06-16 11:59:36 +00:00
Alexey Bataev 6e8248fdad [OPENMP] Fox for http://llvm.org/PR23663: OpenMP crash
Destroy RuntimeCleanupScope before generation of termination instruction in parallel loop precondition.

llvm-svn: 239524
2015-06-11 10:53:56 +00:00
Alexey Bataev 3ae88e2124 [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);
}

llvm-svn: 238010
2015-05-22 08:56:35 +00:00
Alexey Bataev 5129d3a4f5 [OPENMP] Fixed codegen for parameters privatization.
For parameters we shall take a derived type of parameters, not the original one.

llvm-svn: 237882
2015-05-21 09:47:46 +00:00
Alexey Bataev 7a228ff439 [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.

llvm-svn: 237879
2015-05-21 07:59:51 +00:00
Alexey Bataev d7589ffe1d [OPENMP] Fix codegen for ordered loop directives.
loops with ordered clause must be generated the same way as dynamic loops, but with static scheduleing.

llvm-svn: 237788
2015-05-20 13:12:48 +00:00
Alexey Bataev 1d9c15cf18 [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.

llvm-svn: 237691
2015-05-19 12:31:28 +00:00
Alexey Bataev d130fd17f1 [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.

llvm-svn: 237243
2015-05-13 10:23:02 +00:00
Alexey Bataev 040d540940 [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.

llvm-svn: 237100
2015-05-12 08:35:28 +00:00
Alexey Bataev 9d541a72e8 [OPENMP] Fixed atomic construct with non-integer expressions.
Do not emit 'atomicrmw' instruction for simple atomic constructs with non-integer expressions.

llvm-svn: 236828
2015-05-08 11:47:16 +00:00
Alexey Bataev 39f915b8f4 [OPENMP] Code cleanup for capturing of variables in OpenMP regions.
llvm-svn: 236821
2015-05-08 10:41:21 +00:00
Alexey Bataev 53223c986c [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

llvm-svn: 236693
2015-05-07 04:25:17 +00:00
Alexey Bataev 9e03404d8d [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

llvm-svn: 236479
2015-05-05 04:05:12 +00:00
Benjamin Kramer 439ee9d7bc Make helper functions static. NFC.
llvm-svn: 236315
2015-05-01 13:59:53 +00:00
Alexey Bataev 36c1eb95e0 [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

llvm-svn: 236207
2015-04-30 06:51:57 +00:00
Alexey Bataev 6111469a4a [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.

llvm-svn: 235985
2015-04-28 13:20:05 +00:00
Alexey Bataev c925aa3ab8 [OPENMP] Simplified iteration over clauses, NFC.
llvm-svn: 235838
2015-04-27 08:00:32 +00:00
Alexey Bataev 8b8e202a33 [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

llvm-svn: 235836
2015-04-27 05:22:09 +00:00
Alexey Bataev a89adf22db [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

llvm-svn: 235835
2015-04-27 05:04:13 +00:00
Alexey Bataev 9efc03b6f7 [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

llvm-svn: 235834
2015-04-27 04:34:03 +00:00
Alexey Bataev 7387083d95 [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

llvm-svn: 235833
2015-04-27 04:12:12 +00:00
Alexey Bataev 59c654aa43 [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

llvm-svn: 235832
2015-04-27 03:48:52 +00:00
Alexey Bataev 5521d78532 [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

llvm-svn: 235694
2015-04-24 04:21:15 +00:00
Alexey Bataev 8b72566eec [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

llvm-svn: 235692
2015-04-24 04:00:39 +00:00
Alexey Bataev 2cb9b95adf [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

llvm-svn: 235691
2015-04-24 03:37:03 +00:00
Justin Bogner 66242d6c5e 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.

llvm-svn: 235664
2015-04-23 23:06:47 +00:00
Alexey Bataev 5e018f9e29 [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

llvm-svn: 235573
2015-04-23 06:35:10 +00:00
Alexey Bataev 1d67713b44 [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

llvm-svn: 235507
2015-04-22 13:57:31 +00:00
Alexey Bataev 7ebe5fddac [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

llvm-svn: 235506
2015-04-22 13:43:03 +00:00
Alexey Bataev 50a6458870 [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

llvm-svn: 235503
2015-04-22 12:24:45 +00:00
Alexey Bataev 62dbb979c0 [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

llvm-svn: 235500
2015-04-22 11:59:37 +00:00
Alexey Bataev 98eb6e3d41 [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

llvm-svn: 235496
2015-04-22 11:15:40 +00:00
Benjamin Kramer 5df7c1a4eb Make helper function static. NFC.
llvm-svn: 235253
2015-04-18 10:00:10 +00:00
Alexey Bataev f56f98c925 [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

llvm-svn: 235075
2015-04-16 05:39:01 +00:00
Alexey Bataev 38e8953352 [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

llvm-svn: 235074
2015-04-16 04:54:05 +00:00
Alexey Bataev 69c62a9bdb [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

llvm-svn: 234978
2015-04-15 04:52:20 +00:00
Alexey Bataev 420d45b2dd [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

llvm-svn: 234856
2015-04-14 05:11:24 +00:00
Alexey Bataev 68adb7da1a [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

llvm-svn: 234849
2015-04-14 03:29:22 +00:00
Alexey Bataev 671605e85b [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

llvm-svn: 234722
2015-04-13 05:28:11 +00:00
Alexey Bataev 794ba0dcb7 [OPENMP] Codegen for 'reduction' clause in 'parallel' 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>]) {
  ...
  *(Type<i> *)lhs[i] = RedOp<i>(*(Type<i> *)lhs[i], *(Type<i> *)rhs[i]);
  ...
}

... void *RedList[<n>] = {&<RHSExprs>[0], ..., &<RHSExprs>[<n> - 1]};
switch (__kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList), RedList, reduce_func, &<lock>)) {
case 1:
  ...
  <LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
  ...
  __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
  break;
case 2:
  ...
  Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]));
  ...
  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/D8915

llvm-svn: 234583
2015-04-10 10:43:45 +00:00
Alexey Bataev 6f1ffc069b [OPENMP] Refactoring of codegen for OpenMP directives.
Refactored API of OpenMPRuntime for compatibility with combined directives.
Differential Revision: http://reviews.llvm.org/D8859

llvm-svn: 234564
2015-04-10 04:50:10 +00:00
Alexey Bataev b4505a7229 [OPENMP] Codegen for 'atomic update' construct.
Adds atomic update codegen for the following forms of expressions:

x binop= expr;
x++;
++x;
x--;
--x;
x = x binop expr;
x = expr binop x;
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:

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:
...

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

llvm-svn: 233513
2015-03-30 05:20:59 +00:00
Alexey Bataev f268568447 [OPENMP] Improved codegen for implicit/explicit 'barrier' constructs.
Replace boolean IsExplicit parameter of OpenMPRuntime::emitBarrierCall() method by OpenMPDirectiveKind Kind for better compatibility with the runtime library. Also add processing of 'nowait' clause on worksharing directives.
Differential Revision: http://reviews.llvm.org/D8659

llvm-svn: 233511
2015-03-30 04:30:22 +00:00
Alexey Bataev a63048e4fd [OPENMP] Codegen for 'copyprivate' clause ('single' directive).
If there is at least one 'copyprivate' clause is associated with the single directive, the following code is generated:

```
i32 did_it = 0;                                  \\ for 'copyprivate' clause
if(__kmpc_single(ident_t *, gtid)) {
  SingleOpGen();
  __kmpc_end_single(ident_t *, gtid);
  did_it = 1;                                    \\ for 'copyprivate' clause
}
<copyprivate_list>[0] = &var0;
...
<copyprivate_list>[n] = &varn;
call __kmpc_copyprivate(ident_t *, gtid, <copyprivate_list_size>,
                        <copyprivate_list>, <copy_func>, did_it);

...

void<copy_func>(void *LHSArg, void *RHSArg) {
  Dst = (void * [n])(LHSArg);
  Src = (void * [n])(RHSArg);
  Dst[0] = Src[0];
  ... Dst[n] = Src[n];
}
```
All list items from all 'copyprivate' clauses are gathered into single <copyprivate list> (<copyprivate_list_size> is a size in bytes of this list) and <copy_func> is used to propagate values of private or threadprivate variables from the 'single' region to other implicit threads from outer 'parallel' region.
Differential Revision: http://reviews.llvm.org/D8410

llvm-svn: 232932
2015-03-23 06:18:07 +00:00
Alexander Musman 3276a27b5c [OPENMP] CodeGen of the 'linear' clause for the 'omp simd' directive.
The linear variable is privatized (similar to 'private') and its
value on current iteration is calculated, similar to the loop
counter variables.
Differential revision: http://reviews.llvm.org/D8375

llvm-svn: 232890
2015-03-21 10:12:56 +00:00
Alexander Musman 7931b98735 [OPENMP] Enable codegen of the ‘private’ clause for ‘omp simd’ directive
llvm-svn: 232353
2015-03-16 07:14:41 +00:00
Alexander Musman 92bdaabf97 [OPENMP] CodeGen - 'omp for' with dynamic schedule kinds.
Differential Revision: http://reviews.llvm.org/D7138

llvm-svn: 232036
2015-03-12 13:37:50 +00:00
Alexey Bataev 2df54a07bf [OPENMP] Initial codegen for 'omp sections' and 'omp section' directives.
If only one section is found in the sections region, it is emitted just like single region.
Otherwise it is emitted as a static non-chunked loop.

#pragma omp sections
{
#pragma omp section
  {1}
  ...
  #pragma omp section
  {n}
}
is translated to something like

i32 <iter_var>
i32 <last_iter> = 0
i32 <lower_bound> = 0
i32 <upper_bound> = n-1
i32 <stride> = 1
call void @__kmpc_for_static_init_4(<loc>, i32 <gtid>, i32 34/*static non-chunked*/, i32* <last_iter>, i32* <lower_bound>, i32* <upper_bound>, i32* <stride>, i32 1/*increment always 1*/, i32 1/*chunk always 1*/)
<upper_bound> = min(<upper_bound>, n-1)
<iter_var> = <lb>
check:
br <iter_var> <= <upper_bound>, label cont, label exit
continue:
switch (IV) {
  case 0:
  {1};
  break;
  ...
  case <NumSection> - 1:
  {n};
  break;
  }
  ++<iter_var>
  br label check
  exit:
  call void @__kmpc_for_static_fini(<loc>, i32 <gtid>)
Differential Revision: http://reviews.llvm.org/D8244

llvm-svn: 232021
2015-03-12 08:53:29 +00:00
Alexey Bataev 10fec57e5a [OPENMP] Fix for ExprWithCleanups in 'omp atomic' constructs.
This patch allows using of ExprWithCleanups expressions and other complex expressions in 'omp atomic' construct
Differential Revision: http://reviews.llvm.org/D8200

llvm-svn: 231905
2015-03-11 04:48:56 +00:00
Alexey Bataev 62b63b197d [OPENMP] Initial codegen for 'omp task' directive.
The task region is emmitted in several steps:

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;
}
Copy a list of shared variables to field shareds of the resulting structure kmp_task_t returned by the previous call (if any).
Copy a pointer to destructions function to field destructions of the resulting structure kmp_task_t.
Emit a call to kmp_int32 __kmpc_omp_task(ident_t *, kmp_int32 gtid, kmp_task_t *new_task), where new_task is a resulting structure from previous items.
Differential Revision: http://reviews.llvm.org/D7560

llvm-svn: 231762
2015-03-10 07:28:44 +00:00
Alexey Bataev 36bf011e83 [OPENMP] Improved code for generating debug info + generation of all OpenMP regions in termination scope
Patch adds proper generation of debug info for all OpenMP regions. Also, all OpenMP regions are generated in a termination scope, because standard does not allow to throw exceptions out of structured blocks, associated with the OpenMP regions
Differential Revision: http://reviews.llvm.org/D7935

llvm-svn: 231757
2015-03-10 05:15:26 +00:00
Rafael Espindola eb26ddf559 Revert "[OPENMP] Improved code for generating debug info + generation of all OpenMP regions in termination scope Patch adds proper generation of debug info for all OpenMP regions. Also, all OpenMP regions are generated in a termination scope, because standard does not allow to throw exceptions out of structured blocks, associated with the OpenMP regions Differential Revision: http://reviews.llvm.org/D7935"
This reverts commit r231752.

It was failing to link with cmake:

lib64/libclangCodeGen.a(CGOpenMPRuntime.cpp.o):/home/espindola/llvm/llvm/tools/clang/lib/CodeGen/CGOpenMPRuntime.cpp:function clang::CodeGen::InlinedOpenMPRegionRAII::~InlinedOpenMPRegionRAII(): error: undefined reference to 'clang::CodeGen::EHScopeStack::popTerminate()'
clang-3.7: error: linker command failed with exit code 1 (use -v to see invocation)

llvm-svn: 231754
2015-03-10 04:40:21 +00:00
Alexey Bataev 7ab2cc178f [OPENMP] Improved code for generating debug info + generation of all OpenMP regions in termination scope
Patch adds proper generation of debug info for all OpenMP regions. Also, all OpenMP regions are generated in a termination scope, because standard does not allow to throw exceptions out of structured blocks, associated with the OpenMP regions
Differential Revision: http://reviews.llvm.org/D7935

llvm-svn: 231752
2015-03-10 04:22:11 +00:00
Alexey Bataev b832926176 [OPENMP] Codegen for "#pragma omp atomic write"
For global reg lvalue - use regular store through global register.
For simple lvalue - use simple atomic store.
For bitfields, vector element, extended vector elements - the original value of the whole storage (for vector elements) or of some aligned value (for bitfields) is atomically read, the part of this value for the given lvalue is modified and then use atomic compare-and-exchange operation to try to atomically write modified value (if it was not modified).
Also, changes in this patch fix the bug for '#pragma omp atomic read' applied to extended vector elements.
Differential Revision: http://reviews.llvm.org/D7369

llvm-svn: 230736
2015-02-27 06:33:30 +00:00
Alexey Bataev 8cbe0a6b62 [OPENMP] Fixed codegen for directives without function outlining.
Fixed crash on codegen for directives like 'omp for', 'omp single' etc. inside of the 'omp parallel', 'omp task' etc. regions.

llvm-svn: 230621
2015-02-26 10:27:34 +00:00
Alexey Bataev 3eff5f46d7 [OPENMP] Rename methods of OpenMPRuntime class. NFC.
llvm-svn: 230470
2015-02-25 08:32:46 +00:00
David Majnemer a5b195a1dc Revert "Revert r229082 for a bit, it caused PR22577."
This reverts commit r229123.  It was a red herring, the bug was present
without r229082.

llvm-svn: 229205
2015-02-14 01:35:12 +00:00
Nico Weber 7ce96b853d Revert r229082 for a bit, it caused PR22577.
llvm-svn: 229123
2015-02-13 16:27:00 +00:00
David Majnemer abc482effc MS ABI: Implement /volatile:ms
The /volatile:ms semantics turn volatile loads and stores into atomic
acquire and release operations.  This distinction is important because
volatile memory operations do not form a happens-before relationship
with non-atomic memory.  This means that a volatile store is not
sufficient for implementing a mutex unlock routine.

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

llvm-svn: 229082
2015-02-13 07:55:47 +00:00
Alexey Bataev 6956e2e683 [OPENMP] Initial codegen for 'single' directive.
This patch emits the following code for the single directive:

#pragma omp single
<body>
<---->

if(__kmpc_single(...)) {
    <body>
      __kmpc_end_single(...);
}
Differential Revision: http://reviews.llvm.org/D7045

llvm-svn: 228275
2015-02-05 06:35:41 +00:00
Alexey Bataev 9f797f32e2 [OPENMP] Codegen for 'taskyield' directive
For 'taskyield' directive emit call to kmp_int32 __kmpc_omp_taskyield(ident_t *,
kmp_int32 global_tid, int end_part); runtime function call with end_part arg set
to 0 (it is ignored).
Differential Revision: http://reviews.llvm.org/D7047

llvm-svn: 228272
2015-02-05 05:57:51 +00:00
Adrian Prantl 95b24e9b59 Address review feedback for r228003.
- use named constructors
- get rid of MarkAsPrologue

llvm-svn: 228021
2015-02-03 20:00:54 +00:00
Adrian Prantl 39428e74a0 Merge ArtificialLocation into ApplyDebugLocation and make a clear
distinction between the different use-cases. With the previous default
behavior we would occasionally emit empty debug locations in situations
where they actually were strictly required (= on invoke insns).
We now have a choice between defaulting to an empty location or an
artificial location.

Specifically, this fixes a bug caused by a missing debug location when
emitting C++ EH cleanup blocks from within an artificial function, such as
an ObjC destroy helper function.

rdar://problem/19670595

llvm-svn: 228003
2015-02-03 18:40:42 +00:00
Alexander Musman df7a8e2bc8 Support ‘omp for’ with static chunked schedule kind.
Differential Revision: http://reviews.llvm.org/D7006

llvm-svn: 226795
2015-01-22 08:49:35 +00:00
Alexey Bataev b57056f483 [OPENMP] CodeGen for "omp atomic read [seq_cst]" directive.
"omp atomic read [seq_cst]" accepts expressions "v=x;". In this patch we perform
an atomic load of "x" (using builtin atomic loading instructions or a call to
"atomic_load()" for simple lvalues and "kmpc_atomic_start();load
<x>;kmpc_atomic_end();" for other lvalues), convert the result of loading to
type of "v" (using EmitScalarConversion() for simple types and
EmitComplexToScalarConversion() for conversions from complex to scalar) and then
store the result in "v".)
Differential Revision: http://reviews.llvm.org/D6431

llvm-svn: 226788
2015-01-22 06:17:56 +00:00
Alexey Bataev 02e1ec6966 Revert commit revision 226786
Need to add initialization of AtomicInfo::EvaluationKind field

llvm-svn: 226787
2015-01-22 06:09:48 +00:00
Alexey Bataev 92efdce503 [OPENMP] CodeGen for "omp atomic read [seq_cst]" directive.
"omp atomic read [seq_cst]" accepts expressions "v=x;". In this patch we perform
an atomic load of "x" (using builtin atomic loading instructions or a call to
"atomic_load()" for simple lvalues and "kmpc_atomic_start();load
<x>;kmpc_atomic_end();" for other lvalues), convert the result of loading to
type of "v" (using EmitScalarConversion() for simple types and
EmitComplexToScalarConversion() for conversions from complex to scalar) and then
store the result in "v".)
Differential Revision: http://reviews.llvm.org/D6431

llvm-svn: 226786
2015-01-22 05:44:37 +00:00
Alexey Bataev 137421c8a9 Revert commit r226784.
Accidentally modified file SemaType.cpp must be restored to its original state. 

llvm-svn: 226785
2015-01-22 05:35:53 +00:00
Alexey Bataev 13c7c4930c [OPENMP] CodeGen for "omp atomic read [seq_cst]" directive.
"omp atomic read [seq_cst]" accepts expressions "v=x;". In this patch we perform
an atomic load of "x" (using builtin atomic loading instructions or a call to
"atomic_load()" for simple lvalues and "kmpc_atomic_start();load
<x>;kmpc_atomic_end();" for other lvalues), convert the result of loading to
type of "v" (using EmitScalarConversion() for simple types and
EmitComplexToScalarConversion() for conversions from complex to scalar) and then
store the result in "v".
Differential Revision: http://reviews.llvm.org/D6431

llvm-svn: 226784
2015-01-22 05:29:28 +00:00
Chandler Carruth 0d9593ddec [cleanup] Re-sort *all* #include lines with llvm/utils/sort_includes.py
Sorry for the noise, I managed to miss a bunch of recent regressions of
include orderings here. This should actually sort all the includes for
Clang. Again, no functionality changed, this is just a mechanical
cleanup that I try to run periodically to keep the #include lines as
regular as possible across the project.

llvm-svn: 225979
2015-01-14 11:29:14 +00:00
David Blaikie 66e4197f07 Reapply r225000 (reverted in r225555): DebugInfo: Generalize debug info location handling (and follow-up commits).
Several pieces of code were relying on implicit debug location setting
which usually lead to incorrect line information anyway. So I've fixed
those (in r225955 and r225845) separately which should pave the way for
this commit to be cleanly reapplied.

The reason these implicit dependencies resulted in crashes with this
patch is that the debug location would no longer implicitly leak from
one place to another, but be set back to invalid. Once a call with
no/invalid location was emitted, if that call was ever inlined it could
produce invalid debugloc chains and assert during LLVM's codegen.

There may be further cases of such bugs in this patch - they're hard to
flush out with regression testing, so I'll keep an eye out for reports
and investigate/fix them ASAP if they come up.

Original commit message:

Reapply "DebugInfo: Generalize debug info location handling"

Originally committed in r224385 and reverted in r224441 due to concerns
this change might've introduced a crash. Turns out this change fixes the
crash introduced by one of my earlier more specific location handling
changes (those specific fixes are reverted by this patch, in favor of
the more general solution).

Recommitted in r224941 and reverted in r224970 after it caused a crash
when building compiler-rt. Looks to be due to this change zeroing out
the debug location when emitting default arguments (which were meant to
inherit their outer expression's location) thus creating call
instructions without locations - these create problems for inlining and
must not be created. That is fixed and tested in this version of the
change.

Original commit message:

This is a more scalable (fixed in mostly one place, rather than many
places that will need constant improvement/maintenance) solution to
several commits I've made recently to increase source fidelity for
subexpressions.

This resetting had to be done at the DebugLoc level (not the
SourceLocation level) to preserve scoping information (if the resetting
was done with CGDebugInfo::EmitLocation, it would've caused the tail end
of an expression's codegen to end up in a potentially different scope
than the start, even though it was at the same source location). The
drawback to this is that it might leave CGDebugInfo out of sync. Ideally
CGDebugInfo shouldn't have a duplicate sense of the current
SourceLocation, but for now it seems it does... - I don't think I'm
going to tackle removing that just now.

I expect this'll probably cause some more buildbot fallout & I'll
investigate that as it comes up.

Also these sort of improvements might be starting to show a weakness/bug
in LLVM's line table handling: we don't correctly emit is_stmt for
statements, we just put it on every line table entry. This means one
statement split over multiple lines appears as multiple 'statements' and
two statements on one line (without column info) are treated as one
statement.

I don't think we have any IR representation of statements that would
help us distinguish these cases and identify the beginning of each
statement - so that might be something we need to add (possibly to the
lexical scope chain - a scope for each statement). This does cause some
problems for GDB and possibly other DWARF consumers.

llvm-svn: 225956
2015-01-14 07:38:27 +00:00
David Blaikie f353d3ecd0 Revert "DebugInfo: Generalize debug info location handling" and related commits
This reverts commit r225000, r225021, r225083, r225086, r225090.

The root change (r225000) still has several issues where it's caused
calls to be emitted without debug locations. This causes assertion
failures if/when those calls are inlined.

I'll work up some test cases and fixes before recommitting this.

llvm-svn: 225555
2015-01-09 23:00:28 +00:00
David Blaikie 84fe79cfc3 Reapply "DebugInfo: Generalize debug info location handling"
Originally committed in r224385 and reverted in r224441 due to concerns
this change might've introduced a crash. Turns out this change fixes the
crash introduced by one of my earlier more specific location handling
changes (those specific fixes are reverted by this patch, in favor of
the more general solution).

Recommitted in r224941 and reverted in r224970 after it caused a crash
when building compiler-rt. Looks to be due to this change zeroing out
the debug location when emitting default arguments (which were meant to
inherit their outer expression's location) thus creating call
instructions without locations - these create problems for inlining and
must not be created. That is fixed and tested in this version of the
change.

Original commit message:

This is a more scalable (fixed in mostly one place, rather than many
places that will need constant improvement/maintenance) solution to
several commits I've made recently to increase source fidelity for
subexpressions.

This resetting had to be done at the DebugLoc level (not the
SourceLocation level) to preserve scoping information (if the resetting
was done with CGDebugInfo::EmitLocation, it would've caused the tail end
of an expression's codegen to end up in a potentially different scope
than the start, even though it was at the same source location). The
drawback to this is that it might leave CGDebugInfo out of sync. Ideally
CGDebugInfo shouldn't have a duplicate sense of the current
SourceLocation, but for now it seems it does... - I don't think I'm
going to tackle removing that just now.

I expect this'll probably cause some more buildbot fallout & I'll
investigate that as it comes up.

Also these sort of improvements might be starting to show a weakness/bug
in LLVM's line table handling: we don't correctly emit is_stmt for
statements, we just put it on every line table entry. This means one
statement split over multiple lines appears as multiple 'statements' and
two statements on one line (without column info) are treated as one
statement.

I don't think we have any IR representation of statements that would
help us distinguish these cases and identify the beginning of each
statement - so that might be something we need to add (possibly to the
lexical scope chain - a scope for each statement). This does cause some
problems for GDB and possibly other DWARF consumers.

llvm-svn: 225000
2014-12-30 19:39:33 +00:00
David Blaikie 608a24501c Revert "DebugInfo: Generalize debug info location handling"
Asserting when building compiler-rt when using a GCC host compiler.
Reverting while I investigate.

This reverts commit r224941.

llvm-svn: 224970
2014-12-29 23:49:00 +00:00
David Blaikie 3945d1bd99 Reapply "DebugInfo: Generalize debug info location handling"
Originally committed in r224385 and reverted in r224441 due to concerns
this change might've introduced a crash. Turns out this change fixes the
crash introduced by one of my earlier more specific location handling
changes (those specific fixes are reverted by this patch, in favor of
the more general solution).

Original commit message:

This is a more scalable (fixed in mostly one place, rather than many
places that will need constant improvement/maintenance) solution to
several commits I've made recently to increase source fidelity for
subexpressions.

This resetting had to be done at the DebugLoc level (not the
SourceLocation level) to preserve scoping information (if the resetting
was done with CGDebugInfo::EmitLocation, it would've caused the tail end
of an expression's codegen to end up in a potentially different scope
than the start, even though it was at the same source location). The
drawback to this is that it might leave CGDebugInfo out of sync. Ideally
CGDebugInfo shouldn't have a duplicate sense of the current
SourceLocation, but for now it seems it does... - I don't think I'm
going to tackle removing that just now.

I expect this'll probably cause some more buildbot fallout & I'll
investigate that as it comes up.

Also these sort of improvements might be starting to show a weakness/bug
in LLVM's line table handling: we don't correctly emit is_stmt for
statements, we just put it on every line table entry. This means one
statement split over multiple lines appears as multiple 'statements' and
two statements on one line (without column info) are treated as one
statement.

I don't think we have any IR representation of statements that would
help us distinguish these cases and identify the beginning of each
statement - so that might be something we need to add (possibly to the
lexical scope chain - a scope for each statement). This does cause some
problems for GDB and possibly other DWARF consumers.

llvm-svn: 224941
2014-12-29 18:18:45 +00:00
David Blaikie 06b2c54db9 Revert "DebugInfo: Generalize debug info location handling"
Fails an ASan bootstrap - I'll try to reproduce locally & sort that out
before recommitting.

This reverts commit r224385.

llvm-svn: 224441
2014-12-17 18:02:04 +00:00
David Blaikie bf22a4eaee DebugInfo: Generalize debug info location handling
This is a more scalable (fixed in mostly one place, rather than many
places that will need constant improvement/maintenance) solution to
several commits I've made recently to increase source fidelity for
subexpressions.

This resetting had to be done at the DebugLoc level (not the
SourceLocation level) to preserve scoping information (if the resetting
was done with CGDebugInfo::EmitLocation, it would've caused the tail end
of an expression's codegen to end up in a potentially different scope
than the start, even though it was at the same source location). The
drawback to this is that it might leave CGDebugInfo out of sync. Ideally
CGDebugInfo shouldn't have a duplicate sense of the current
SourceLocation, but for now it seems it does... - I don't think I'm
going to tackle removing that just now.

I expect this'll probably cause some more buildbot fallout & I'll
investigate that as it comes up.

Also these sort of improvements might be starting to show a weakness/bug
in LLVM's line table handling: we don't correctly emit is_stmt for
statements, we just put it on every line table entry. This means one
statement split over multiple lines appears as multiple 'statements' and
two statements on one line (without column info) are treated as one
statement.

I don't think we have any IR representation of statements that would
help us distinguish these cases and identify the beginning of each
statement - so that might be something we need to add (possibly to the
lexical scope chain - a scope for each statement). This does cause some
problems for GDB and possibly other DWARF consumers.

llvm-svn: 224385
2014-12-16 22:49:17 +00:00
Alexey Bataev f841bd9fcd [OPENMP] Bugfix for processing of global variables in OpenMP regions.
Currently, if global variable is marked as a private OpenMP variable, the compiler crashes in debug version or generates incorrect code in release version. It happens because in the OpenMP region the original global variable is used instead of the generated private copy. It happens because currently globals variables are not captured in the OpenMP region.
This patch adds capturing of global variables iff private copy of the global variable must be used in the OpenMP region.
Differential Revision: http://reviews.llvm.org/D6259

llvm-svn: 224323
2014-12-16 07:00:22 +00:00
Alexander Musman c638868bdf First patch with codegen of the 'omp for' directive. It implements
the simplest case, which is used when no chunk_size is specified in
the schedule(static) or no 'schedule' clause is specified - the
iteration space is divided by the library into chunks that are
approximately equal in size, and at most one chunk is distributed
to each thread. In this case, we do not need an outer loop in each
thread - each thread requests once which iterations range it should
handle (using __kmpc_for_static_init runtime call) and then runs the
inner loop on this range.

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

llvm-svn: 224233
2014-12-15 07:07:06 +00:00
Alexey Bataev 8f7c1b0b9d [OPENMP] Codegen for 'omp barrier' directive.
Adds generation of call to "i32 kmpc_cancel_barrier(ident_t *, i32)" libcall for explicitly specified barriers (OMP_IDENT_BARRIER_EXPL flag is added to "flags" field of "ident_t" structure).
Also this patch replaces all calls to "kmpc_barrier" function by calls of "__kmpc_cancel_barrier" function which provides additional functionality for OpenMP 4.0.
Also, library specific enum OpenMPLocationFlags moved to private section of CGOpenMPRuntime class to make it more independent from library implementation.
Differential Revision: http://reviews.llvm.org/D6447

llvm-svn: 223444
2014-12-05 04:09:23 +00:00
Alexey Bataev 8d690650e8 [OPENMP] Codegen for 'omp master' directive
Patch adds 2 library functions to OpenMPRuntime class - int32 kmpc_master(ident_t *, int32 gtid) and void kmpc_end_master(ident_t *, int32 gtid);
For 'omp master' directive the next code is generated:

if (__kmpc_master(loc, gtid)) {
    <Associated structured block>;
      __kmpc_end_master(log, gtid);
}

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

llvm-svn: 223342
2014-12-04 07:23:53 +00:00
Alexey Bataev 75ddfabed7 [OPENMP] Formating and code improvement for codegen of 'omp critical' directive.
No functional changes, only code improvements.

llvm-svn: 223010
2014-12-01 11:32:38 +00:00
Alexey Bataev cc37cc1db2 [OPENMP] Codegen for "omp flush" directive.
For each "omp flush" directive a call to "void kmpc_flush(ident_t *, ...)" function is generated.
Directive "omp flush" may have an associated list of variables to flush, but currently runtime function ignores them. So the patch generates just "call kmpc_flush(ident_t *<loc>, i32 0)".
Differential Revision: http://reviews.llvm.org/D6292

llvm-svn: 222409
2014-11-20 04:34:54 +00:00
Alexey Bataev 03b340a3a5 [OPENMP] Codegen for 'private' clause in 'parallel' directive.
This patch generates some helper variables which used as a private copies of the corresponding original variables inside an OpenMP 'parallel' directive. These generated variables are initialized by default (with the default constructor, if any). In outlined function references to original variables are replaced by the references to these private helper variables. At the end of the initialization of the private variables and implicit barier is set by calling __kmpc_barrier(...) runtime function to be sure that all threads were initialized using original values of the variables.
Differential Revision: http://reviews.llvm.org/D4752

llvm-svn: 220262
2014-10-21 03:16:40 +00:00
Alexey Bataev b205978100 [OPENMP] Codegen for 'num_threads' clause in 'parallel' directive.
This patch generates call to "kmpc_push_num_threads(ident_t *loc, kmp_int32 global_tid, kmp_int32 num_threads);" library function before calling "kmpc_fork_call" each time there is an associated "num_threads" clause in the "omp parallel" directive.
Differential Revision: http://reviews.llvm.org/D5145

llvm-svn: 219599
2014-10-13 08:23:51 +00:00
Alexey Bataev d74d060d6d [OPENMP] Codegen for 'if' clause in 'parallel' directive.
Adds codegen for 'if' clause. Currently only for 'if' clause used with the 'parallel' directive.
If condition evaluates to true, the code executes parallel version of the code by calling __kmpc_fork_call(loc, 1, microtask, captured_struct/*context*/), where loc - debug location, 1 - number of additional parameters after "microtask" argument, microtask - is outlined finction for the code associated with the 'parallel' directive, captured_struct - list of variables captured in this outlined function.
If condition evaluates to false, the code executes serial version of the code by executing the following code:

global_thread_id.addr = alloca i32
store i32 global_thread_id, global_thread_id.addr
zero.addr = alloca i32
store i32 0, zero.addr
kmpc_serialized_parallel(loc, global_thread_id);
microtask(global_thread_id.addr, zero.addr, captured_struct/*context*/);
kmpc_end_serialized_parallel(loc, global_thread_id);

Where loc - debug location, global_thread_id - global thread id, returned by __kmpc_global_thread_num() call or passed as a first parameter in microtask() call, global_thread_id.addr - address of the variable, where stored global_thread_id value, zero.addr - implicit bound thread id (should be set to 0 for serial call), microtask() and captured_struct are the same as in parallel call.

Also this patch 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/D4716

llvm-svn: 219597
2014-10-13 06:02:40 +00:00
Alexey Bataev 1809571c76 Code reformatting and improvement for OpenMP.
Moved CGOpenMPRegionInfo from CGOpenMPRuntime.h to CGOpenMPRuntime.cpp file and reworked the code for this change. Also added processing of ThreadID variable passed as an argument in outlined functions in parallel and task directives.

llvm-svn: 219490
2014-10-10 12:19:54 +00:00
Alexey Bataev 435ad7ba5e Code improvements in OpenMP CodeGen.
This patch makes class OMPPrivateScope a common class for all private variables. Reworked processing of firstprivate variables (now it is based on OMPPrivateScope too).

llvm-svn: 219486
2014-10-10 09:48:26 +00:00
Alexey Bataev 13314bf526 [OPENMP] 'omp teams' directive basic support.
Includes parsing and semantic analysis for 'omp teams' directive support from OpenMP 4.0. Adds additional analysis to 'omp target' directive with 'omp teams' directive.  

llvm-svn: 219385
2014-10-09 04:18:56 +00:00
Alexey Bataev 4a5bb772c3 [OPENMP] Codegen for 'firstprivate' clause.
This patch generates some helper variables that used as private copies of the corresponding original variables inside an OpenMP 'parallel' directive. These generated variables are initialized by copy using values of the original variables (with the copy constructor, if any). For arrays, initializator is generated for single element and in the codegen procedure this initial value is automatically propagated between all elements of the private copy.
In outlined function, references to original variables are replaced by the references to these private helper variables. At the end of the initialization of the private variables an implicit barier is generated by calling __kmpc_barrier(...) runtime function to be sure that all threads were initialized using original values of the variables.
Differential Revision: http://reviews.llvm.org/D5140

llvm-svn: 219306
2014-10-08 14:01:46 +00:00
Alexey Bataev 8068b643c4 Revert commit r219297.
Still troubles with OpenMP/parallel_firstprivate_codegen.cpp (now in ARM buildbots).

llvm-svn: 219298
2014-10-08 12:00:22 +00:00
Alexey Bataev 3854f63aaf [OPENMP] Codegen for 'firstprivate' clause.
This patch generates some helper variables that used as private copies of the corresponding original variables inside an OpenMP 'parallel' directive. These generated variables are initialized by copy using values of the original variables (with the copy constructor, if any). For arrays, initializator is generated for single element and in the codegen procedure this initial value is automatically propagated between all elements of the private copy.
In outlined function, references to original variables are replaced by the references to these private helper variables. At the end of the initialization of the private variables an implicit barier is generated by calling __kmpc_barrier(...) runtime function to be sure that all threads were initialized using original values of the variables.
Differential Revision: http://reviews.llvm.org/D5140

llvm-svn: 219297
2014-10-08 11:35:04 +00:00
Alexey Bataev bdef50e1ad Revert back r219295.
To fix issues with test OpenMP/parallel_firstprivate_codegen.cpp

llvm-svn: 219296
2014-10-08 11:12:35 +00:00
Alexey Bataev e7a5517a58 [OPENMP] Codegen for 'firstprivate' clause.
This patch generates some helper variables that used as private copies of the corresponding original variables inside an OpenMP 'parallel' directive. These generated variables are initialized by copy using values of the original variables (with the copy constructor, if any). For arrays, initializator is generated for single element and in the codegen procedure this initial value is automatically propagated between all elements of the private copy.
In outlined function, references to original variables are replaced by the references to these private helper variables. At the end of the initialization of the private variables an implicit barier is generated by calling __kmpc_barrier(...) runtime function to be sure that all threads were initialized using original values of the variables.
Differential Revision: http://reviews.llvm.org/D5140

llvm-svn: 219295
2014-10-08 10:42:55 +00:00
Renato Golin 9804fa5d48 Revert "[OPENMP] 'omp teams' directive basic support. Includes parsing and semantic analysis for 'omp teams' directive support from OpenMP 4.0. Adds additional analysis to 'omp target' directive with 'omp teams' directive."
This reverts commit r219197 because it broke ARM self-hosting buildbots with
segmentation fault errors in many tests.

llvm-svn: 219289
2014-10-08 09:06:45 +00:00
Alexey Bataev 941bbec6f4 [OPENMP] 'omp teams' directive basic support.
Includes parsing and semantic analysis for 'omp teams' directive support from OpenMP 4.0. Adds additional analysis to 'omp target' directive with 'omp teams' directive.

llvm-svn: 219197
2014-10-07 10:13:33 +00:00
Alexander Musman d196ef2124 [OPENMP] Small refactoring of EmitOMPSimdLoop helper routine.
No functional changes intended.
Renamed EmitOMPSimdLoop to EmitOMPInnerLoop, I plan to re-use
it to emit inner loop in the future patches for CodeGen of the
worksharing loop directives (omp for, omp for simd).

llvm-svn: 219195
2014-10-07 08:57:09 +00:00
Alexander Musman a5f070aec0 [OPENMP] Loop collapsing and codegen for 'omp simd' directive.
This patch implements collapsing of the loops (in particular, in
presense of clause 'collapse'). It calculates number of iterations N
and expressions nesessary to calculate the nested loops counters
values based on new iteration variable (that goes from 0 to N-1)
in Sema. It also adds Codegen for 'omp simd', which uses
(and tests) this feature.

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

llvm-svn: 218743
2014-10-01 06:03:56 +00:00
Alexander Musman 09184fedc0 [OPENMP] Codegen of the ‘aligned’ clause for the ‘omp simd’ directive.
Differential Revision: http://reviews.llvm.org/D5499

llvm-svn: 218660
2014-09-30 05:29:28 +00:00
Alexander Musman e4e893bb36 [OPENMP] Parsing/Sema of directive omp parallel for simd
llvm-svn: 218299
2014-09-23 09:33:00 +00:00
Alexey Bataev 3a3bf0bbe3 [OPENMP] Codegen for 'omp critical' directive.
This patch adds codegen for constructs:
#pragma omp critical [name]
<body>

It generates global variable ".gomp_critical_user_[name].var" of type int32[8]. Then it generates library call "kmpc_critical(loc, gtid, .gomp_critical_user_[name].var)", code for <body> statement and final call "kmpc_end_critical(loc, gtid, .gomp_critical_user_[name].var)".
Differential Revision: http://reviews.llvm.org/D5202

llvm-svn: 218239
2014-09-22 10:01:53 +00:00
Alexey Bataev 0bd520b767 [OPENMP] Initial parsing/sema analysis of 'target' directive.
llvm-svn: 218110
2014-09-19 08:19:49 +00:00
Alexander Musman f82886e502 Parsing/Sema of directive omp for simd
llvm-svn: 218029
2014-09-18 05:12:34 +00:00
Alexey Bataev 0162e459ef [OPENMP] Initial parsing and sema analysis for 'atomic' directive.
llvm-svn: 213639
2014-07-22 10:10:35 +00:00
Alexey Bataev 9fb6e647e7 [OPENMP] Initial parsing and sema analysis for 'ordered' directive.
llvm-svn: 213616
2014-07-22 06:45:04 +00:00
Alexey Bataev 6125da9258 [OPENMP] Initial parsing and sema analysis for 'flush' directive.
llvm-svn: 213512
2014-07-21 11:26:11 +00:00
Alexander Musman d9ed09f7a5 [OPENMP] Parsing/Sema of the OpenMP directive 'critical'.
llvm-svn: 213510
2014-07-21 09:42:05 +00:00
Alexey Bataev 2df347ad96 [OPENMP] Initial parsing and sema analysis for 'taskwait' directive.
llvm-svn: 213363
2014-07-18 10:17:07 +00:00
Alexey Bataev 4d1dfeabc9 [OPENMP] Initial parsing and sema analysis for 'barrier' directive.
llvm-svn: 213360
2014-07-18 09:11:51 +00:00
Alexey Bataev 68446b7253 [OPENMP] Initial parsing and sema analysis of 'taskyield' directive.
llvm-svn: 213355
2014-07-18 07:47:19 +00:00
Alexander Musman 80c2289a03 [OPENMP] Parsing/Sema analysis of directive 'master'
llvm-svn: 213237
2014-07-17 08:54:58 +00:00
Alexey Bataev 9c2e8ee72f [OPENMP] Parsing and sema analysis for 'omp task' directive.
llvm-svn: 212804
2014-07-11 11:25:16 +00:00
Alexey Bataev 84d0b3efee [OPENMP] Parsing and sema analysis for 'omp parallel sections' directive.
llvm-svn: 212516
2014-07-08 08:12:03 +00:00
Alexey Bataev 4acb859fbd [OPENMP] Added initial support for 'omp parallel for'.
llvm-svn: 212453
2014-07-07 13:01:15 +00:00
Alexey Bataev aca7fcf276 Using of variable length arrays in captured statements and OpenMP constructs.
Differential Revision: http://reviews.llvm.org/D4067

llvm-svn: 212010
2014-06-30 02:55:54 +00:00
Alexey Bataev d1e40fbfe1 [OPENMP] Initial parsing and sema analysis for 'single' directive.
llvm-svn: 211774
2014-06-26 12:05:45 +00:00
Alexey Bataev 1e0498a92d [OPENMP] Initial parsing and sema analysis for 'section' directive.
llvm-svn: 211767
2014-06-26 08:21:58 +00:00
Alexey Bataev d3f8dd2d15 [OPENMP] Initial support for 'sections' directive.
llvm-svn: 211685
2014-06-25 11:44:49 +00:00
Alexey Bataev 23b6942634 [OPENMP] Reformatting and code improvement.
llvm-svn: 211147
2014-06-18 07:08:49 +00:00
Alexey Bataev f29276edb7 [OPENMP] Initial support for '#pragma omp for' (fixed incompatibility with MSVC).
llvm-svn: 211140
2014-06-18 04:14:57 +00:00
Rafael Espindola a566efbec9 Revert "[OPENMP] Initial support for '#pragma omp for'."
This reverts commit r211096. Looks like it broke the msvc build:

SemaOpenMP.cpp(140) : error C4519: default template arguments are only allowed on a class template

llvm-svn: 211113
2014-06-17 17:20:53 +00:00
Alexey Bataev c77dd5257a [OPENMP] Initial support for '#pragma omp for'.
llvm-svn: 211096
2014-06-17 11:49:22 +00:00
Alexander Musman 515ad8c490 This patch adds a helper class (CGLoopInfo) for marking memory instructions with llvm.mem.parallel_loop_access metadata.
It also adds a simple initial version of codegen for pragma omp simd (it will change in the future to support all the clauses).

Differential revision: http://reviews.llvm.org/D3644

llvm-svn: 209411
2014-05-22 08:54:05 +00:00
Alexey Bataev 9959db5fa9 [OPENMP] Initial codegen for '#pragma omp parallel'
llvm-svn: 208077
2014-05-06 10:08:46 +00:00