PIPS
inits.c File Reference
#include "defines-local.h"
+ Include dependency graph for inits.c:

Go to the source code of this file.

Functions

void create_common_parameters_h (FILE *file)
 Fabien Coelho, June 1993. More...
 
void create_parameters_h (FILE *file, entity module)
 create_parameters_h More...
 
int max_size_of_processors ()
 
static int code_number (tag t)
 translation from an hpf_newdecl tag to the runtime code expected More...
 
void create_init_common_param_for_arrays (FILE *file, entity module)
 
void create_init_common_param_for_templates (FILE *file)
 
void create_init_common_param_for_processors (FILE *file)
 
void create_init_common_param (FILE *file)
 create_init_common_param (templates and modules) More...
 

Function Documentation

◆ code_number()

static int code_number ( tag  t)
static

translation from an hpf_newdecl tag to the runtime code expected

just to avoid a gcc warning

Definition at line 141 of file inits.c.

143 {
144  switch(t)
145  {
146  case is_hpf_newdecl_none: return 0;
147  case is_hpf_newdecl_alpha: return 1;
148  case is_hpf_newdecl_beta: return 2;
149  case is_hpf_newdecl_gamma: return 3;
150  case is_hpf_newdecl_delta: return 4;
151  default:
152  pips_internal_error("unexpected hpf_newdecl tag %d", t);
153  }
154 
155  return -1; /* just to avoid a gcc warning */
156 }
@ is_hpf_newdecl_none
Definition: hpf_private.h:665
@ is_hpf_newdecl_delta
Definition: hpf_private.h:669
@ is_hpf_newdecl_alpha
Definition: hpf_private.h:666
@ is_hpf_newdecl_beta
Definition: hpf_private.h:667
@ is_hpf_newdecl_gamma
Definition: hpf_private.h:668
#define pips_internal_error
Definition: misc-local.h:149

References is_hpf_newdecl_alpha, is_hpf_newdecl_beta, is_hpf_newdecl_delta, is_hpf_newdecl_gamma, is_hpf_newdecl_none, and pips_internal_error.

Referenced by create_init_common_param_for_arrays().

+ Here is the caller graph for this function:

◆ create_common_parameters_h()

void create_common_parameters_h ( FILE *  file)

Fabien Coelho, June 1993.

inits.c

in this file there are functions to generate the run-time resolution parameters.

Parameters
fileile

Definition at line 36 of file inits.c.

38 {
39  fprintf(file,
40  " integer\n"
41  " $ REALNBOFARRAYS,\n"
42  " $ REALNBOFTEMPLATES,\n"
43  " $ REALNBOFPROCESSORS,\n"
44  " $ REALMAXSIZEOFPROCS,\n"
45  " $ REALMAXSIZEOFBUFFER\n\n"
46  "!\n! parameters\n!\n"
47  " parameter(REALNBOFARRAYS = %d)\n"
48  " parameter(REALNBOFTEMPLATES = %d)\n"
49  " parameter(REALNBOFPROCESSORS = %d)\n"
50  " parameter(REALMAXSIZEOFPROCS = %d)\n"
51  " parameter(REALMAXSIZEOFBUFFER = %d)\n",
56  get_int_property("HPFC_BUFFER_SIZE"));
57 }
int get_int_property(const string)
int number_of_templates(void)
int number_of_processors(void)
int number_of_distributed_arrays(void)
declarations.c
int max_size_of_processors()
Definition: inits.c:120
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...

References fprintf(), get_int_property(), max_size_of_processors(), number_of_distributed_arrays(), number_of_processors(), and number_of_templates().

Referenced by put_generated_resources_for_program().

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

◆ create_init_common_param()

void create_init_common_param ( FILE*  file)

create_init_common_param (templates and modules)

Parameters
fileile

Definition at line 511 of file inits.c.

513 {
516 }
void create_init_common_param_for_processors(FILE *file)
Definition: inits.c:470
void create_init_common_param_for_templates(FILE *file)
Definition: inits.c:391

References create_init_common_param_for_processors(), and create_init_common_param_for_templates().

Referenced by put_generated_resources_for_program().

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

