PIPS
NewGen quick and intelligent recursion on objects (visitor pattern)
+ Collaboration diagram for NewGen quick and intelligent recursion on objects (visitor pattern):

Modules

 NewGen useful functions for recursion visitors
 They may be used by some recursion.
 
 NewGen inheritance tracking during visiting object
 Methods to get parent information constructed during recursion.
 

Functions

void gen_recurse_stop (void *obj)
 Tells the recursion not to go in this object. More...
 
static void gen_internal_context_multi_recurse (void *o, void *context, bool gointabs, va_list pvar)
 Multi recursion generic visitor function. More...
 
void gen_context_multi_recurse (void *o, void *context,...)
 Multi-recursion with context function visitor. More...
 
void gen_full_recurse (void *o, void *context,...)
 Full multi-recursion with context function visitor. More...
 
void gen_multi_recurse (void *o,...)
 Multi recursion visitor function. More...
 
void gen_recurse (void *obj, int domain, bool(*filter)(void *encountered), void(*rewrite)(void *encountered_object))
 Visit all the objects from a given types found in an object. More...
 
void gen_context_recurse (void *obj, void *context, int domain, bool(*filter)(void *encountered_object, void *context), void(*rewrite)(void *encountered_object, void *context))
 Visit all the objects from a given types found in an object with a context. More...
 

Detailed Description

Function Documentation

◆ gen_context_multi_recurse()

void gen_context_multi_recurse ( void *  o,
void *  context,
  ... 
)

Multi-recursion with context function visitor.

gen_context_multi_recurse(obj, context, [domain, filter, rewrite,]* NULL);

recurse from object obj (in a top-down way), applies filter_i on encountered domain_i objects with the context, if true, recurses down from the domain_i object, and applies rewrite_i on exit from the object (in a bottom-up way).

Newgen persistant fields are not visited.

You can't visit domain number 0, but there are none...

Definition at line 3373 of file genClib.c.

3374 {
3375  va_list pvar;
3376  va_start(pvar, context);
3378  va_end(pvar);
3379 }
static void gen_internal_context_multi_recurse(void *o, void *context, bool gointabs, va_list pvar)
Multi recursion generic visitor function.
Definition: genClib.c:3270
Definition: delay.c:253

References gen_internal_context_multi_recurse().

Referenced by add_counters(), atomize_all(), atomize_cse_this_statement_expressions(), bottom_up_abc_statement(), callers_to_call_sites(), collect_glopriv(), compute_callees(), convert_pointer_to_array(), cusq_ctxt_init(), eole_manageable_expression(), find_calls_to_function(), find_loops_and_calls_in_box(), forward_substitute_in_anyloop(), forward_substitute_in_call(), forward_substitute_in_exp(), freia_build_image_occurrences(), freia_compile(), freia_compute_output_images(), freia_shuffle_move_forward(), freia_switch_image_in_statement(), gen_context_recurse(), get_list_of_rhs(), get_referenced_entities_filtered(), group_constants(), guard_elimination(), guess_write_effect_on_entity(), initial_code_abc_statement(), instruction_selection(), interprocedural_abc_statement(), isolate_patch_entities(), live_out_paths_from_caller_to_callee(), live_paths_of_module_statement(), loop_statistics(), make_eliminate_original_variables(), make_mpi_conversion(), normalize_microcode(), outliner(), perform_substitution(), pips_code_abc_statement(), private_variables(), remove_redundant_communications(), remove_simple_scalar_pointers(), remove_statement_redundant(), replace_entities(), replace_entity_by_expression_with_filter(), search_nested_loops_and_calls(), sequence_working_false(), simdizer(), statement_flatten_declarations(), statement_to_called_user_entities(), statement_to_declarations(), statement_to_referenced_entities(), substitute_entity_in_expression(), substitute_image_occurrences(), test_working_false(), tiling_sequence(), top_down_abc_statement(), type_this_chunk(), and unstructured_to_flow_sensitive_postconditions_or_transformers().

+ Here is the call graph for this function:

◆ gen_context_recurse()

