PIPS
loop_nest_annotate.c File Reference
#include <stdio.h>
#include <string.h>
#include "genC.h"
#include "boolean.h"
#include "arithmetique.h"
#include "vecteur.h"
#include "contrainte.h"
#include "ray_dte.h"
#include "sommet.h"
#include "sg.h"
#include "sc.h"
#include "polyedre.h"
#include "matrix.h"
#include "linear.h"
#include "ri.h"
#include "effects.h"
#include "database.h"
#include "ri-util.h"
#include "prettyprint.h"
#include "effects-util.h"
#include "constants.h"
#include "misc.h"
#include "control.h"
#include "text-util.h"
#include "pipsdbm.h"
#include "resources.h"
#include "properties.h"
#include "effects-simple.h"
+ Include dependency graph for loop_nest_annotate.c:

Go to the source code of this file.

Data Structures

struct  gpu_lna_context
 In modern PIPS programming, all is passed through a context instead of having a global variable. More...
 

Macros

#define COMMA   ","
 Loop nests transformation phase for par4all : More...
 
#define OPENPAREN   "("
 
#define CLOSEPAREN   ")"
 

Functions

static bool loop_push (loop l, gpu_lna_context *p)
 Push a loop that matches the criterion for annotation. More...
 
static void loop_annotate (loop l, gpu_lna_context *p)
 Do the real annotation work on previously marked loops bottom-up. More...
 
bool gpu_loop_nest_annotate_on_statement (statement s)
 annotates loop nests in the following way : More...
 
bool gpu_loop_nest_annotate (const char *module_name)
 
static bool parallelize_annotated_loop_nest (statement s)
 Callback for gen_recurse Parallelize perfectly nested loop nest, till we reach the magic comment. More...
 
bool gpu_parallelize_annotated_loop_nest (const string mod_name)
 Parallelize the launcher based on loop nest annotate sentinels. More...
 
bool clear_annotated_loop_nest (statement s)
 Callback for gen_recurse Remove annotation on a loop nest. More...
 
bool gpu_clear_annotations_on_loop_nest (const string mod_name)
 Remove all annotations on a loop nest. More...
 

Macro Definition Documentation

◆ CLOSEPAREN

#define CLOSEPAREN   ")"

Definition at line 104 of file loop_nest_annotate.c.

◆ COMMA

#define COMMA   ","

Loop nests transformation phase for par4all :

gpu_loop_nest_annotate takes a module that is of the form :

typedef float float_t; void p4a_kernel_wrapper_1(float_t save[501][501], float_t space[501][501], int i, int j); void p4a_kernel_launcher_1(float_t save[501][501], float_t space[501][501]) { int i; int j; kernel2: for(i = 0; i <= 100; i += 1) for(j = 0; j <= 200; j += 1) p4a_kernel_wrapper_1(save, space, i+1, j+1); }

and transforms it into :

typedef float float_t; void p4a_kernel_wrapper_1(float_t save[501][501], float_t space[501][501], int i, int j); void p4a_kernel_launcher_1(float_t save[501][501], float_t space[501][501]) { int i; int j; kernel2: Loop nest P4A begin, 2D(200, 100) for(i = 0; i <= 100; i += 1) for(j = 0; j <= 200; j += 1) Loop nest P4A end if (i <= 100 && j <= 200) p4a_kernel_wrapper_1(save, space, i+1, j+1); }

for further generation of CUDA code. } Ansi includes
Newgen includes Pips includes

Definition at line 102 of file loop_nest_annotate.c.

◆ OPENPAREN

#define OPENPAREN   "("

Definition at line 103 of file loop_nest_annotate.c.

Function Documentation

◆ clear_annotated_loop_nest()

bool clear_annotated_loop_nest ( statement  s)

Callback for gen_recurse Remove annotation on a loop nest.

Definition at line 465 of file loop_nest_annotate.c.

465  {
466  string comment = statement_comments(s);
468  && (NULL != strstr(comment, "Loop nest P4A end")|| NULL != strstr(comment, "Loop nest P4A begin"))) {
469  // clear the comment
470  // We may instead filter out only the annotation inside the comment
472  }
473  return true;
474 }
static void comment(string_buffer code, spoc_hardware_type hw, dagvtx v, int stage, int side, bool flip)
Definition: freia_spoc.c:52
bool empty_comments_p(const char *)
Definition: statement.c:107
#define string_undefined
Definition: newgen_types.h:40
#define statement_comments(x)
Definition: ri.h:2456