◆ create_init_common_param_for_arrays()

void create_init_common_param_for_arrays ( FILE*  file,
entity  module 
)

NODIMA: Number Of DIMensions of an Array ATOT: Array TO Template

The primary entity is the initial mapping ??? not sure... some decision should be involved...

RANGEA: lower, upper, size and declaration, aso

RANGEA contents:

1: lower bound 2: upper bound 3: size, (2)-(1)+1 4: new declaration flag

5: distribution parameter n, 6: alignment rate a, 7: alignment shift, b-t_{m}

5: distribution parameter n, 6: cycle length n*p, 7: initial cycle number, 8: alignment shift, b-t_{m}

5: distribution parameter n 6: cycle length n*p, 7: initial cycle number, 8: alignment shift, b-t_{m} 9: alignment rate a, 10: chunck size ceil(n,|a|)

ALIGN

Parameters
fileile
moduleodule

Definition at line 158 of file inits.c.

161 {
163 
164  fprintf(file, "!\n! Arrays Initializations for %s\n!\n",
166 
167  MAP(ENTITY, array,
168  {
169  int an = load_hpf_number(array);
170  int nd = NumberOfDimension(array);
172  entity template = align_template(al);
173  int tn = load_hpf_number(template);
174  distribute di = load_hpf_distribution(template);
175  int i;
176 
177  /* NODIMA: Number Of DIMensions of an Array
178  * ATOT: Array TO Template
179  */
180  fprintf(file,
181  "!\n! initializing array %s, number %d\n!\n"
182  " NODIMA(%d) = %d\n"
183  " ATOT(%d) = %d\n",
184  entity_local_name(array), an, an, nd, an, tn);
185 
187  {
188  /* The primary entity is the initial mapping ???
189  * not sure... some decision should be involved...
190  */
191  fprintf(file, "\n"
192  " MSTATUS(%d) = %d\n"
193  " LIVEMAPPING(%d) = .TRUE.\n", an, an, an);
194  }
195 
196  /* RANGEA: lower, upper, size and declaration, aso
197  */
198  i = 1;
199  for (i=1; i<=nd; i++)
200  {
204  int sz = (ub-lb+1);
205  tag decl = new_declaration_tag(array, i);
207 
208  /* RANGEA contents:
209  *
210  * 1: lower bound
211  * 2: upper bound
212  * 3: size, (2)-(1)+1
213  * 4: new declaration flag
214  */
215  fprintf(file, "\n"
216  " RANGEA(%d, %d, 1) = %d\n"
217  " RANGEA(%d, %d, 2) = %d\n"
218  " RANGEA(%d, %d, 3) = %d\n!\n"
219  " RANGEA(%d, %d, 4) = %d\n",
220  an, i, lb, an, i, ub, an, i, sz,
221  an, i, code_number(decl));
222 
223  switch(decl)
224  {
225  case is_hpf_newdecl_none:
226  break;
228  /*
229  * 5: 1 - lower bound
230  */
231  fprintf(file, " RANGEA(%d, %d, 5) = %d\n",
232  an, i, (1-lb));
233  break;
234  case is_hpf_newdecl_beta:
235  {
236  int tdim = alignment_templatedim(a);
237  int procdim = 0;
240  tdim,
241  &procdim);
243  int rate;
244  int shift;
245  dimension
246  dim = FindIthDimension(template, tdim);
247 
248  pips_assert("block distribution",
250 
254 
255  /* 5: distribution parameter n,
256  * 6: alignment rate a,
257  * 7: alignment shift, b-t_{m}
258  */
259  fprintf(file,
260  " RANGEA(%d, %d, 5) = %d\n"
261  " RANGEA(%d, %d, 6) = %d\n"
262  " RANGEA(%d, %d, 7) = %d\n",
263  an, i, param, an, i, rate, an, i, shift);
264 
265  break;
266  }
268  {
269  int tdim = alignment_templatedim(a);
270  int procdim = 0;
273  tdim,
274  &procdim);
276  int sc;
277  int no;
278  int shift;
279  dimension
280  dim = FindIthDimension(template, tdim);
281  entity
282  proc = distribute_processors(di);
283 
284  pips_assert("cyclic distribution",
286 
287  sc = param*SizeOfIthDimension(proc, procdim);
290  no = (lb + shift) / sc ;
291 
292  /* 5: distribution parameter n,
293  * 6: cycle length n*p,
294  * 7: initial cycle number,
295  * 8: alignment shift, b-t_{m}
296  */
297  fprintf(file,
298  " RANGEA(%d, %d, 5) = %d\n"
299  " RANGEA(%d, %d, 6) = %d\n"
300  " RANGEA(%d, %d, 7) = %d\n"
301  " RANGEA(%d, %d, 8) = %d\n",
302  an, i, param, an, i, sc, an, i, no, an, i, shift);
303 
304  break;
305  }
307  {
308  int tdim = alignment_templatedim(a);
309  int procdim = 0;
312  tdim,
313  &procdim);
314  int rate = HpfcExpressionToInt(alignment_rate(a));
317  int sc;
318  int no;
319  int shift;
320  int chck;
321  dimension
322  templdim = FindIthDimension(template, tdim);
323  entity
324  proc = distribute_processors(di);
325 
326  pips_assert("cyclic distribution",
328 
329  sc = param*SizeOfIthDimension(proc, procdim);
330  shift = (cst - HpfcExpressionToInt(dimension_lower(templdim)));
331  no = (rate*lb + shift) / sc ;
332  chck = iceil(param, abs(rate));
333 
334  /* 5: distribution parameter n
335  * 6: cycle length n*p,
336  * 7: initial cycle number,
337  * 8: alignment shift, b-t_{m}
338  * 9: alignment rate a,
339  * 10: chunck size ceil(n,|a|)
340  */
341  fprintf(file,
342  " RANGEA(%d, %d, 5) = %d\n"
343  " RANGEA(%d, %d, 6) = %d\n"
344  " RANGEA(%d, %d, 7) = %d\n"
345  " RANGEA(%d, %d, 8) = %d\n"
346  " RANGEA(%d, %d, 9) = %d\n"
347  " RANGEA(%d, %d, 10) = %d\n",
348  an, i, param, an, i, sc, an, i, no,
349  an, i, shift, an, i, rate, an, i, chck);
350  break;
351  }
352  default:
353  pips_internal_error("unexpected decl. tag (%d)", decl);
354  }
355  }
356 
357  fprintf(file, "\n");
358 
359  /* ALIGN
360  */
361 
362  for(i=1 ; i<=NumberOfDimension(template) ; i++)
363  {
364  alignment
366 
367  if (a==alignment_undefined)
368  {
369  fprintf(file, " ALIGN(%d, %d, 1) = INTFLAG\n", an, i);
370  }
371  else
372  {
373  int adim = alignment_arraydim(a);
374 
375  fprintf(file,
376  " ALIGN(%d, %d, 1) = %d\n"
377  " ALIGN(%d, %d, 2) = %d\n"
378  " ALIGN(%d, %d, 3) = %d\n",
379  an, i, adim, an, i,
380  adim ? HpfcExpressionToInt(alignment_rate(a)) : 0,
382 
383  }
384  }
385  },
386  l);
387 
388  gen_free_list(l);
389 }
bool(* dynamic_entity_p)(entity)
as expected, true if entity e is dynamic.
Definition: dynamic.c:145
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
#define MAP(_map_CASTER, _map_item, _map_code, _map_list)
Apply/map an instruction block on all the elements of a list (old fashioned)
Definition: newgen_list.h:226
#define alignment_templatedim(x)
Definition: hpf.h:136
#define alignment_undefined
Definition: hpf.h:108
#define distribution_style(x)
Definition: hpf.h:210
#define alignment_constant(x)
Definition: hpf.h:140
#define align_template(x)
Definition: hpf.h:98
#define align_alignment(x)
Definition: hpf.h:96
#define distribute_distribution(x)
Definition: hpf.h:174
#define alignment_rate(x)
Definition: hpf.h:138
#define alignment_arraydim(x)
Definition: hpf.h:134
#define distribute_processors(x)
Definition: hpf.h:176
#define distribution_parameter(x)
Definition: hpf.h:212
#define style_block_p(x)
Definition: hpf.h:262
#define style_cyclic_p(x)
Definition: hpf.h:265
int HpfcExpressionToInt(expression e)
HpfcExpressionToInt(e)
Definition: hpfc-util.c:569
alignment FindAlignmentOfTemplateDim(list lal, int dim)
Definition: hpfc-util.c:389
alignment FindAlignmentOfDim(list lal, int dim)
Definition: hpfc-util.c:377
distribution FindDistributionOfDim(list ldi, int dim, int *pdim)
Definition: hpfc-util.c:401
tag new_declaration_tag(entity array, int dim)
Definition: declarations.c:229
list list_of_distributed_arrays_for_module(entity module)
returns the list of entities that are 'local' to module
Definition: declarations.c:72
#define iceil(a, b)
integer ceiling function
distribute load_hpf_distribution(entity)
entity load_primary_entity(entity)
align load_hpf_alignment(entity)
intptr_t load_hpf_number(entity)
static int code_number(tag t)
translation from an hpf_newdecl tag to the runtime code expected
Definition: inits.c:141
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
int tag
TAG.
Definition: newgen_types.h:92
static char * module
Definition: pips.c:74
const char * entity_local_name(entity e)
entity_local_name modified so that it does not core when used in vect_fprint, since someone thought t...
Definition: entity.c:453
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
dimension entity_ith_dimension(entity, int)
Another semantics would be: is this reference r to e a kill for e? In general, this cannot be answere...
Definition: variable.c:1228
dimension FindIthDimension(entity, int)
Definition: type.c:1180
int SizeOfIthDimension(entity, int)
this function returns the size of the ith dimension of a variable e.
Definition: size.c:453
int NumberOfDimension(entity)
Definition: size.c:588
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define dimension_lower(x)
Definition: ri.h:980
#define dimension_upper(x)
Definition: ri.h:982
static entity array
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
Definition: replace.c:135
#define abs(v)
Definition: syntax-local.h:48

References abs, align_alignment, align_template, alignment_arraydim, alignment_constant, alignment_rate, alignment_templatedim, alignment_undefined, array, code_number(), dimension_lower, dimension_upper, distribute_distribution, distribute_processors, distribution_parameter, distribution_style, dynamic_entity_p, ENTITY, entity_ith_dimension(), entity_local_name(), FindAlignmentOfDim(), FindAlignmentOfTemplateDim(), FindDistributionOfDim(), FindIthDimension(), fprintf(), gen_free_list(), HpfcExpressionToInt(), iceil, is_hpf_newdecl_alpha, is_hpf_newdecl_beta, is_hpf_newdecl_delta, is_hpf_newdecl_gamma, is_hpf_newdecl_none, list_of_distributed_arrays_for_module(), load_hpf_alignment(), load_hpf_distribution(), load_hpf_number(), load_primary_entity(), MAP, module, module_local_name(), new_declaration_tag(), NumberOfDimension(), pips_assert, pips_internal_error, SizeOfIthDimension(), style_block_p, and style_cyclic_p.

Referenced by put_generated_resources_for_common(), and put_generated_resources_for_module().

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

◆ create_init_common_param_for_processors()

void create_init_common_param_for_processors ( FILE*  file)

NODIMP: Number Of DIMensions of a Processors arrangement

RANGEP: lower, upper, size

Parameters
fileile

Definition at line 470 of file inits.c.

472 {
473  fprintf(file, "!\n! Processors Initializations\n!\n");
474 
475  MAP(ENTITY, proc,
476  {
477  int pn = load_hpf_number(proc);
478  int nd = NumberOfDimension(proc);
479  int procdim = 1;
480 
481  fprintf(file, "!\n! initializing processors %s, number %d\n!\n",
482  entity_local_name(proc), pn);
483 
484  /* NODIMP: Number Of DIMensions of a Processors arrangement
485  */
486  fprintf(file, " NODIMP(%d) = %d\n", pn, nd);
487 
488  /* RANGEP: lower, upper, size
489  */
490  MAP(DIMENSION, d,
491  {
494  int sz = (ub-lb+1);
495 
496  fprintf(file, "\n"
497  " RANGEP(%d, %d, 1) = %d\n"
498  " RANGEP(%d, %d, 2) = %d\n"
499  " RANGEP(%d, %d, 3) = %d\n",
500  pn, procdim, lb, pn, procdim, ub, pn, procdim, sz);
501 
502  procdim++;
503  },
505  },
507 }
list list_of_processors(void)
#define type_variable(x)
Definition: ri.h:2949
#define variable_dimensions(x)
Definition: ri.h:3122
#define entity_type(x)
Definition: ri.h:2792

References DIMENSION, dimension_lower, dimension_upper, ENTITY, entity_local_name(), entity_type, fprintf(), HpfcExpressionToInt(), list_of_processors(), load_hpf_number(), MAP, NumberOfDimension(), type_variable, and variable_dimensions.

Referenced by create_init_common_param().

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

◆ create_init_common_param_for_templates()

void create_init_common_param_for_templates ( FILE*  file)

NODIMT: Number Of DIMensions of a Template TTOP: Template TO Processors arrangement

RANGET: lower, upper, size

DIST

Parameters
fileile

Definition at line 391 of file inits.c.

393 {
394  fprintf(file, "!\n! Templates Initializations\n!\n");
395 
396  MAP(ENTITY, template,
397  {
398  int tn = load_hpf_number(template);
399  int nd = NumberOfDimension(template);
400  distribute di = load_hpf_distribution(template);
401  entity proc = distribute_processors(di);
402  int pn = load_hpf_number(proc);
403  int procdim = 1;
404  int tempdim = 1;
405 
406  /* NODIMT: Number Of DIMensions of a Template
407  * TTOP: Template TO Processors arrangement
408  */
409  fprintf(file,
410  "!\n! initializing template %s, number %d\n!\n"
411  " NODIMT(%d) = %d\n"
412  " TTOP(%d) = %d\n",
413  entity_local_name(template), tn, tn, nd, tn, pn);
414 
415  /* RANGET: lower, upper, size
416  */
417  MAP(DIMENSION, d,
418  {
421  int sz = (ub-lb+1);
422 
423  fprintf(file, "\n"
424  " RANGET(%d, %d, 1) = %d\n"
425  " RANGET(%d, %d, 2) = %d\n"
426  " RANGET(%d, %d, 3) = %d\n",
427  tn, tempdim, lb, tn, tempdim, ub, tn, tempdim, sz);
428 
429  tempdim++;
430  },
432 
433  /* DIST
434  */
435  tempdim = 1;
436  fprintf(file, "\n");
437  MAP(DISTRIBUTION, d,
438  {
439  int param;
440  bool block_case = false;
441 
442  switch(style_tag(distribution_style(d)))
443  {
444  case is_style_none:
445  break;
446  case is_style_block:
447  block_case = true;
449  case is_style_cyclic:
451  if (!block_case) param = -param;
452  fprintf(file,
453  " DIST(%d, %d, 1) = %d\n"
454  " DIST(%d, %d, 2) = %d\n",
455  tn, procdim, tempdim, tn, procdim, param);
456  procdim++;
457  break;
458  default:
459  pips_internal_error("unexpected style tag");
460  break;
461  }
462 
463  tempdim++;
464  },
466  },
468 }
#define DISTRIBUTION(x)
DISTRIBUTION.
Definition: hpf.h:180
#define style_tag(x)
Definition: hpf.h:258
@ is_style_cyclic
Definition: hpf.h:239
@ is_style_block
Definition: hpf.h:238
@ is_style_none
Definition: hpf.h:237
list list_of_templates(void)
#define _FALLTHROUGH_
Definition: misc-local.h:238

References _FALLTHROUGH_, DIMENSION, dimension_lower, dimension_upper, distribute_distribution, distribute_processors, DISTRIBUTION, distribution_parameter, distribution_style, ENTITY, entity_local_name(), entity_type, fprintf(), HpfcExpressionToInt(), is_style_block, is_style_cyclic, is_style_none, list_of_templates(), load_hpf_distribution(), load_hpf_number(), MAP, NumberOfDimension(), pips_internal_error, style_tag, type_variable, and variable_dimensions.

Referenced by create_init_common_param().

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

◆ create_parameters_h()

void create_parameters_h ( FILE *  file,
entity  module 
)

create_parameters_h

to be called after the declaration_with_overlaps() call. it generates the parameters for module.

formal parameters are passed the value by the caller as far as overlapable dimensions are concerned.

otherwise it is a secondary copy

Parameters
fileile
moduleodule

Definition at line 65 of file inits.c.

68 {
69  entity newarray = entity_undefined;
70  int i;
72 
73  fprintf(file, "!\n! parameters generated for %s\n!\n",
75 
76  MAP(ENTITY, array,
77  {
78  bool is_argument = storage_formal_p(entity_storage(array));
79  int andim;
80  newarray = load_new_node(array);
81  andim = NumberOfDimension(newarray);
82 
83  pips_debug(8, "considering array %s (new is %s)\n",
84  entity_name(array), entity_name(newarray));
85 
86  /* formal parameters are passed the value by the caller
87  * as far as overlapable dimensions are concerned.
88  */
92  for (i=1 ; i<=andim ; i++)
93  {
94  if (!is_argument || !ith_dim_overlapable_p(array, i))
95  {
96  string ld = bound_parameter_name(newarray, LOWER, i);
97  string ud = bound_parameter_name(newarray, UPPER, i);
98  dimension d = FindIthDimension(newarray, i);
99 
100  fprintf(file,
101  " integer \n"
102  " $ %s,\n"
103  " $ %s\n"
104  " parameter(%s = %d)\n"
105  " parameter(%s = %d)\n",
106  ld, ud,
109 
110  free(ld); free(ud);
111  }
112  }
113  /* otherwise it is a secondary copy */
114  },
115  l);
116 
117  gen_free_list(l);
118 }
static bool ud(effect fin, effect fout)
UD detects Use/Def conflicts between effects FIN and FOUT.
Definition: chains.c:1038
#define UPPER(c)
Definition: genSML.c:37
void free(void *)
bool ith_dim_overlapable_p(entity array, int i)
Definition: hpfc-util.c:178
#define LOWER
entity load_similar_mapping(entity)
entity load_new_node(entity)
string bound_parameter_name(entity, string, int)
returns a name for the bound of the declaration of array array, side side and dimension dim.
Definition: run-time.c:488
bool bound_similar_mapping_p(entity)
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define storage_formal_p(x)
Definition: ri.h:2522
#define entity_storage(x)
Definition: ri.h:2794
#define entity_undefined
Definition: ri.h:2761
#define entity_name(x)
Definition: ri.h:2790

References array, bound_parameter_name(), bound_similar_mapping_p(), dimension_lower, dimension_upper, dynamic_entity_p, ENTITY, entity_name, entity_storage, entity_undefined, FindIthDimension(), fprintf(), free(), gen_free_list(), HpfcExpressionToInt(), ith_dim_overlapable_p(), list_of_distributed_arrays_for_module(), load_new_node(), load_similar_mapping(), LOWER, MAP, module, module_local_name(), NumberOfDimension(), pips_debug, storage_formal_p, ud(), and UPPER.

Referenced by put_generated_resources_for_common(), and put_generated_resources_for_module().

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

◆ max_size_of_processors()

int max_size_of_processors ( void  )

Definition at line 120 of file inits.c.

121 {
122  int current_max = 1;
123 
124  MAP(ENTITY, e,
125  {
126  variable a;
127 
128  pips_assert("variable", type_variable_p(entity_type(e)));
129  a = type_variable(entity_type(e));
130 
133  },
135 
136  return current_max;
137 }
static int current_max
#define max(a, b)
int element_number(basic, list)
END_EOLE.
Definition: size.c:391
#define type_variable_p(x)
Definition: ri.h:2947
#define variable_basic(x)
Definition: ri.h:3120

References current_max, element_number(), ENTITY, entity_type, list_of_processors(), MAP, max, pips_assert, type_variable, type_variable_p, variable_basic, and variable_dimensions.

Referenced by create_common_parameters_h().

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