void gen_context_recurse ( void *  obj,
void *  context,
int  domain,
bool(*)(void *encountered_object, void *context filter,
void(*)(void *encountered_object, void *context rewrite 
)

Visit all the objects from a given types found in an object with a context.

Parameters
objthe object to start visiting
domainthe type of objects we want to visit
contextis a pointer that is given to the filter and rewrite methods too. It is quite useful when one wants side effects on other objects without having to rely on (dirty) global variables.
filterthe filter method (function) to apply to an encountered object of the good type during the prefix (top-down) visit. Its second argument is the context passed texto from the global context parameter. If the method returns true, the recursion is going on. If it returns false, the visit does not go further inside this object and the rewrite method is not be called during the bottom-up visit.
rewriteis the method (function) to apply to an encountered object of the good type during the prefix (bottom-up) visit. Its second argument is the context passed texto from the global context parameter
Parameters
objstarting point

Definition at line 3483 of file genClib.c.

3489 {
3490  gen_context_multi_recurse(obj, context, domain, filter, rewrite, NULL);
3491 }
void gen_context_multi_recurse(void *o, void *context,...)
Multi-recursion with context function visitor.
Definition: genClib.c:3373
A DOMAIN union describes the structure of a user type.

References gen_context_multi_recurse().

+ Here is the call graph for this function:

◆ gen_full_recurse()

void gen_full_recurse ( void *  o,
void *  context,
  ... 
)

Full multi-recursion with context function visitor.

gen_full_recurse(obj, context, [domain, filter, rewrite,]* NULL);

recurse from object obj (in a top-down way), applies filter_i on encountered domain_i objects with the context, if true, recurses down from the domain_i object, and applies rewrite_i on exit from the object (in a bottom-up way).

Newgen persistant fields and their contents ARE VISITED.

The current implementation does not try to be intelligent, thus will recurse anywhere until stopped by a decision or an object was already visited. Beware, if you do not take extra care, this mean visiting all entities and their contents when visiting from a statement in pips.

You can't visit domain number 0, but there are none.

Definition at line 3402 of file genClib.c.

3403 {
3404  va_list pvar;
3405  va_start(pvar, context);
3407  va_end(pvar);
3408 }

References gen_internal_context_multi_recurse().

+ Here is the call graph for this function:

◆ gen_internal_context_multi_recurse()

static void gen_internal_context_multi_recurse ( void *  o,
void *  context,
bool  gointabs,
va_list  pvar 
)
static

Multi recursion generic visitor function.

It is more intended for internal use, but may be useful instead of gen_context_multi_recurse() to give iteration parameters as a va_list.

Refer to the documentation of gen_context_multi_recurse().

Beware that the function is reentrant.

Definition at line 3269 of file genClib.c.

3274 {
3275  gen_chunk * obj = (gen_chunk*) o;
3276  int i, domain;
3277  GenFilterTableType new_filter_table;
3278  GenRewriteTableType new_rewrite_table;
3279  GenDecisionTableType new_decision_table, new_domain_table, *p_table;
3280  struct multi_recurse *saved_mrc, new_mrc;
3281  struct driver dr;
3282 
3283  message_assert("tabulated domain recursion is not implemented", !gointabs);
3284 
3286 
3287  // the object must be a valid newgen object
3288  message_assert("not null and defined object to visit",
3289  obj!=(gen_chunk*)NULL && obj!=gen_chunk_undefined);
3290 
3291  // initialize the new tables
3292  for(i=0; i<MAX_DOMAIN; i++)
3293  {
3294  new_domain_table[i] = false;
3295  new_decision_table[i] = false;
3296  new_filter_table[i] = NULL;
3297  new_rewrite_table[i] = NULL;
3298  }
3299 
3300  // read the arguments
3301  while((domain=va_arg(pvar, int)) != 0)
3302  {
3303  message_assert("domain specified once", !new_domain_table[domain]);
3304 
3305  new_domain_table[domain] = true;
3306  new_filter_table[domain] = va_arg(pvar, GenFilterType);
3307  new_rewrite_table[domain] = va_arg(pvar, GenRewriteType);
3308 
3309  for(i=0, p_table=get_decision_table(domain); i<number_of_domains; i++)
3310  new_decision_table[i] |= (*p_table)[i];
3311  }
3312 
3313  // initialize multi recurse stuff
3314  new_mrc.seen = hash_table_make(hash_pointer, 0),
3315  new_mrc.always_recurse = gointabs, // quick and dirty...
3316  new_mrc.domains = &new_domain_table,
3317  new_mrc.decisions = &new_decision_table,
3318  new_mrc.filters = &new_filter_table,
3319  new_mrc.rewrites = &new_rewrite_table,
3320  new_mrc.context = context;
3321  new_mrc.upwards = stack_make(0, 20, 0);
3322  new_mrc.previous = NULL;
3323  new_mrc.current = NULL;
3324 
3325  // initialize recursion driver
3326  // (should contains a pointer to previous one to pass the context,
3327  // instead of relying on a global variable...)
3328  dr.null = gen_null,
3329  dr.leaf_in = tabulated_leaf_in,
3330  dr.leaf_out = gen_null,
3331  dr.simple_in = quick_multi_recurse_simple_in,
3332  dr.array_leaf = gen_array_leaf,
3333  dr.simple_out = gen_null,
3334  dr.obj_in = quick_multi_recurse_obj_in,
3335  dr.obj_out = quick_multi_recurse_obj_out;
3336 
3337  // push the current context
3338  saved_mrc = current_mrc, current_mrc = &new_mrc;
3339 
3340  // recurse!
3341  gen_trav_stop_recursion = false;
3342  stack_push(NULL, new_mrc.upwards); // root is conventionaly set to NULL
3343  gen_trav_obj(obj, &dr);
3344  // if there was no interruption, the stack must be back to the root
3345  if (!gen_trav_stop_recursion) {
3346  message_assert("back to root", stack_size(current_mrc->upwards) == 1);
3347  void * popped = stack_pop(current_mrc->upwards);
3348  message_assert("back to root", popped == NULL);
3349  }
3350  gen_trav_stop_recursion = false;
3351 
3352  // cleanup, and restore the previous context
3353  hash_table_free(new_mrc.seen);
3354  stack_free(&new_mrc.upwards);
3355  current_mrc = saved_mrc;
3356 }
#define gen_chunk_undefined
Definition: genC.h:74
static bool gen_trav_stop_recursion
Definition: genClib.c:384
static int quick_multi_recurse_obj_in(gen_chunk *obj, __attribute__((unused)) struct driver *dr)
Definition: genClib.c:3154
static void gen_array_leaf(struct gen_binding *bp, int i, gen_chunk *obj, struct driver *dr)
GEN_ARRAY_LEAF is the default recursive call to gen_trav_leaf.
Definition: genClib.c:494
bool(* GenFilterType)()
Definition: genClib.c:3081
static struct multi_recurse * current_mrc
the current multi recurse driver.
Definition: genClib.c:3137
static int tabulated_leaf_in(gen_chunk *obj, struct gen_binding *bp)
Definition: genClib.c:620
static int quick_multi_recurse_simple_in(gen_chunk *obj, union domain *dp)
Definition: genClib.c:3224
void(* GenRewriteType)()
Definition: genClib.c:3082
static GenDecisionTableType * get_decision_table(int domain)
returns a decision table for the given domain.
Definition: genClib.c:3062
GenFilterType GenFilterTableType[MAX_DOMAIN]
Definition: genClib.c:3084
static int number_of_domains
Definition: genClib.c:2858
char GenDecisionTableType[MAX_DOMAIN]
Definition: genClib.c:2854
static void gen_trav_obj()
static void quick_multi_recurse_obj_out(gen_chunk *obj, __attribute__((unused)) struct gen_binding *bp, __attribute__((unused)) struct driver *dr)
Definition: genClib.c:3199
GenRewriteType GenRewriteTableType[MAX_DOMAIN]
Definition: genClib.c:3085
void gen_null(__attribute__((unused)) void *unused)
Ignore the argument.
Definition: genClib.c:2752
hash_table hash_table_make(hash_key_type key_type, size_t size)
Definition: hash.c:294
void hash_table_free(hash_table htp)
this function deletes a hash table that is no longer useful.
Definition: hash.c:327
#define message_assert(msg, ex)
Definition: newgen_assert.h:47
@ hash_pointer
Definition: newgen_hash.h:32
#define check_read_spec_performed()
#define MAX_DOMAIN
MAX_DOMAIN is the maximum number of entries in the DOMAINS table.
int stack_size(const stack)
observers
void stack_push(void *, stack)
stack use
Definition: stack.c:373
void stack_free(stack *)
type, bucket_size, policy
Definition: stack.c:292
stack stack_make(int, int, int)
allocation
Definition: stack.c:246
void * stack_pop(stack)
POPs one item from stack s.
Definition: stack.c:399
The DRIVER structure is used to monitor the general function which traverses objects.
Definition: genClib.c:365
the current data needed for a multi recursion are stored in a multi recurse struct.
Definition: genClib.c:3109
gen_chunk * previous
Definition: genClib.c:3127
bool always_recurse
Definition: genClib.c:3114
GenFilterTableType * filters
Definition: genClib.c:3120
GenDecisionTableType * decisions
Definition: genClib.c:3118
GenDecisionTableType * domains
Definition: genClib.c:3116
GenRewriteTableType * rewrites
Definition: genClib.c:3121
gen_chunk * current
Definition: genClib.c:3129
void * context
Definition: genClib.c:3123
stack upwards
Definition: genClib.c:3125
hash_table seen
Definition: genClib.c:3111
A gen_chunk is used to store every object.
Definition: genC.h:58

References multi_recurse::always_recurse, driver::array_leaf, check_read_spec_performed, multi_recurse::context, multi_recurse::current, current_mrc, multi_recurse::decisions, multi_recurse::domains, multi_recurse::filters, gen_array_leaf(), gen_chunk_undefined, gen_null(), gen_trav_obj(), gen_trav_stop_recursion, get_decision_table(), hash_pointer, hash_table_free(), hash_table_make(), driver::leaf_in, driver::leaf_out, MAX_DOMAIN, message_assert, driver::null, number_of_domains, driver::obj_in, driver::obj_out, multi_recurse::previous, quick_multi_recurse_obj_in(), quick_multi_recurse_obj_out(), quick_multi_recurse_simple_in(), multi_recurse::rewrites, multi_recurse::seen, driver::simple_in, driver::simple_out, stack_free(), stack_make(), stack_pop(), stack_push(), stack_size(), tabulated_leaf_in(), and multi_recurse::upwards.

Referenced by gen_context_multi_recurse(), gen_full_recurse(), and gen_multi_recurse().

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

◆ gen_multi_recurse()

void gen_multi_recurse ( void *  o,
  ... 
)

Multi recursion visitor function.

gen_context_multi_recurse(obj, context, [domain, filter, rewrite,]* NULL);

recurse from object obj (in a top-down way), applies filter_i on encountered domain_i objects with the context, if true, recurses down from the domain_i object, and applies rewrite_i on exit from the object (in a bottom-up way).

Newgen persistant fields are not visited.

Bug : you can't visit domain number 0 if any... The good news is that there is no NewGen object of domain number 0, since it seems that to start at 7 for user domains...

Definition at line 3428 of file genClib.c.

3429 {
3430  va_list pvar;
3431  va_start(pvar, o);
3432  gen_internal_context_multi_recurse(o, NULL, false, pvar);
3433  va_end(pvar);
3434 }

References gen_internal_context_multi_recurse().

Referenced by add_alias_pairs_for_this_caller(), add_aliases_for_current_caller(), atomize_object(), bourdoncle_component(), bourdoncle_partition(), bourdoncle_unstructured_free(), build_binary_operators_with_huffman(), build_full_ctrl_graph(), compute_proper_reductions(), count_references_to_variable(), count_references_to_variable_element(), debug_print_referenced_entities(), do_array_to_pointer_walker(), do_linearize_array_walker(), drop_dummy_loops(), drop_it(), equal_reference_in_expression_p(), expression_substitution(), extract_distributed_non_constant_terms(), find_reference_to_variable(), FindRefToDistArray(), FindRefToDistArrayInStatement(), gen_multi_recurse_explorer(), gen_recurse(), get_all_entities(), get_operator(), handle_hpf_directives(), icm_codegen(), list_of_referenced_entities(), node_to_linked_nodes(), nodecl_p(), normalize_all_expressions_of(), normalize_first_expressions_of(), only_io_mapping(), out_regions_from_caller_to_callee(), output_the_attachments_for_emacs(), parallel_loop_nest_to_body(), perform_ac_cse(), perform_icm_association(), print_embedding_graph(), print_module_icfg(), print_unstructured(), remove_variable_from_reduction(), simple_statement(), simple_switch_old_to_new(), simplify_constant_address_expressions(), sort_all_loop_locals(), split_update_operator(), statement_structural_cleaning(), statement_to_line_number(), step_directive_parser(), subarray_shift_p(), substitute_return(), unnormalize_expression(), unstructured_shallow_copy(), unstructured_to_flow_sensitive_postconditions_or_transformers(), unstructured_to_transformer(), update_common_references_in_obj(), update_object_for_module(), update_precondition_with_call_site_preconditions(), and variable_declaration_coherency_p().

+ Here is the call graph for this function:

◆ gen_recurse()

void gen_recurse ( void *  obj,
int  domain,
bool(*)(void *encountered)  filter,
void(*)(void *encountered_object)  rewrite 
)

Visit all the objects from a given types found in an object.

Parameters
objthe object to start visiting
domainthe type of objects we want to visit
filterthe filter method (function) to apply to an encountered object of the good type during the prefix (top-down) visit. If it returns true, the recursion is going on and the rewrite filter will be called during the bottom-up visit. If it returns false, the visit does not go further inside this object and the rewrite method will not be called during the bottom-up visit.
rewriteis the method (function) to apply to an encountered object of the good type during the prefix (bottom-up) visit
Parameters
objstarting point

Definition at line 3452 of file genClib.c.

3457 {
3458  gen_multi_recurse(obj, domain, filter, rewrite, NULL);
3459 }
void gen_multi_recurse(void *o,...)
Multi recursion visitor function.
Definition: genClib.c:3428

References gen_multi_recurse().

+ Here is the call graph for this function:

◆ gen_recurse_stop()

void gen_recurse_stop ( void *  obj)

Tells the recursion not to go in this object.

This may be interesting when the recursion modifies the visited data structure. if obj is NULL, the whole recursion is stopped !

Definition at line 3251 of file genClib.c.

3252 {
3253  if (obj)
3254  hash_put(current_mrc->seen, obj, obj);
3255  else
3256  gen_trav_stop_recursion = true;
3257 }
void hash_put(hash_table htp, const void *key, const void *val)
This functions stores a couple (key,val) in the hash table pointed to by htp.
Definition: hash.c:364

References current_mrc, gen_trav_stop_recursion, hash_put(), and multi_recurse::seen.

Referenced by atom_cse_expression(), atomize_call_filter(), call_count_flt(), call_flt(), cannot_be_empty(), check_private_variables_call_walker(), check_simple(), cse_atom_call_flt(), cse_call_flt(), do_check_isolate_statement_preconditions_on_call(), do_kernelize(), do_recurse_statements_conflict_p(), do_substitute(), do_terapix_loop_optimizer(), do_terapix_pointer_initialized_from_a_mask_p(), does_it_depend(), entity_to_declaring_statement_aux(), entity_used_in_calls_walker(), entity_used_somewhere_walker(), fcs_count(), figure_out_if_it_is_a_format(), find_loop_from_label_walker(), find_statements_interactively_walker(), find_statements_with_label_walker(), find_statements_with_pragma_walker(), fsr_call_flt(), fsr_reference_flt(), guess_write_effect_on_entity_walker(), image_ref_flt(), inline_has_inlinable_calls_crawler(), insert_before_current_statement(), inv_entity_filter(), loop_flt(), loop_stop(), not_simple(), reductions_rewrite(), reference_filter(), reference_rwt(), related_effect(), replace_statement_walker(), simplify_complex_expression(), solve_name_clashes(), statement_in_statement_walker(), swis_call_flt(), test_stop(), top_down_abc_insert_before_statement(), vis_rwt(), and while_stop().

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