References comment(), empty_comments_p(), statement_comments, and string_undefined.

Referenced by gpu_clear_annotations_on_loop_nest().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ gpu_clear_annotations_on_loop_nest()

bool gpu_clear_annotations_on_loop_nest ( const string  mod_name)

Remove all annotations on a loop nest.

Parameters
mod_nameod_name

Definition at line 477 of file loop_nest_annotate.c.

477  {
478  // Use this module name and this environment variable to set
480  "GPU_IFY_DEBUG_LEVEL");
481 
482  // Parallelize loops
485 
486  // Put back the new statement module
488  ;
489  // The macro above does a "return TRUE" indeed.
490 }
static statement module_statement
Definition: alias_check.c:125
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
void gen_null(__attribute__((unused)) void *unused)
Ignore the argument.
Definition: genClib.c:2752
#define PIPS_PHASE_POSTLUDE(new_module_statement)
End a transformation phase by putting back into PIPS the (possibly) modified statement.
#define PIPS_PHASE_PRELUDE(module_name, debug_env_var)
Start a phase that use a module CODE.
bool clear_annotated_loop_nest(statement s)
Callback for gen_recurse Remove annotation on a loop nest.
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362

References clear_annotated_loop_nest(), gen_null(), gen_recurse, module_statement, PIPS_PHASE_POSTLUDE, PIPS_PHASE_PRELUDE, and statement_domain.

+ Here is the call graph for this function:

◆ gpu_loop_nest_annotate()

bool gpu_loop_nest_annotate ( const char *  module_name)
Parameters
module_nameodule_name

Definition at line 406 of file loop_nest_annotate.c.

406  {
407  // Use this module name and this environment variable to set
409  PIPS_PHASE_PRELUDE(module_name, "P4A_LOOP_NEST_ANOTATE_DEBUG_LEVEL");
410 
412 
413  // Put back the new statement module
415  ;
416  // The macro above does a "return TRUE" indeed.
417 }
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
bool gpu_loop_nest_annotate_on_statement(statement s)
annotates loop nests in the following way :

References gpu_loop_nest_annotate_on_statement(), module_name(), module_statement, PIPS_PHASE_POSTLUDE, and PIPS_PHASE_PRELUDE.

+ Here is the call graph for this function:

◆ gpu_loop_nest_annotate_on_statement()

bool gpu_loop_nest_annotate_on_statement ( statement  s)

annotates loop nests in the following way :

loop_nest_annotate.c

for(i=0; i<=100; i++) for(j=0; j<=200; j++) foo();

==>

// Loop nest P4A begin,2D(200, 100) for(i=0; i<=100; i++) for(j=0; j<=200; j++) // Loop nest P4A end if (i<=100&&j<=200) foo();

for loops must have been transformed into loops.

Parameters
mod_namename of the module
Returns
true

Initialize context

Annotate the loop nests of the module.

Clean up things: (hasn't it been done previously in loop_annotate?)

Definition at line 383 of file loop_nest_annotate.c.

383  {
384  /* Initialize context */
385  gpu_lna_context c;
388  c.max_loop_nest_depth = -1;
389  c.loop_nest_depth = 0;
390  c.inner_reached = false;
392  = get_bool_property("GPU_LOOP_NEST_ANNOTATE_PARALLEL");
393  c.fail_p = false;
396 
397  /* Annotate the loop nests of the module. */
399 
400  /* Clean up things: (hasn't it been done previously in loop_annotate?) */
402 
403  return true;
404 }
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
#define gen_context_recurse(start, ctxt, domain_number, flt, rwt)
Definition: genC.h:285
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
static void loop_annotate(loop l, gpu_lna_context *p)
Do the real annotation work on previously marked loops bottom-up.
static bool loop_push(loop l, gpu_lna_context *p)
Push a loop that matches the criterion for annotation.
#define loop_undefined
Definition: ri.h:1612
#define loop_domain
newgen_language_domain_defined
Definition: ri.h:218
#define expression_undefined
Definition: ri.h:1223
In modern PIPS programming, all is passed through a context instead of having a global variable.
bool gpu_loop_nest_annotate_parallel_p
True if we only deal with parallel loop nests.
bool fail_p
The generation may fail because of an unhandled case for isntance.
expression guard_expression
bool inner_reached
True only when we reach the inner annotated loop:

References expression_undefined, gpu_lna_context::fail_p, gen_context_recurse, gen_free_list(), get_bool_property(), gpu_lna_context::gpu_loop_nest_annotate_parallel_p, gpu_lna_context::guard_expression, gpu_lna_context::inner_loop, gpu_lna_context::inner_reached, gpu_lna_context::l_enclosing_loops, gpu_lna_context::l_number_iter_exp, loop_annotate(), loop_domain, gpu_lna_context::loop_nest_depth, loop_push(), loop_undefined, gpu_lna_context::max_loop_nest_depth, and NIL.

Referenced by gpu_ify_statement(), and gpu_loop_nest_annotate().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ gpu_parallelize_annotated_loop_nest()

bool gpu_parallelize_annotated_loop_nest ( const string  mod_name)

Parallelize the launcher based on loop nest annotate sentinels.

Parameters
mod_nameod_name

Definition at line 445 of file loop_nest_annotate.c.

445  {
446  // Use this module name and this environment variable to set
448  "GPU_IFY_DEBUG_LEVEL");
449 
450  // Parallelize loops
453 
454  // Put back the new statement module
456  ;
457  // The macro above does a "return TRUE" indeed.
458 }
static bool parallelize_annotated_loop_nest(statement s)
Callback for gen_recurse Parallelize perfectly nested loop nest, till we reach the magic comment.

References gen_null(), gen_recurse, module_statement, parallelize_annotated_loop_nest(), PIPS_PHASE_POSTLUDE, PIPS_PHASE_PRELUDE, and statement_domain.

+ Here is the call graph for this function:

◆ loop_annotate()

static void loop_annotate ( loop  l,
gpu_lna_context p 
)
static

Do the real annotation work on previously marked loops bottom-up.

We have to select the operators that are different in C and FORTRAN

The first time we enter this function is when we reach the innermost loop nest level.

We are at the innermost loop nest level

First we build the guard to be added to the loop body statement using the enclosing loops upper bounds. And we push on l_number_iter_exp an expression representing the number of iteration of each loop; currently, we do not check that variables modified inside loops are not used in loop bounds expressions. but we take care of loop indices used in deeper loop bounds.

first check if the lower bound depend on enclosing loop indices

We have to clean the list of effect from any "preference" since the next loop modify the references and can make our "preference" invalid

Keep the number of iterations for the generation of the outermost comment

We will have deepest loop size first:

We are now on our way back in the recursion; we do nothing, unless we are at the uppermost level.

Output inner dimension first:

Concatenate the dimension of the innermost loop:

Idem for other dimensions, but do not forget to insert the ', '

Then we add the comment : // Loop nest P4A end

reset context

Definition at line 153 of file loop_nest_annotate.c.

153  {
154  /* We have to select the operators that are different in C and FORTRAN */
155  string and_op =
158  string
159  less_op =
162  /* The first time we enter this function is when we reach the innermost
163  loop nest level.
164  */
165  if(p->inner_loop == loop_undefined) {
166  expression guard_exp = expression_undefined;
167 
168  /* We are at the innermost loop nest level */
169  p->inner_loop = l;
170  /* First we build the guard to be added to the loop body statement using the
171  enclosing loops upper bounds.
172  And we push on l_number_iter_exp an expression representing the
173  number of iteration of each loop;
174  currently, we do not check that variables modified inside loops
175  are not used in loop bounds expressions.
176  but we take care of loop indices used in deeper loop bounds.
178  entity c_index = loop_index(c_loop);
179  range c_range = loop_range(c_loop);
180  expression c_lower = copy_expression(range_lower(c_range));
181  expression c_upper = copy_expression(range_upper(c_range));
182  expression c_inc = range_increment(c_range);
183  expression c_number_iter_exp = expression_undefined;
184  expression c_guard;
185 
186  if(expression_constant_p(c_inc) && expression_to_int(c_inc) == 1) {
187  /* first check if the lower bound depend on enclosing loop indices */
188  list l_eff_lower_bound = proper_effects_of_expression(c_lower);
189  list l_eff_upper_bound = proper_effects_of_expression(c_upper);
190 
191  /* We have to clean the list of effect from any "preference" since the
192  * next loop modify the references and can make our "preference" invalid
193  */
194  void remove_preferences(void * obj);
195  {
196  FOREACH(effect,e,l_eff_lower_bound) {
198  }
199  }
200  {
201  FOREACH(effect,e,l_eff_upper_bound) {
203  }
204  }
205 
206  FOREACH(LOOP, other_loop, p->l_enclosing_loops) {
207  if(other_loop != l) {
208  range range_other_loop = loop_range(other_loop);
209  expression lower_other_loop = range_lower(range_other_loop);
210  expression upper_other_loop = range_upper(range_other_loop);
211 
212  if(effects_read_variable_p(l_eff_lower_bound,
213  loop_index(other_loop))) {
214  expression new_lower_1 = c_lower;
215  expression new_lower_2 = copy_expression(c_lower);
216  replace_entity_by_expression(new_lower_1,
217  loop_index(other_loop),
218  lower_other_loop);
219  (void)simplify_expression(&new_lower_1);
220  replace_entity_by_expression(new_lower_2,
221  loop_index(other_loop),
222  upper_other_loop);
223 
224  (void)simplify_expression(&new_lower_2);
225  c_lower = make_min_expression(new_lower_1,
226  new_lower_2,
228  }
229  if(effects_read_variable_p(l_eff_upper_bound,
230  loop_index(other_loop))) {
231  expression new_upper_1 = c_upper;
232  expression new_upper_2 = copy_expression(c_upper);
233  replace_entity_by_expression(new_upper_1,
234  loop_index(other_loop),
235  lower_other_loop);
236  (void)simplify_expression(&new_upper_1);
237  replace_entity_by_expression(new_upper_2,
238  loop_index(other_loop),
239  upper_other_loop);
240  (void)simplify_expression(&new_upper_2);
241 
242  c_upper = make_max_expression(new_upper_1,
243  new_upper_2,
245  }
246  }
247  }
248 
249  c_guard
250  = MakeBinaryCall(entity_intrinsic(less_op),
252  NIL)),
253  copy_expression(range_upper(c_range)));
254 
255  if(expression_undefined_p(guard_exp))
256  guard_exp = c_guard;
257  else
258  guard_exp = MakeBinaryCall(entity_intrinsic(and_op),
259  guard_exp,
260  c_guard);
261 
262  pips_debug(2, "guard expression : %s\n",
263  expression_to_string(guard_exp));
264 
265  /* Keep the number of iterations for the generation of the
266  outermost comment */
267  c_number_iter_exp = make_op_exp(MINUS_OPERATOR_NAME, c_upper, c_lower);
268  c_number_iter_exp = make_op_exp(PLUS_OPERATOR_NAME,
269  c_number_iter_exp,
270  int_to_expression(1));
271  /* We will have deepest loop size first: */
272  p->l_number_iter_exp = CONS(EXPRESSION, c_number_iter_exp,
273  p->l_number_iter_exp);
274 
275  } else {
276  p->fail_p = true;
277  pips_user_warning("case not handled: loop increment is not 1.\n");
278  }
279  }
280  if(!p->fail_p) {
281  p->guard_expression = guard_exp;
282  }
283 
284  }
285 
286  /* We are now on our way back in the recursion; we do nothing, unless
287  we are at the uppermost level.
288  */
289  if(gen_length(p->l_enclosing_loops) == 1) {
290  if(!p->fail_p)
291  // if the process has succeeded, we add the outermost comment :
292  // Loop nest P4A begin, xD(upper_bound,..) and the inner guard.
293  {
295  // Then we add the comment such as: '// Loop nest P4A begin,3D(200, 100)'
296  string outer_s;
297  (void)asprintf(&outer_s,
298  "%s Loop nest P4A begin,%dD" OPENPAREN,
300  p->loop_nest_depth);
301 
302  bool first_iteration = true;
303  /* Output inner dimension first: */FOREACH(EXPRESSION, upper_exp, p->l_number_iter_exp) {
304  string buf;
305  string buf1 = expression_to_string(upper_exp);
306  if(first_iteration)
307  /* Concatenate the dimension of the innermost loop: */
308  (void)asprintf(&buf, "%s%s", outer_s, buf1);
309  else
310  /* Idem for other dimensions, but do not forget to insert the ', ' */
311  (void)asprintf(&buf, "%s%s%s", outer_s, COMMA" ", buf1);
312  free(outer_s);
313  free(buf1);
314  outer_s = buf;
315  first_iteration = false;
316  }
317  (void)asprintf(&statement_comments(current_stat),
318  "%s"CLOSEPAREN"\n",
319  outer_s);
320  free(outer_s);
322  loop_body(p->inner_loop),
324  /* Then we add the comment : // Loop nest P4A end */statement_comments(guard_s)
326  " Loop nest P4A end\n",
327  NULL));
328  loop_body(p->inner_loop) = guard_s;
329 
330  /* reset context */
331  p->loop_nest_depth = 0;
332  p->max_loop_nest_depth = -1;
334  p->l_number_iter_exp = NIL;
335  p->fail_p = false;
338  }
339 
340  else
341  // the process has failed: we clean everything and reset context
342  {
343  p->loop_nest_depth = 0;
344  p->max_loop_nest_depth = -1;
346  p->l_number_iter_exp = NIL;
347  p->fail_p = false;
352  }
353  }
354  }
355  if(gen_length(p->l_enclosing_loops)) {
357  }
358  return;
359 }
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
test make_test(expression a1, statement a2, statement a3)
Definition: ri.c:2607
void free_expression(expression p)
Definition: ri.c:853
void remove_preferences(void *)
delay.c
Definition: delay.c:89
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
static string c_loop(loop l)
list proper_effects_of_expression(expression)
bool effects_read_variable_p(list, entity)
Definition: effects.c:1123
void gen_full_free_list(list l)
Definition: genClib.c:1023
void free(void *)
statement make_empty_block_statement(void)
Build an empty statement (block/sequence)
Definition: statement.c:625
void replace_entity_by_expression(void *s, entity ent, expression exp)
replace all reference to entity ent by expression exp in s.
Definition: replace.c:220
gen_chunk * gen_get_ancestor(int, const void *)
return the first ancestor object found of the given type.
Definition: genClib.c:3560
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
size_t gen_length(const list l)
Definition: list.c:150
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
Definition: newgen_list.h:179
bool expression_constant_p(expression)
HPFC module by Fabien COELHO.
Definition: expression.c:2453
enum language_utype get_prettyprint_language_tag()
Definition: language.c:67
#define CLOSEPAREN
#define COMMA
Loop nests transformation phase for par4all :
#define OPENPAREN
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define pips_user_warning
Definition: misc-local.h:146
#define asprintf
Definition: misc-local.h:225
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
string expression_to_string(expression e)
Definition: expression.c:77
string get_comment_sentinel()
Start a single line comment.
Definition: misc.c:154
#define C_LESS_OR_EQUAL_OPERATOR_NAME
#define C_AND_OPERATOR_NAME
#define MINUS_OPERATOR_NAME
#define PLUS_OPERATOR_NAME
#define test_to_statement(t)
#define AND_OPERATOR_NAME
FI: intrinsics are defined at a third place after bootstrap and effects! I guess the name should be d...
#define LESS_OR_EQUAL_OPERATOR_NAME
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
expression reference_to_expression(reference r)
Definition: expression.c:196
bool simplify_expression(expression *pexp)
use polynomials to simplify an expression in some cases this operation can change the basic of the ex...
Definition: expression.c:3770
int expression_to_int(expression exp)
================================================================
Definition: expression.c:2205
expression make_min_expression(expression e1, expression e2, enum language_utype lang)
Definition: expression.c:1600
expression MakeBinaryCall(entity f, expression eg, expression ed)
Creates a call expression to a function with 2 arguments.
Definition: expression.c:354
expression int_to_expression(_int i)
transform an int into an expression and generate the corresponding entity if necessary; it is not cle...
Definition: expression.c:1188
expression make_op_exp(char *op_name, expression exp1, expression exp2)
================================================================
Definition: expression.c:2012
expression make_max_expression(expression e1, expression e2, enum language_utype lang)
Definition: expression.c:1579
#define loop_body(x)
Definition: ri.h:1644
#define LOOP(x)
LOOP.
Definition: ri.h:1606
#define range_upper(x)
Definition: ri.h:2290
#define range_increment(x)
Definition: ri.h:2292
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define expression_undefined_p(x)
Definition: ri.h:1224
#define range_lower(x)
Definition: ri.h:2288
#define loop_range(x)
Definition: ri.h:1642
@ is_language_c
Definition: ri.h:1567
#define loop_index(x)
Definition: ri.h:1640
char * strdup()
static char buf[BSZ]
Definition: split_file.c:157
The structure used to build lists in NewGen.
Definition: newgen_list.h:41

References AND_OPERATOR_NAME, asprintf, buf, C_AND_OPERATOR_NAME, C_LESS_OR_EQUAL_OPERATOR_NAME, c_loop(), CLOSEPAREN, COMMA, concatenate(), CONS, copy_expression(), effects_read_variable_p(), entity_intrinsic(), EXPRESSION, expression_constant_p(), expression_to_int(), expression_to_string(), expression_undefined, expression_undefined_p, gpu_lna_context::fail_p, FOREACH, free(), free_expression(), gen_free_list(), gen_full_free_list(), gen_get_ancestor(), gen_length(), get_comment_sentinel(), get_prettyprint_language_tag(), gpu_lna_context::guard_expression, gpu_lna_context::inner_loop, int_to_expression(), is_language_c, gpu_lna_context::l_enclosing_loops, gpu_lna_context::l_number_iter_exp, LESS_OR_EQUAL_OPERATOR_NAME, LOOP, loop_body, loop_index, gpu_lna_context::loop_nest_depth, loop_range, loop_undefined, make_empty_block_statement(), make_max_expression(), make_min_expression(), make_op_exp(), make_reference(), make_test(), MakeBinaryCall(), gpu_lna_context::max_loop_nest_depth, MINUS_OPERATOR_NAME, NIL, OPENPAREN, pips_debug, pips_user_warning, PLUS_OPERATOR_NAME, POP, proper_effects_of_expression(), range_increment, range_lower, range_upper, reference_to_expression(), remove_preferences(), replace_entity_by_expression(), simplify_expression(), statement_comments, statement_domain, strdup(), and test_to_statement.

Referenced by gpu_loop_nest_annotate_on_statement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ loop_push()

static bool loop_push ( loop  l,
gpu_lna_context p 
)
static

Push a loop that matches the criterion for annotation.

This is the first loop we met in this loop nest

Let's compute the loop_nest_depth

this loop does not belong to the perfectly nested loops

Definition at line 126 of file loop_nest_annotate.c.

126  {
127  if(p->max_loop_nest_depth == -1) {
128  /* This is the first loop we met in this loop nest */
130  return true;
131  }
132 
133  /* Let's compute the loop_nest_depth */
137  : depth_of_perfect_loop_nest(current_stat);
138  }
139 
141  /* this loop does not belong to the perfectly nested loops */
142  return false;
143  else {
145  p->loop_nest_depth++;
146  // Go on recursing:
147  return true;
148  }
149  return false;
150 }
bool loop_parallel_p(loop l)
Test if a loop is parallel.
Definition: loop.c:393
int depth_of_perfect_loop_nest(statement s)
Compute the depth of a perfect loop-nest.
Definition: loop.c:476
int depth_of_parallel_perfect_loop_nest(statement s)
Compute the depth of a parallel perfect loop-nest.
Definition: loop.c:436
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344

References CONS, depth_of_parallel_perfect_loop_nest(), depth_of_perfect_loop_nest(), gen_get_ancestor(), gen_nconc(), gpu_lna_context::gpu_loop_nest_annotate_parallel_p, gpu_lna_context::l_enclosing_loops, LOOP, gpu_lna_context::loop_nest_depth, loop_parallel_p(), gpu_lna_context::max_loop_nest_depth, NIL, and statement_domain.

Referenced by gpu_loop_nest_annotate_on_statement().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parallelize_annotated_loop_nest()

static bool parallelize_annotated_loop_nest ( statement  s)
static

Callback for gen_recurse Parallelize perfectly nested loop nest, till we reach the magic comment.

FIXME : should detect the beginning sentinel, but since we use it in launcher, it has no importance at that time

Definition at line 426 of file loop_nest_annotate.c.

426  {
427  char **comment=NULL;
428  if(statement_loop_p(s)) {
430  // Check the inner comment to find out the sentinel and stop recursion
432  } else {
434  }
435 
436  // Check sentinel
437  if(comment && !empty_comments_p(*comment) && NULL != strstr(*comment, "Loop nest P4A end")) {
438  // stop recursion
439  return false;
440  }
441  return true;
442 }
loop statement_loop(statement)
Get the loop of a statement.
Definition: statement.c:1374
bool statement_loop_p(statement)
Definition: statement.c:349
char ** find_first_statement_comment(statement)
Find the first non-empty comment of a statement, if any returns a pointer to the comment if found,...
Definition: statement.c:1772
#define execution_tag(x)
Definition: ri.h:1207
#define loop_execution(x)
Definition: ri.h:1648
@ is_execution_parallel
Definition: ri.h:1190

References comment(), empty_comments_p(), execution_tag, find_first_statement_comment(), is_execution_parallel, loop_body, loop_execution, statement_loop(), and statement_loop_p().

Referenced by gpu_parallelize_annotated_loop_nest().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: