PIPS
liveness_analysis_engine.c File Reference
#include <stdio.h>
#include <string.h>
#include "genC.h"
#include "linear.h"
#include "ri.h"
#include "effects.h"
#include "database.h"
#include "misc.h"
#include "ri-util.h"
#include "effects-util.h"
#include "constants.h"
#include "text-util.h"
#include "text.h"
#include "properties.h"
#include "pipsdbm.h"
#include "resources.h"
#include "pointer_values.h"
#include "effects-generic.h"
#include "prettyprint.h"
+ Include dependency graph for liveness_analysis_engine.c:

Go to the source code of this file.

Data Structures

struct  live_paths_analysis_context
 
struct  live_out_summary_engine_context
 

Functions

static void init_live_paths_context (live_paths_analysis_context *ctxt, effects_representation_val representation)
 
static void reset_live_paths_context (live_paths_analysis_context *ctxt)
 
static list convert_rw_effects (list lrw, live_paths_analysis_context *ctxt)
 
static void reset_converted_rw_effects (list *lrw, live_paths_analysis_context *ctxt)
 
static list convert_in_effects (list lin, live_paths_analysis_context *ctxt)
 
static void reset_converted_in_effects (list *lin, live_paths_analysis_context *ctxt)
 
bool live_in_summary_paths_engine (const char *module_name)
 liveness_analysis_engine.c More...
 
static void set_live_out_summary_engine_context (live_out_summary_engine_context *ctxt, entity callee)
 
static void reset_live_out_summary_engine_context (live_out_summary_engine_context *ctxt)
 
static void update_live_out_summary_engine_context_paths (live_out_summary_engine_context *ctxt, list l_paths)
 
static bool live_out_paths_from_call_site_to_callee (call c, live_out_summary_engine_context *ctxt)
 
static bool live_out_summary_paths_stmt_filter (statement s, __attribute__((unused)) live_out_summary_engine_context *ctxt)
 
static void live_out_paths_from_caller_to_callee (entity caller, entity callee, live_out_summary_engine_context *ctxt)
 
bool live_out_summary_paths_engine (const char *module_name)
 
static void live_in_paths_of_statement (statement s, live_paths_analysis_context *ctxt)
 
static bool live_out_paths_from_unstructured_to_nodes (unstructured unstr, live_paths_analysis_context *ctxt)
 
static bool live_out_paths_from_forloop_to_body (forloop l, live_paths_analysis_context *ctxt)
 
static bool live_out_paths_from_whileloop_to_body (whileloop l, live_paths_analysis_context *ctxt)
 
static void live_in_paths_of_whileloop (whileloop l, live_paths_analysis_context *ctxt)
 
static bool live_out_paths_from_loop_to_body (loop l, live_paths_analysis_context *ctxt)
 
static void live_in_paths_of_loop (loop l, live_paths_analysis_context *ctxt)
 
static bool live_out_paths_from_test_to_branches (test t, _UNUSED_ live_paths_analysis_context *ctxt)
 
static bool live_paths_from_block_to_statements (sequence seq, live_paths_analysis_context *ctxt)
 
static void live_paths_of_module_statement (statement stmt, live_paths_analysis_context *ctxt)
 
bool live_paths_engine (const char *module_name, effects_representation_val representation)
 
static Psysteme new_system_with_only_live_variable (Psysteme sc, reference ref, list llivein, list lliveout)
 Create a new nsc system from the sc system of a region. More...
 
static bool filter_live_out_regions_statement (statement st)
 For each statement store the new live_out_regions. More...
 
bool live_out_region_engine (const char *module_name, __attribute__((unused)) effects_representation_val representation)
 

Function Documentation

◆ convert_in_effects()

static list convert_in_effects ( list  lin,
live_paths_analysis_context ctxt 
)
static

◆ convert_rw_effects()

static list convert_rw_effects ( list  lrw,
live_paths_analysis_context ctxt 
)
static

Definition at line 92 of file liveness_analysis_engine.c.

93 {
94  if (!ctxt->memory_effects_only)
95  lrw = effects_store_effects(lrw);
96 
97  return lrw;
98 }

References effects_store_effects(), and live_paths_analysis_context::memory_effects_only.

Referenced by live_in_paths_of_loop(), live_in_paths_of_statement(), live_in_paths_of_whileloop(), live_out_paths_from_forloop_to_body(), live_out_paths_from_loop_to_body(), and live_out_paths_from_whileloop_to_body().

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

◆ filter_live_out_regions_statement()

static bool filter_live_out_regions_statement ( statement  st)
static

For each statement store the new live_out_regions.

Definition at line 1339 of file liveness_analysis_engine.c.

1339  {
1340  ifdebug(1) {
1341  pips_debug(1, "begin with statement:\n");
1342  print_statement(st);
1343  }
1344  list llivein = load_live_in_paths_list(st);
1345  list lliveout = load_live_out_paths_list(st);
1346  list loutregions = load_statement_out_regions(st);
1347  list lliveoutreg = NIL;
1348 
1349  FOREACH(EFFECT, reg, loutregions) {
1350  reference rreg = effect_any_reference(reg);
1351  descriptor dreg = effect_descriptor(reg);
1352  switch (descriptor_tag(dreg)) {
1353  case is_descriptor_none:
1354  pips_debug(3, "scalar region");
1355  lliveoutreg = CONS(EFFECT, (*effect_dup_func)(reg), lliveoutreg);
1356  break;
1357  case is_descriptor_convex:
1358  {
1359  pips_debug(3, "convex region");
1360  Psysteme sc = descriptor_convex(dreg);
1361  Psysteme nsc = new_system_with_only_live_variable(sc, rreg, llivein, lliveout);
1362  effect r = make_effect(
1363  copy_cell(effect_cell(reg)),
1364  copy_action(effect_action(reg)),
1366  make_descriptor_convex(nsc) );
1367  lliveoutreg = CONS(EFFECT, r, lliveoutreg);
1368  break;
1369  }
1371  pips_debug(3, "convex union region");
1372  pips_internal_error("Not done yet...\n");
1373  //can use new_system_with_only_live_variable for each sc
1374  break;
1375  default:
1376  pips_internal_error("This case never occurs\n descriptor = %d\n", descriptor_tag(dreg));
1377  break;
1378  }
1379  }
1380 
1381  // memorize the new live_out_regions for the statement.
1382  store_live_out_regions_list(st, lliveoutreg);
1383 
1384  ifdebug(1) {
1385  pips_debug(1, "end statement:\n");
1386  print_statement(st);
1387  }
1388  return true;
1389 }
action copy_action(action p)
ACTION.
Definition: effects.c:77
descriptor make_descriptor_convex(Psysteme _field_)
Definition: effects.c:439
approximation copy_approximation(approximation p)
APPROXIMATION.
Definition: effects.c:132
effect make_effect(cell a1, action a2, approximation a3, descriptor a4)
Definition: effects.c:484
cell copy_cell(cell p)
CELL.
Definition: effects.c:246
list load_live_out_paths_list(statement)
list load_live_in_paths_list(statement)
void store_live_out_regions_list(statement, list)
list load_statement_out_regions(statement)
effect(* effect_dup_func)(effect eff)
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
#define descriptor_tag(x)
Definition: effects.h:595
#define effect_action(x)
Definition: effects.h:642
@ is_descriptor_none
Definition: effects.h:576
@ is_descriptor_convexunion
Definition: effects.h:574
@ is_descriptor_convex
Definition: effects.h:575
#define effect_descriptor(x)
Definition: effects.h:646
#define descriptor_convex(x)
Definition: effects.h:601
#define effect_approximation(x)
Definition: effects.h:644
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
#define effect_cell(x)
Definition: effects.h:640
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
#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
static Psysteme new_system_with_only_live_variable(Psysteme sc, reference ref, list llivein, list lliveout)
Create a new nsc system from the sc system of a region.
#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_internal_error
Definition: misc-local.h:149
void print_statement(statement)
Print a statement on stderr.
Definition: statement.c:98
#define ifdebug(n)
Definition: sg.c:47
The structure used to build lists in NewGen.
Definition: newgen_list.h:41

References CONS, copy_action(), copy_approximation(), copy_cell(), descriptor_convex, descriptor_tag, EFFECT, effect_action, effect_any_reference, effect_approximation, effect_cell, effect_descriptor, effect_dup_func, FOREACH, ifdebug, is_descriptor_convex, is_descriptor_convexunion, is_descriptor_none, load_live_in_paths_list(), load_live_out_paths_list(), load_statement_out_regions(), make_descriptor_convex(), make_effect(), new_system_with_only_live_variable(), NIL, pips_debug, pips_internal_error, print_statement(), and store_live_out_regions_list().

Referenced by live_out_region_engine().

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

◆ init_live_paths_context()

static void init_live_paths_context ( live_paths_analysis_context ctxt,
effects_representation_val  representation 
)
static

Definition at line 67 of file liveness_analysis_engine.c.

69 {
70  ctxt->memory_effects_only = get_bool_property("MEMORY_EFFECTS_ONLY");
71  ctxt->memory_in_out_effects_only = get_bool_property("MEMORY_IN_OUT_EFFECTS_ONLY");
72  if (! ctxt->memory_effects_only)
73  // if the MEMORY_EFFECTS_ONLY is FALSE on input,
74  // we have to temporarily set MEMORY_EFFECTS_ONLY to
75  // TRUE so that functions computing R/W effects
76  // do not compute non memory effects which would have to be filtered.
77  set_bool_property("MEMORY_EFFECTS_ONLY", true);
78  ctxt->representation = representation;
79 }
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
void set_bool_property(const char *, bool)
effects_representation_val representation

References get_bool_property(), live_paths_analysis_context::memory_effects_only, live_paths_analysis_context::memory_in_out_effects_only, live_paths_analysis_context::representation, and set_bool_property().

Referenced by live_paths_engine().

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

◆ live_in_paths_of_loop()

static void live_in_paths_of_loop ( loop  l,
live_paths_analysis_context ctxt 
)
static

The live in paths of a loop statement are the live in paths of its header plus the live in paths of its first iteration if it is exectuted

If the loop belongs to a sequence of statements, which is generally the case, its live in paths have already been computed. I don't yet know if they may be much more precisely computed here. For performance reasons, I don't try to recompute them if they are already available. The code below is likely to be seldom executed; however, it has been tested on small cases.

Live in effects of header

We assume that there is no side effect in the loop header; thus the live in effects of the header are similar to its proper read effects

Live in effects of first iteration if it exists minus read effects on the loop index, which are masked by its initialization in the header, and read effects on loop locals if the loop is parallel;

beware: potential sharing with loop_locals(l)

free l_masked_vars: beware of the potential sharing with loop_locals

put them together

Definition at line 952 of file liveness_analysis_engine.c.

953 {
954  /* The live in paths of a loop statement are the live in paths of its header
955  * plus the live in paths of its first iteration if it is exectuted
956  */
957 
958  statement
960  statement
961  body = loop_body(l);
962  entity
963  index = loop_index(l);
964 
965  pips_debug(1,"begin\n");
966 
967  /* If the loop belongs to a sequence of statements, which is
968  * generally the case, its live in paths have already been computed.
969  * I don't yet know if they may be much more precisely computed here.
970  * For performance reasons, I don't try to recompute them if they
971  * are already available.
972  * The code below is likely to be seldom executed;
973  * however, it has been tested on small cases.
974  */
976  {
977 
978  /* Live in effects of header */
979  /* We assume that there is no side effect in the loop header;
980  * thus the live in effects of the header are similar to its proper read effects
981  */
983  ctxt);
984  list l_live_in_header =
986  reset_converted_rw_effects(&l_prop_header, ctxt);
987  pips_debug_effects(3, "live in paths of loop header:\n", l_live_in_header);
988 
989  /* Live in effects of first iteration if it exists minus read effects
990  * on the loop index, which are masked by its initialization in the header,
991  * and read effects on loop locals if the loop is parallel;
992  */
993  list l_masked_vars = NIL;
994  if(loop_parallel_p(l))
995  l_masked_vars = loop_locals(l);
996  /* beware: potential sharing with loop_locals(l) */
997  l_masked_vars = CONS(ENTITY, index, l_masked_vars);
998 
999  list l_live_in_first_iter =
1001  l_masked_vars);
1002 
1003  /* free l_masked_vars: beware of the potential sharing with loop_locals */
1004  if (loop_parallel_p(l) && !ENDP(l_masked_vars))
1005  CDR(l_masked_vars) = NIL;
1006  gen_free_list(l_masked_vars);
1007 
1008  if (! normalizable_and_linear_loop_p(index, loop_range(l)))
1009  {
1010  pips_debug(7, "non linear loop range.\n");
1011  effects_to_may_effects(l_live_in_first_iter);
1012  }
1013  // functions that can be pointed by loop_descriptor_make_func:
1014  // loop_undefined_descriptor_make
1015  // loop_convex_descriptor_make
1017  {
1018  if (loop_executed_never_p(l)) {
1019  //l_live_in_first_iter must had been a duplicated effect, so need to free them
1020  gen_full_free_list(l_live_in_first_iter);
1021  l_live_in_first_iter = NIL;
1022  }
1023  else if (!loop_executed_at_least_once_p(l))
1024  effects_to_may_effects(l_live_in_first_iter);
1025  }
1026  else
1027  {
1028  pips_internal_error("live paths of loop not implemented for convex paths\n");
1029  }
1030 
1031  pips_debug_effects(3, "live in paths of loop first iteration:\n", l_live_in_header);
1032 
1033  /* put them together */
1034  // functions that can be pointed by effects_union_op:
1035  // ProperEffectsMustUnion
1036  // RegionsMustUnion
1037  // ReferenceUnion
1038  // EffectsMustUnion
1039  list l_live_in_loop = (*effects_union_op)(l_live_in_header,
1040  l_live_in_first_iter,
1042 
1043  pips_debug_effects(3, "live in paths of loop:\n", l_live_in_loop);
1044 
1045  store_live_in_paths_list(current_stmt, l_live_in_loop);
1046  }
1047 
1048  pips_debug(1,"end\n");
1049 }
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
static statement current_stmt
#define pips_debug_effects(level, message, l_eff)
void effects_to_may_effects(list)
list effects_read_effects_dup(list)
list proper_to_summary_effects(list)
list load_proper_rw_effects_list(statement)
descriptor(* loop_descriptor_make_func)(loop)
descriptor loop_undefined_descriptor_make(loop)
bool normalizable_and_linear_loop_p(entity, range)
void store_live_in_paths_list(statement, list)
bool bound_live_in_paths_p(statement)
list effects_dup_without_variables(list, list)
bool effects_same_action_p(effect, effect)
void gen_full_free_list(list l)
Definition: genClib.c:1023
gen_chunk * gen_get_ancestor(int, const void *)
return the first ancestor object found of the given type.
Definition: genClib.c:3560
bool loop_parallel_p(loop l)
Test if a loop is parallel.
Definition: loop.c:393
bool loop_executed_never_p(loop l)
Check if loop bound are constant and then if upper < lower.
Definition: loop.c:971
bool loop_executed_at_least_once_p(loop l)
Check if loop bound are constant and then if upper >= lower.
Definition: loop.c:937
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
static void reset_converted_rw_effects(list *lrw, live_paths_analysis_context *ctxt)
static list convert_rw_effects(list lrw, live_paths_analysis_context *ctxt)
#define loop_body(x)
Definition: ri.h:1644
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
#define loop_locals(x)
Definition: ri.h:1650
#define loop_range(x)
Definition: ri.h:1642
#define loop_index(x)
Definition: ri.h:1640

References bound_live_in_paths_p(), CDR, CONS, convert_rw_effects(), current_stmt, effects_dup_without_variables(), effects_read_effects_dup(), effects_same_action_p(), effects_to_may_effects(), ENDP, ENTITY, gen_free_list(), gen_full_free_list(), gen_get_ancestor(), load_live_in_paths_list(), load_proper_rw_effects_list(), loop_body, loop_descriptor_make_func, loop_executed_at_least_once_p(), loop_executed_never_p(), loop_index, loop_locals, loop_parallel_p(), loop_range, loop_undefined_descriptor_make(), NIL, normalizable_and_linear_loop_p(), pips_debug, pips_debug_effects, pips_internal_error, proper_to_summary_effects(), reset_converted_rw_effects(), statement_domain, and store_live_in_paths_list().

Referenced by live_paths_of_module_statement().

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

◆ live_in_paths_of_statement()

static void live_in_paths_of_statement ( statement  s,
live_paths_analysis_context ctxt 
)
static

live in paths may have already been computed, for instance for sequences

First, we get the live out paths of the statement

Live_in(S) = (live_out(S) o T(S) - W(S)) U IN (S)

first take care of declarations

Definition at line 361 of file liveness_analysis_engine.c.

363 {
364  /* live in paths may have already been computed,
365  * for instance for sequences
366  */
367  pips_debug(1,"begin for statement with ordering: %03zd and number: %03zd\n",
369 
370  if ( !bound_live_in_paths_p(s) )
371  {
372  pips_debug(1, "not bound\n");
373  /* First, we get the live out paths of the statement */
374  list l_live_out = effects_dup(load_live_out_paths_list(s));
375 
376  /* Live_in(S) = (live_out(S) o T(S) - W(S)) U IN (S) */
377 
378  /* first take care of declarations */
381  {
383  storage decl_storage = entity_storage(decl);
384  if (storage_ram_p(decl_storage)
385  // keep paths on static variables
386  && !static_area_p(ram_section(storage_ram(decl_storage))))
387  l_live_out = filter_effects_with_declaration(l_live_out, decl);
388  }
389  }
390 
391  // then move the live_out effects of the statement in the store
392  // before the statement
393  transformer t = (*load_completed_transformer_func)(s);
394 
395  // functions that can be pointed by effects_transformer_composition_op:
396  // effects_composition_with_transformer_nop
397  // effects_undefined_composition_with_transformer
398  // convex_regions_transformer_compose
399  // simple_effects_composition_with_effect_transformer
400  (*effects_transformer_composition_op)(l_live_out, t);
401 
402  // next, remove the effects written by the statement
403  // and add the in effects of the statement
405  list l_write = effects_write_effects_dup(l_rw);
406  pips_debug_effects(5, "write effects:\n", l_write);
407 
409  pips_debug_effects(5, "in effects:\n", l_in);
410 
411  // functions that can be pointed by effects_union_op:
412  // ProperEffectsMustUnion
413  // RegionsMustUnion
414  // ReferenceUnion
415  // EffectsMustUnion
416  // functions that can be pointed by effects_sup_difference_op:
417  // effects_undefined_binary_operator
418  // RegionsSupDifference
419  // EffectsSupDifference
420  list l_live_in = (*effects_union_op)(
421  effects_dup(l_in),
422  (*effects_sup_difference_op)(l_live_out, l_write,
425  pips_debug_effects(5, "resulting live in paths:\n", l_live_in);
426 
427 
428  store_live_in_paths_list(s, l_live_in);
429 
430  reset_converted_rw_effects(&l_rw, ctxt);
431  reset_converted_in_effects(&l_in, ctxt);
432 
433  }
434  pips_debug(1,"end\n");
435  return;
436 }
list effects_write_effects_dup(list)
list load_in_effects_list(statement)
list effects_dup(list)
list filter_effects_with_declaration(list, entity)
list load_rw_effects_list(statement)
bool r_w_combinable_p(effect, effect)
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
bool declaration_statement_p(statement)
Had to be optimized according to Beatrice Creusillet.
Definition: statement.c:224
static void reset_converted_in_effects(list *lin, live_paths_analysis_context *ctxt)
static list convert_in_effects(list lin, live_paths_analysis_context *ctxt)
bool static_area_p(entity aire)
Definition: area.c:77
bool c_module_p(entity m)
Test if a module "m" is written in C.
Definition: entity.c:2777
#define statement_ordering(x)
Definition: ri.h:2454
#define entity_storage(x)
Definition: ri.h:2794
#define storage_ram_p(x)
Definition: ri.h:2519
#define ram_section(x)
Definition: ri.h:2249
#define statement_declarations(x)
Definition: ri.h:2460
#define storage_ram(x)
Definition: ri.h:2521
#define statement_number(x)
Definition: ri.h:2452

References bound_live_in_paths_p(), c_module_p(), convert_in_effects(), convert_rw_effects(), declaration_statement_p(), effects_dup(), effects_same_action_p(), effects_write_effects_dup(), ENTITY, entity_storage, filter_effects_with_declaration(), FOREACH, get_current_module_entity(), load_in_effects_list(), load_live_out_paths_list(), load_rw_effects_list(), pips_debug, pips_debug_effects, r_w_combinable_p(), ram_section, reset_converted_in_effects(), reset_converted_rw_effects(), statement_declarations, statement_number, statement_ordering, static_area_p(), storage_ram, storage_ram_p, and store_live_in_paths_list().

Referenced by live_paths_from_block_to_statements(), and live_paths_of_module_statement().

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

◆ live_in_paths_of_whileloop()

static void live_in_paths_of_whileloop ( whileloop  l,
live_paths_analysis_context ctxt 
)
static

If the loop belongs to a sequence of statements, which is generally the case, its live in paths have already been computed. I don't yet know if they may be much more precisely computed here. For performance reasons, I don't try to recompute them if they are already available. see also the comment inside the else branch of if (!before_p) about the way of computing live in paths. The code below is likely to be seldom executed; however, it has been tested on small cases.

the live in paths of the loop are either those of the first iteration if there is one, or the live out paths of the whole loop is there is no iteration; we must remove the write effects and add the in effects of the condition evaluation

As we currently only compute simple live paths, I wonder if there is a difference with the live out paths of the loop body...

Get the live out paths of the whole loop

It may be executed...

...or the first iteration of the loop body

Take into account the effects of the condition

We don't have the in effects of the condition evaluation we safely approximate them by its may read proper effects if there are write effects during its evaluation

Definition at line 725 of file liveness_analysis_engine.c.

726 {
727  statement
729  bool before_p = evaluation_before_p(whileloop_evaluation(l));
730  statement body = whileloop_body(l);
731 
732  list l_live_in_loop = NIL;
733 
734  pips_debug(1,"begin\n");
735 
736  /* If the loop belongs to a sequence of statements, which is
737  * generally the case, its live in paths have already been computed.
738  * I don't yet know if they may be much more precisely computed here.
739  * For performance reasons, I don't try to recompute them if they
740  * are already available.
741  * see also the comment inside the else branch of if (!before_p)
742  * about the way of computing live in paths.
743  * The code below is likely to be seldom executed;
744  * however, it has been tested on small cases.
745  */
747  {
748  list l_live_in_body = effects_dup(load_live_in_paths_list(body));
749  pips_debug_effects(3, "live in paths of loop body:\n", l_live_in_body);
750 
751  if (!before_p)
752  {
753  pips_debug(1, "do while loop: live in paths are those of the body\n");
754  l_live_in_loop = l_live_in_body;
755  }
756  else
757  {
758  /* the live in paths of the loop are either those of the
759  * first iteration if there is one, or the live out paths
760  * of the whole loop is there is no iteration;
761  * we must remove the write effects and add the in effects
762  * of the condition evaluation
763  */
764 
765  /* As we currently only compute simple live paths,
766  * I wonder if there is a difference with the live out paths
767  * of the loop body...
768  */
769 
770  /* Get the live out paths of the whole loop
771  */
773  pips_debug_effects(3, "live out paths of whole loop:\n", l_live_out_loop);
774  effects_to_may_effects(l_live_out_loop); /* It may be executed... */
775 
776  /* ...or the first iteration of the loop body */
777  effects_to_may_effects(l_live_in_body);
778 
779  // functions that can be pointed by effects_union_op:
780  // ProperEffectsMustUnion
781  // RegionsMustUnion
782  // ReferenceUnion
783  // EffectsMustUnion
784  list l_live_out_after_cond =
785  (*effects_union_op)(l_live_out_loop,
786  l_live_in_body,
788 
789  pips_debug_effects(3, "live out paths after first condition evaluation:\n",
790  l_live_out_after_cond);
791 
792  /* Take into account the effects of the condition */
793  list l_prop_cond =
795 
796  list l_write_cond =
798  pips_debug_effects(3, "write effects of condition:\n", l_write_cond);
799 
800  /* We don't have the in effects of the condition evaluation
801  * we safely approximate them by its may read proper effects
802  * if there are write effects during its evaluation
803  */
804  list l_in_cond =
806  if (!ENDP(l_write_cond)) effects_to_may_effects(l_in_cond);
807  pips_debug_effects(3, "approximation of in effects of condition:\n",
808  l_in_cond);
809 
810  // functions that can be pointed by effects_union_op:
811  // ProperEffectsMustUnion
812  // RegionsMustUnion
813  // ReferenceUnion
814  // EffectsMustUnion
815  // functions that can be pointed by effects_sup_difference_op:
816  // effects_undefined_binary_operator
817  // RegionsSupDifference
818  // EffectsSupDifference
819  l_live_in_loop =
820  (*effects_union_op)(l_in_cond,
821  (*effects_sup_difference_op)(l_live_out_after_cond,
822  l_write_cond,
825 
826  reset_converted_rw_effects(&l_prop_cond, ctxt);
827  }
828 
829  pips_debug_effects(3, "live in paths of loop:\n", l_live_in_loop);
830 
831  store_live_in_paths_list(current_stmt, l_live_in_loop);
832  }
833  else
834  {
835  pips_debug(1, "already bound\n");
836  }
837 
838  pips_debug(1,"end\n");
839 
840  return;
841 }
#define whileloop_evaluation(x)
Definition: ri.h:3166
#define whileloop_body(x)
Definition: ri.h:3162
#define evaluation_before_p(x)
Definition: ri.h:1159

References bound_live_in_paths_p(), convert_rw_effects(), current_stmt, effects_dup(), effects_read_effects_dup(), effects_same_action_p(), effects_to_may_effects(), effects_write_effects_dup(), ENDP, evaluation_before_p, gen_get_ancestor(), load_live_in_paths_list(), load_live_out_paths_list(), load_proper_rw_effects_list(), NIL, pips_debug, pips_debug_effects, proper_to_summary_effects(), r_w_combinable_p(), reset_converted_rw_effects(), statement_domain, store_live_in_paths_list(), whileloop_body, and whileloop_evaluation.

Referenced by live_paths_of_module_statement().

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

◆ live_in_summary_paths_engine()

bool live_in_summary_paths_engine ( const char *  module_name)

liveness_analysis_engine.c

Parameters
module_nameodule_name

Definition at line 130 of file liveness_analysis_engine.c.

131 {
132  list l_glob = NIL, l_loc = NIL;
133  statement module_stat;
134 
137  db_get_memory_resource(DBR_CODE, module_name, true) );
138  module_stat = get_current_module_statement();
139 
140  // functions that can be pointed by effects_computation_init_func:
141  // effects_computation_no_init
142  // init_convex_in_out_regions
143  // init_convex_rw_regions
144  (*effects_computation_init_func)(module_name);
145 
147 
148  l_loc = load_live_in_paths_list(module_stat);
149 
150  // functions that can be pointed by effects_local_to_global_translation_op:
151  // effects_dynamic_elim
152  // regions_dynamic_elim
153  l_glob = (*effects_local_to_global_translation_op)(l_loc);
154 
155  (*db_put_live_in_summary_paths_func)(module_name, l_glob);
156 
160 
161  // functions that can be pointed by effects_computation_reset_func:
162  // effects_computation_no_reset
163  // reset_convex_in_out_regions
164  // reset_convex_rw_regions
165  (*effects_computation_reset_func)(module_name);
166 
167  return true;
168 }
void set_live_in_paths(statement_effects)
statement_effects(* db_get_live_in_paths_func)(const char *)
void reset_live_in_paths(void)
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
void reset_current_module_entity(void)
Reset the current module entity.
Definition: static.c:97
void reset_current_module_statement(void)
Reset the current module statement.
Definition: static.c:221
statement set_current_module_statement(statement)
Set the current module statement.
Definition: static.c:165
statement get_current_module_statement(void)
Get the current module statement.
Definition: static.c:208
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
string db_get_memory_resource(const char *rname, const char *oname, bool pure)
Return the pointer to the resource, whatever it is.
Definition: database.c:755
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479

References db_get_live_in_paths_func, db_get_memory_resource(), get_current_module_statement(), load_live_in_paths_list(), module_name(), module_name_to_entity(), NIL, reset_current_module_entity(), reset_current_module_statement(), reset_live_in_paths(), set_current_module_entity(), set_current_module_statement(), and set_live_in_paths().

+ Here is the call graph for this function:

◆ live_out_paths_from_call_site_to_callee()

static bool live_out_paths_from_call_site_to_callee ( call  c,
live_out_summary_engine_context ctxt 
)
static

there is a problem here because the context is in the store preceding the statement whereas live_out_paths hold after the statement. So I think I must apply the transformer to get the post-condition. That's ok for simple paths since they are store independent. BC.

There may also be a problem here in C, because calls may be anywhere inside an expression, and not solely as standalone statements. It may be better to call this function during the intraprocedural analysis of callers and not during a standalone phase which would have to deal with calls in sub-expressions, and thus also with store/pointers modifications. BC.

Definition at line 209 of file liveness_analysis_engine.c.

210 {
211  pips_debug(1, "considering call to %s\n", entity_name(call_function(c)));
212  pips_debug(2, "current context callee: %s\n", entity_name(ctxt->current_callee));
213 
214  if (call_function(c) != ctxt->current_callee)
215  {
216  return (true);
217  }
218  pips_debug(1, "good candidate\n");
219 
221 
222  /* there is a problem here because the context is in the store preceding the statement
223  * whereas live_out_paths hold after the statement.
224  * So I think I must apply the transformer to get the post-condition.
225  * That's ok for simple paths since they are store independent. BC.
226  */
227  transformer stmt_context = (*load_context_func)(current_stmt);
228 
229  /* There may also be a problem here in C, because calls may be
230  * anywhere inside an expression, and not solely as standalone
231  * statements. It may be better to call this function during the
232  * intraprocedural analysis of callers and not during a standalone
233  * phase which would have to deal with calls in sub-expressions,
234  * and thus also with store/pointers modifications.
235  * BC.
236  */
238 
239  pips_debug_effects(3, "current statement live_out_paths:\n", l_out);
241  call_arguments(c), l_out,
242  stmt_context);
244  return true;
245 }
list generic_effects_forward_translation(entity, list, list, transformer)
static void update_live_out_summary_engine_context_paths(live_out_summary_engine_context *ctxt, list l_paths)
#define call_function(x)
Definition: ri.h:709
#define entity_name(x)
Definition: ri.h:2790
#define call_arguments(x)
Definition: ri.h:711

References call_arguments, call_function, live_out_summary_engine_context::current_callee, current_stmt, entity_name, gen_get_ancestor(), generic_effects_forward_translation(), load_live_out_paths_list(), pips_debug, pips_debug_effects, statement_domain, and update_live_out_summary_engine_context_paths().

Referenced by live_out_paths_from_caller_to_callee().

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

◆ live_out_paths_from_caller_to_callee()

static void live_out_paths_from_caller_to_callee ( entity  caller,
entity  callee,
live_out_summary_engine_context ctxt 
)
static

All we need to perform the translation

Definition at line 256 of file liveness_analysis_engine.c.

258 {
259  const char *caller_name;
260  statement caller_statement;
261 
264  caller_name = module_local_name(caller);
265  pips_debug(2, "begin for caller: %s, and callee: %s\n", caller_name,
267  pips_debug(2, "current context callee: %s\n", entity_name(ctxt->current_callee));
268  /* All we need to perform the translation */
270  db_get_memory_resource(DBR_CODE, caller_name, true) );
271  caller_statement = get_current_module_statement();
272 
273  // functions that can be pointed by effects_computation_init_func:
274  // effects_computation_no_init
275  // init_convex_in_out_regions
276  // init_convex_rw_regions
277  (*effects_computation_init_func)(caller_name);
278 
280 
281  make_statement_global_stack(); // in case the semantics library is used
282 
283  //ctxt->current_callee = callee;
284  gen_context_multi_recurse(caller_statement, ctxt,
287  NULL);
288 
289  free_statement_global_stack(); // in case the semantics library is used
290 
295 
296  // functions that can be pointed by effects_computation_reset_func:
297  // effects_computation_no_reset
298  // reset_convex_in_out_regions
299  // reset_convex_rw_regions
300  (*effects_computation_reset_func)(caller_name);
301 }
static const char * caller_name
Definition: alias_check.c:122
static entity callee
Definition: alias_pairs.c:62
void reset_live_out_paths(void)
statement_effects(* db_get_live_out_paths_func)(const char *)
void set_live_out_paths(statement_effects)
void gen_context_multi_recurse(void *o, void *context,...)
Multi-recursion with context function visitor.
Definition: genClib.c:3373
void gen_null(__attribute__((unused)) void *unused)
Ignore the argument.
Definition: genClib.c:2752
static bool live_out_paths_from_call_site_to_callee(call c, live_out_summary_engine_context *ctxt)
static bool live_out_summary_paths_stmt_filter(statement s, __attribute__((unused)) live_out_summary_engine_context *ctxt)
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
void free_statement_global_stack(void)
Definition: static.c:358
void make_statement_global_stack(void)
Definition: static.c:318
#define call_domain
newgen_callees_domain_defined
Definition: ri.h:58

References call_domain, callee, caller_name, live_out_summary_engine_context::current_callee, db_get_live_out_paths_func, db_get_memory_resource(), entity_name, free_statement_global_stack(), gen_context_multi_recurse(), gen_null(), get_current_module_statement(), live_out_paths_from_call_site_to_callee(), live_out_summary_paths_stmt_filter(), make_statement_global_stack(), module_local_name(), pips_debug, reset_current_module_entity(), reset_current_module_statement(), reset_live_out_paths(), set_current_module_entity(), set_current_module_statement(), set_live_out_paths(), and statement_domain.

Referenced by live_out_summary_paths_engine().

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

◆ live_out_paths_from_forloop_to_body()

static bool live_out_paths_from_forloop_to_body ( forloop  l,
live_paths_analysis_context ctxt 
)
static

The live out paths of an iteration are the paths that

  • belong to the live in paths of the next iteration if it exists, that is to say if the condition evaluates to true; the write effects of the condition evaluation mask the live in paths of the next iteration; and the in effects of the condition evaluation must be added.
  • or belong to the live out of the whole loop if the next iteration does not exist. However, the condition is evaluated, and its write effects mask the live out paths at the end of the whole loop.

First, we get the live out paths of the whole loop

It may be executed...

...or another next iteration of the loop body

Take into account the effects of the header

We don't have the in effects of the header evaluation we safely approximate them by its may read proper effects if there are write effects during its evaluation We could be much more precise here by distinguishing the three different components and re-computing their effects. However, for loops are generally converted to loops or while loops by the controlizer, so I leave this as it is for the time being.

Definition at line 532 of file liveness_analysis_engine.c.

534 {
535  statement
537  statement body = forloop_body(l);
538 
539  pips_debug(1,"begin\n");
540 
541  /* The live out paths of an iteration are the paths that
542  * - belong to the live in paths of the next iteration if it exists,
543  * that is to say if the condition evaluates to true;
544  * the write effects of the condition evaluation mask the
545  * live in paths of the next iteration; and the in effects
546  * of the condition evaluation must be added.
547  * - or belong to the live out of the whole loop if the next iteration
548  * does not exist. However, the condition is evaluated,
549  * and its write effects mask the live out paths at the end of the
550  * whole loop.
551  */
552 
553  /* First, we get the live out paths of the whole loop
554  */
556  pips_debug_effects(3, "live out paths of whole loop:\n", l_live_out_loop);
557  effects_to_may_effects(l_live_out_loop); /* It may be executed... */
558 
559  /* ...or another next iteration of the loop body */
560  list l_in_next_iter = convert_in_effects(load_invariant_in_effects_list(body), ctxt);
561  list l_in_next_iter_may = effects_dup(l_in_next_iter);
562  effects_to_may_effects(l_in_next_iter_may);
563  pips_debug_effects(3, "(may) in effects of next iterations:\n",
564  l_in_next_iter_may);
565  reset_converted_in_effects(&l_in_next_iter, ctxt);
566 
567  // functions that can be pointed by effects_union_op:
568  // ProperEffectsMustUnion
569  // RegionsMustUnion
570  // ReferenceUnion
571  // EffectsMustUnion
572  list l_live_out_after_cond =
573  (*effects_union_op)(l_live_out_loop,
574  l_in_next_iter_may,
576 
577  pips_debug_effects(3, "live out paths after header evaluation:\n",
578  l_live_out_after_cond);
579 
580  /* Take into account the effects of the header */
582  ctxt);
583 
584  list l_write_cond =
586  pips_debug_effects(3, "write effects of condition:\n", l_write_cond);
587 
588 
589  /* We don't have the in effects of the header evaluation
590  * we safely approximate them by its may read proper effects
591  * if there are write effects during its evaluation
592  * We could be much more precise here by distinguishing
593  * the three different components and re-computing their effects.
594  * However, for loops are generally converted to loops or while loops
595  * by the controlizer, so I leave this as it is for the time being.
596  */
597  list l_in_cond =
599  if (!ENDP(l_write_cond)) effects_to_may_effects(l_in_cond);
600  pips_debug_effects(3, "approximation of in effects of condition:\n", l_in_cond);
601 
602  // functions that can be pointed by effects_union_op:
603  // ProperEffectsMustUnion
604  // RegionsMustUnion
605  // ReferenceUnion
606  // EffectsMustUnion
607  // functions that can be pointed by effects_sup_difference_op:
608  // effects_undefined_binary_operator
609  // RegionsSupDifference
610  // EffectsSupDifference
611  list l_live_out_body =
612  (*effects_union_op)(l_in_cond,
613  (*effects_sup_difference_op)(l_live_out_after_cond,
614  l_write_cond,
617 
618 
619  reset_converted_rw_effects(&l_prop_cond, ctxt);
620 
621  pips_debug_effects(3, "live out paths of loop body:\n", l_live_out_body);
622 
623  store_live_out_paths_list(body, l_live_out_body);
624 
625  pips_debug(1,"end\n");
626 
627  return true;
628 }
list load_invariant_in_effects_list(statement)
void store_live_out_paths_list(statement, list)
#define forloop_body(x)
Definition: ri.h:1372

References convert_in_effects(), convert_rw_effects(), current_stmt, effects_dup(), effects_read_effects_dup(), effects_same_action_p(), effects_to_may_effects(), effects_write_effects_dup(), ENDP, forloop_body, gen_get_ancestor(), load_invariant_in_effects_list(), load_live_out_paths_list(), load_proper_rw_effects_list(), pips_debug, pips_debug_effects, proper_to_summary_effects(), r_w_combinable_p(), reset_converted_in_effects(), reset_converted_rw_effects(), statement_domain, and store_live_out_paths_list().

Referenced by live_paths_of_module_statement().

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

◆ live_out_paths_from_loop_to_body()

static bool live_out_paths_from_loop_to_body ( loop  l,
live_paths_analysis_context ctxt 
)
static

First, we get the live out paths of the statement corresponding to the whole loop

We then compute the live out paths of the loop body

The live out paths of an iteration are the paths that

  • belong to the in effects of the next iterations if there exist some, except for the loop locals if the loop is parallel;
  • or belong to the live out of the whole loop if the next iteration does not exist.
  • to these, for the C language, we must add the read effects resulting from the evaluation of the incremental expression and of the upper bound. This includes an exact path for the loop index.

Definition at line 845 of file liveness_analysis_engine.c.

846 {
847  statement
849  statement
850  body = loop_body(l);
851  entity
852  index = loop_index(l);
853 
854  pips_debug(1,"begin\n");
855 
856  /* First, we get the live out paths of the statement corresponding to the
857  * whole loop
858  */
860  pips_debug_effects(3, "live out paths of whole loop:\n", l_live_out_loop);
861 
862  list l_rw_body = convert_rw_effects(load_rw_effects_list(body),
863  ctxt);
864  list l_w_body = effects_write_effects_dup(l_rw_body);
865  reset_converted_rw_effects(&l_rw_body, ctxt);
866 
867  if (loop_executed_never_p(l)) {
868  //l_w_body must had been a duplicated effect, so need to free them
869  gen_full_free_list(l_w_body);
870  l_w_body = NIL;
871  }
872  else if (!loop_executed_at_least_once_p(l))
873  effects_to_may_effects(l_w_body);
874  // functions that can be pointed by effects_sup_difference_op:
875  // effects_undefined_binary_operator
876  // RegionsSupDifference
877  // EffectsSupDifference
878  l_live_out_loop = (*effects_sup_difference_op)(l_live_out_loop, l_w_body,
880  pips_debug_effects(3, "live out paths of an iteration due to live out paths of whole loop\n", l_live_out_loop);
881 
882 
883  /* We then compute the live out paths of the loop body */
884  /* The live out paths of an iteration are the paths that
885  * - belong to the in effects of the next iterations if there exist some,
886  * except for the loop locals if the loop is parallel;
887  * - or belong to the live out of the whole loop if the next iteration
888  * does not exist.
889  * - to these, for the C language, we must add the read effects resulting
890  * from the evaluation of the incremental expression and of the upper
891  * bound. This includes an exact path for the loop index.
892  */
893  list l_masked_vars = NIL;
894  if(loop_parallel_p(l))
895  l_masked_vars = loop_locals(l);
896 
897  list l_inv_in_body = convert_in_effects(load_invariant_in_effects_list(body), ctxt);
898  list l_inv_in_body_may =
899  effects_dup_without_variables(l_inv_in_body, l_masked_vars);
900  effects_to_may_effects(l_inv_in_body_may);
901  pips_debug_effects(3, "(may) live in paths of an iteration:\n", l_inv_in_body_may);
902 
903  // functions that can be pointed by effects_union_op:
904  // ProperEffectsMustUnion
905  // RegionsMustUnion
906  // ReferenceUnion
907  // EffectsMustUnion
908  list l_live_out_body = (*effects_union_op)(l_live_out_loop,
909  l_inv_in_body_may,
911  reset_converted_in_effects(&l_inv_in_body, ctxt);
912 
914  ctxt);
915  list l_live_in_header =
917  reset_converted_rw_effects(&l_prop_header, ctxt);
918  // functions that can be pointed by reference_to_effect_func:
919  // reference_to_simple_effect
920  // reference_to_convex_region
921  // reference_to_reference_effect
922  list l_index = CONS(EFFECT,
924  NIL);
925  // functions that can be pointed by effects_union_op:
926  // ProperEffectsMustUnion
927  // RegionsMustUnion
928  // ReferenceUnion
929  // EffectsMustUnion
930  l_live_in_header = (*effects_union_op)(l_index, l_live_in_header, effects_same_action_p);
931 
932  pips_debug_effects(3, "live in paths of loop header:\n", l_live_in_header);
933 
934  // functions that can be pointed by effects_union_op:
935  // ProperEffectsMustUnion
936  // RegionsMustUnion
937  // ReferenceUnion
938  // EffectsMustUnion
939  l_live_out_body = (*effects_union_op)(l_live_out_body,
940  l_live_in_header,
942 
943  pips_debug_effects(3, "live out paths of loop body:\n", l_live_out_body);
944 
945  store_live_out_paths_list(body, l_live_out_body);
946 
947  pips_debug(1,"end\n");
948  return true;
949 }
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
effect(* reference_to_effect_func)(reference, action, bool)
action make_action_read_memory(void)
Definition: effects.c:1017

References CONS, convert_in_effects(), convert_rw_effects(), current_stmt, EFFECT, effects_dup(), effects_dup_without_variables(), effects_read_effects_dup(), effects_same_action_p(), effects_to_may_effects(), effects_write_effects_dup(), gen_full_free_list(), gen_get_ancestor(), load_invariant_in_effects_list(), load_live_out_paths_list(), load_proper_rw_effects_list(), load_rw_effects_list(), loop_body, loop_executed_at_least_once_p(), loop_executed_never_p(), loop_index, loop_locals, loop_parallel_p(), make_action_read_memory(), make_reference(), NIL, pips_debug, pips_debug_effects, proper_to_summary_effects(), r_w_combinable_p(), reference_to_effect_func, reset_converted_in_effects(), reset_converted_rw_effects(), statement_domain, and store_live_out_paths_list().

Referenced by live_paths_of_module_statement().

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

◆ live_out_paths_from_test_to_branches()

static bool live_out_paths_from_test_to_branches ( test  t,
_UNUSED_ live_paths_analysis_context ctxt 
)
static

First, we get the live out paths of the statement corresponding to the test

The live out paths for each branch are the live_out_paths of the test

The live in paths of the test are computed with the surrounding sequence live paths computation.

Definition at line 1052 of file liveness_analysis_engine.c.

1054 {
1055  statement
1057 
1058  pips_debug(1,"begin\n");
1059 
1060  /* First, we get the live out paths of the statement corresponding to the test
1061  */
1062  list l_live_out_test = load_live_out_paths_list(current_stmt);
1063 
1064  /* The live out paths for each branch are the live_out_paths
1065  of the test
1066  */
1067  store_live_out_paths_list(test_true(t), effects_dup(l_live_out_test));
1068  store_live_out_paths_list(test_false(t), effects_dup(l_live_out_test));
1069 
1070 
1071  /* The live in paths of the test are computed with the surrounding
1072  sequence live paths computation.
1073  */
1074  pips_debug(1,"end\n");
1075 
1076  return true;
1077 }
#define test_false(x)
Definition: ri.h:2837
#define test_true(x)
Definition: ri.h:2835

References current_stmt, effects_dup(), gen_get_ancestor(), load_live_out_paths_list(), pips_debug, statement_domain, store_live_out_paths_list(), test_false, and test_true.

Referenced by live_paths_of_module_statement().

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

◆ live_out_paths_from_unstructured_to_nodes()

static bool live_out_paths_from_unstructured_to_nodes ( unstructured  unstr,
live_paths_analysis_context ctxt 
)
static

Adopt a very conservative strategy: live_out(node)= live_out(unstructured)*may U (U_{n \in nodes} IN(nodes)) If convex paths were to be computed, transformers should be taken into account.

The exit node is a particular case: its live_out paths are the live_out paths of the unstructured.

there is only one statement in u;

It may be executed...

be sure live_out paths are not stored twice, in particular for the exit node

Definition at line 439 of file liveness_analysis_engine.c.

441 {
442  pips_debug(1,"begin\n");
443 
444  /* Adopt a very conservative strategy:
445  * live_out(node)= live_out(unstructured)*may U (U_{n \in nodes} IN(nodes))
446  * If convex paths were to be computed, transformers should be taken into account.
447  */
448  /* The exit node is a particular case: its live_out paths are the live_out paths
449  * of the unstructured.
450  */
451 
452  statement
454  control exit_ctrl = unstructured_exit( unstr );
455  statement exit_node = control_statement(exit_ctrl);
456 
458  pips_debug_effects(3, "live out paths of whole unstructured:\n", l_live_out_unstr);
459  store_live_out_paths_list(exit_node, l_live_out_unstr);
460 
461  if(control_predecessors(exit_ctrl) == NIL && control_successors(exit_ctrl) == NIL)
462  {
463  /* there is only one statement in u; */
464  pips_debug(6, "unique node\n");
465  }
466  else
467  {
468  l_live_out_unstr = effects_dup(l_live_out_unstr);
469  effects_to_may_effects(l_live_out_unstr); /* It may be executed... */
470 
471  list l_in = NIL;
472 
473  list l_nodes = NIL;
475  (ctrl, unstr, l_nodes,
476  {
477  statement node_stmt = control_statement(ctrl);
478  pips_debug(3, "visiting node statement with ordering: "
479  "%03zd and number: %03zd\n",
480  statement_ordering(node_stmt),
481  statement_number(node_stmt));
482 
483  list l_in_node = convert_in_effects(load_in_effects_list(node_stmt), ctxt);
484  list l_in_node_may = effects_dup(l_in_node);
485  effects_to_may_effects(l_in_node_may);
486 
487  // functions that can be pointed by effects_union_op:
488  // ProperEffectsMustUnion
489  // RegionsMustUnion
490  // ReferenceUnion
491  // EffectsMustUnion
492  l_in = (*effects_union_op)(l_in_node_may, l_in,
494  pips_debug_effects(5, "current in effects:\n", l_in);
495  reset_converted_in_effects(&l_in_node, ctxt);
496  });
497 
498  // functions that can be pointed by effects_union_op:
499  // ProperEffectsMustUnion
500  // RegionsMustUnion
501  // ReferenceUnion
502  // EffectsMustUnion
503  list l_live_out_nodes = (*effects_union_op)(l_in, l_live_out_unstr,
505  pips_debug_effects(3, "l_live_out_nodes:\n", l_live_out_nodes);
506 
507  FOREACH(CONTROL, ctrl, l_nodes)
508  {
509 
510  statement node_stmt = control_statement(ctrl);
511 
512  /* be sure live_out paths are not stored twice, in particular
513  for the exit node
514  */
515  if ( !bound_live_out_paths_p(node_stmt) )
516  {
517  pips_debug(3, "storing live out paths for node statement "
518  "with ordering: %03zd and number: %03zd\n",
519  statement_ordering(node_stmt),
520  statement_number(node_stmt));
521  store_live_out_paths_list(node_stmt, effects_dup(l_live_out_nodes));
522  }
523  }
524  }
525 
526  pips_debug(1,"end\n");
527 
528  return true;
529 }
bool bound_live_out_paths_p(statement)
#define UNSTRUCTURED_CONTROL_MAP(c, u, l, code)
Walk through all the controls of un unstructured.
#define control_predecessors(x)
Definition: ri.h:943
#define CONTROL(x)
CONTROL.
Definition: ri.h:910
#define control_successors(x)
Definition: ri.h:945
#define unstructured_exit(x)
Definition: ri.h:3006
#define control_statement(x)
Definition: ri.h:941

References bound_live_out_paths_p(), CONTROL, control_predecessors, control_statement, control_successors, convert_in_effects(), current_stmt, effects_dup(), effects_same_action_p(), effects_to_may_effects(), FOREACH, gen_get_ancestor(), load_in_effects_list(), load_live_out_paths_list(), NIL, pips_debug, pips_debug_effects, reset_converted_in_effects(), statement_domain, statement_number, statement_ordering, store_live_out_paths_list(), UNSTRUCTURED_CONTROL_MAP, and unstructured_exit.

Referenced by live_paths_of_module_statement().

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

◆ live_out_paths_from_whileloop_to_body()

static bool live_out_paths_from_whileloop_to_body ( whileloop  l,
live_paths_analysis_context ctxt 
)
static

The live out paths of an iteration are the paths that

  • belong to the live in paths of the next iteration if it exists, that is to say if the condition evaluates to true; the write effects of the condition evaluation mask the live in paths of the next iteration; and the in effects of the condition evaluation must be added.
  • or belong to the live out of the whole loop if the next iteration does not exist. However, the condition is evaluated, and its write effects mask the live out paths at the end of the whole loop.

First, we get the live out paths of the whole loop

It may be executed...

...or another next iteration of the loop body

Take into account the effects of the condition

We don't have the in effects of the condition evaluation we safely approximate them by its may read proper effects if there are write effects during its evaluation

Definition at line 631 of file liveness_analysis_engine.c.

632 {
633  statement
635  statement body = whileloop_body(l);
636 
637  pips_debug(1,"begin\n");
638 
639  /* The live out paths of an iteration are the paths that
640  * - belong to the live in paths of the next iteration if it exists,
641  * that is to say if the condition evaluates to true;
642  * the write effects of the condition evaluation mask the
643  * live in paths of the next iteration; and the in effects
644  * of the condition evaluation must be added.
645  * - or belong to the live out of the whole loop if the next iteration
646  * does not exist. However, the condition is evaluated,
647  * and its write effects mask the live out paths at the end of the
648  * whole loop.
649  */
650 
651  /* First, we get the live out paths of the whole loop
652  */
654  pips_debug_effects(3, "live out paths of whole loop:\n", l_live_out_loop);
655  effects_to_may_effects(l_live_out_loop); /* It may be executed... */
656 
657  /* ...or another next iteration of the loop body */
658  list l_in_next_iter = convert_in_effects(load_invariant_in_effects_list(body), ctxt);
659  list l_in_next_iter_may = effects_dup(l_in_next_iter);
660  effects_to_may_effects(l_in_next_iter_may);
661  pips_debug_effects(3, "(may) in effects of next iterations:\n",
662  l_in_next_iter_may);
663  reset_converted_in_effects(&l_in_next_iter, ctxt);
664 
665  // functions that can be pointed by effects_union_op:
666  // ProperEffectsMustUnion
667  // RegionsMustUnion
668  // ReferenceUnion
669  // EffectsMustUnion
670  list l_live_out_after_cond =
671  (*effects_union_op)(l_live_out_loop,
672  l_in_next_iter_may,
674 
675  pips_debug_effects(3, "live out paths after any condition evaluation:\n",
676  l_live_out_after_cond);
677 
678  /* Take into account the effects of the condition */
680  ctxt);
681 
682  list l_write_cond =
684  pips_debug_effects(3, "write effects of condition:\n", l_write_cond);
685 
686 
687  /* We don't have the in effects of the condition evaluation
688  * we safely approximate them by its may read proper effects
689  * if there are write effects during its evaluation
690  */
691  list l_in_cond =
693  if (!ENDP(l_write_cond)) effects_to_may_effects(l_in_cond);
694  pips_debug_effects(3, "approximation of in effects of condition:\n", l_in_cond);
695 
696  // functions that can be pointed by effects_union_op:
697  // ProperEffectsMustUnion
698  // RegionsMustUnion
699  // ReferenceUnion
700  // EffectsMustUnion
701  // functions that can be pointed by effects_sup_difference_op:
702  // effects_undefined_binary_operator
703  // RegionsSupDifference
704  // EffectsSupDifference
705  list l_live_out_body =
706  (*effects_union_op)(l_in_cond,
707  (*effects_sup_difference_op)(l_live_out_after_cond,
708  l_write_cond,
711 
712 
713  reset_converted_rw_effects(&l_prop_cond, ctxt);
714 
715  pips_debug_effects(3, "live out paths of loop body:\n", l_live_out_body);
716 
717  store_live_out_paths_list(body, l_live_out_body);
718 
719  pips_debug(1,"end\n");
720 
721  return true;
722 }

References convert_in_effects(), convert_rw_effects(), current_stmt, effects_dup(), effects_read_effects_dup(), effects_same_action_p(), effects_to_may_effects(), effects_write_effects_dup(), ENDP, gen_get_ancestor(), load_invariant_in_effects_list(), load_live_out_paths_list(), load_proper_rw_effects_list(), pips_debug, pips_debug_effects, proper_to_summary_effects(), r_w_combinable_p(), reset_converted_in_effects(), reset_converted_rw_effects(), statement_domain, store_live_out_paths_list(), and whileloop_body.

Referenced by live_paths_of_module_statement().

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

◆ live_out_region_engine()

bool live_out_region_engine ( const char *  module_name,
__attribute__((unused)) effects_representation_val  representation 
)

Definition at line 1394 of file liveness_analysis_engine.c.

1394  {
1396  bool good_result_p = true;
1397 
1398  debug_on("GMRE_DEBUG_LEVEL");
1399  pips_debug(1, "begin\n");
1400 
1401  //-- configure environment --//
1403 
1405  db_get_memory_resource(DBR_CODE, module_name, true) );
1407 
1408  pips_assert("Statement should be OK before...",
1410 
1412 
1413  //-- get dependencies --//
1415  db_get_memory_resource(DBR_OUT_REGIONS, module_name, true));
1417  db_get_memory_resource(DBR_LIVE_OUT_PATHS, module_name, true));
1419  db_get_memory_resource(DBR_LIVE_IN_PATHS, module_name, true));
1420 
1421 
1422  //-- Make the job -- //
1425 
1426  //-- Save modified code to database --//
1427  DB_PUT_MEMORY_RESOURCE(DBR_LIVE_OUT_REGIONS, module_name,
1429 
1430 
1431  //-- reset module and dependencies --//
1434 
1439 
1440  pips_debug(1, "end\n");
1441  debug_off();
1442 
1443  return (good_result_p);
1444 }
bool statement_consistent_p(statement p)
Definition: ri.c:2195
static statement module_statement
Definition: alias_check.c:125
void init_live_out_regions(void)
void reset_live_out_regions(void)
statement_effects get_live_out_regions(void)
void reset_out_effects(void)
void set_out_effects(statement_effects)
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
#define DB_PUT_MEMORY_RESOURCE(res_name, own_name, res_val)
conform to old interface.
Definition: pipsdbm-local.h:66
static bool filter_live_out_regions_statement(statement st)
For each statement store the new live_out_regions.
#define debug_on(env)
Definition: misc-local.h:157
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define debug_off()
Definition: misc-local.h:160

References db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug_off, debug_on, filter_live_out_regions_statement(), gen_null(), gen_recurse, get_current_module_statement(), get_live_out_regions(), init_live_out_regions(), module_name(), module_name_to_entity(), module_statement, pips_assert, pips_debug, reset_current_module_entity(), reset_current_module_statement(), reset_live_in_paths(), reset_live_out_paths(), reset_live_out_regions(), reset_out_effects(), set_current_module_entity(), set_current_module_statement(), set_live_in_paths(), set_live_out_paths(), set_out_effects(), statement_consistent_p(), and statement_domain.

+ Here is the call graph for this function:

◆ live_out_summary_paths_engine()

bool live_out_summary_paths_engine ( const char *  module_name)

Look for all call sites in the callers

Parameters
module_nameodule_name

Definition at line 304 of file liveness_analysis_engine.c.

305 {
306  /* Look for all call sites in the callers */
307  callees callers = (callees) db_get_memory_resource(DBR_CALLERS,
308  module_name,
309  true);
311 
314 
315  ifdebug(1)
316  {
317  pips_debug(1, "begin for %s with %td callers\n",
318  module_name,
319  gen_length(callees_callees(callers)));
321  {fprintf(stderr, "%s, ", caller_name);}
322  fprintf(stderr, "\n");
323  }
324 
327  debug_on("LIVE_PATHS_DEBUG_LEVEL");
329  {
332  }
333  debug_off();
335  ctxt.l_current_paths = NIL;
336  (*db_put_live_out_summary_paths_func)(module_name, ctxt.l_current_paths);
337 
338  ifdebug(1)
339  {
341  db_get_memory_resource(DBR_CODE,
343  true) );
344 
345  pips_debug(1, "live out paths for module %s:\n", module_name);
346  (*effects_prettyprint_func)(ctxt.l_current_paths);
347  pips_debug(1, "end\n");
349  }
350 
354 
355  return true;
356 }
void free_effects_private_current_context_stack(void)
void make_effects_private_current_context_stack(void)
#define STRING(x)
Definition: genC.h:87
#define list_undefined_p(c)
Return if a list is undefined.
Definition: newgen_list.h:75
size_t gen_length(const list l)
Definition: list.c:150
static void reset_live_out_summary_engine_context(live_out_summary_engine_context *ctxt)
static void live_out_paths_from_caller_to_callee(entity caller, entity callee, live_out_summary_engine_context *ctxt)
static void set_live_out_summary_engine_context(live_out_summary_engine_context *ctxt, entity callee)
struct _newgen_struct_callees_ * callees
Definition: ri.h:55
#define callees_callees(x)
Definition: ri.h:675
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...

References callee, callees_callees, caller_name, db_get_memory_resource(), debug_off, debug_on, FOREACH, fprintf(), free_effects_private_current_context_stack(), gen_length(), ifdebug, live_out_summary_engine_context::l_current_paths, list_undefined_p, live_out_paths_from_caller_to_callee(), make_effects_private_current_context_stack(), module_local_name(), module_name(), module_name_to_entity(), NIL, pips_debug, reset_current_module_entity(), reset_current_module_statement(), reset_live_out_summary_engine_context(), set_current_module_entity(), set_current_module_statement(), set_live_out_summary_engine_context(), and STRING.

+ Here is the call graph for this function:

◆ live_out_summary_paths_stmt_filter()

static bool live_out_summary_paths_stmt_filter ( statement  s,
__attribute__((unused)) live_out_summary_engine_context ctxt 
)
static

Definition at line 248 of file liveness_analysis_engine.c.

250 {
251  pips_debug(1, "statement %03zd\n", statement_number(s));
252  return(true);
253 }

References pips_debug, and statement_number.

Referenced by live_out_paths_from_caller_to_callee().

+ Here is the caller graph for this function:

◆ live_paths_engine()

bool live_paths_engine ( const char *  module_name,
effects_representation_val  representation 
)

Get the code of the module.

Get the various effects and in_effects of the module.

Initialize the map for live_out and live_int paths

Get the live_out_summary_paths of the current module

And stores them as the live out paths of the module statement

Compute the live paths of the module.

Parameters
module_nameodule_name
representationepresentation

Definition at line 1178 of file liveness_analysis_engine.c.

1179 {
1180  debug_on("LIVE_PATHS_DEBUG_LEVEL");
1181  pips_debug(1, "begin\n");
1182 
1184 
1185  /* Get the code of the module. */
1187  db_get_memory_resource(DBR_CODE, module_name, true) );
1189 
1190 
1192  // functions that can be pointed by effects_computation_init_func:
1193  // effects_computation_no_init
1194  // init_convex_in_out_regions
1195  // init_convex_rw_regions
1196  (*effects_computation_init_func)(module_name);
1197 
1198  /* Get the various effects and in_effects of the module. */
1199 
1203 
1207 
1208 
1209  /* Initialize the map for live_out and live_int paths */
1212 
1213  /* Get the live_out_summary_paths of the current module */
1214  list l_sum_live_out = (*db_get_live_out_summary_paths_func)(module_name);
1215  /* And stores them as the live out paths of the module statement */
1217 
1218  /* Compute the live paths of the module. */
1220  init_live_paths_context(&ctxt, representation);
1222  reset_live_paths_context(&ctxt);
1223 
1224  pips_debug(1, "end\n");
1225 
1226  (*db_put_live_out_paths_func)(module_name, get_live_out_paths());
1227  (*db_put_live_in_paths_func)(module_name, get_live_in_paths());
1228 
1230  reset_rw_effects();
1232  reset_in_effects();
1237  // functions that can be pointed by effects_computation_reset_func:
1238  // effects_computation_no_reset
1239  // reset_convex_in_out_regions
1240  // reset_convex_rw_regions
1241  (*effects_computation_reset_func)(module_name);
1242 
1244 
1247  pips_debug(1, "end\n");
1248 
1249  debug_off();
1250  return true;
1251 }
void set_invariant_in_effects(statement_effects)
void set_cumulated_in_effects(statement_effects)
statement_effects(* db_get_invariant_in_effects_func)(const char *)
void set_rw_effects(statement_effects)
void reset_invariant_in_effects(void)
void init_live_out_paths(void)
void reset_cumulated_in_effects(void)
statement_effects(* db_get_invariant_rw_effects_func)(const char *)
void init_live_in_paths(void)
void reset_proper_rw_effects(void)
statement_effects get_live_in_paths(void)
void set_proper_rw_effects(statement_effects)
statement_effects(* db_get_cumulated_in_effects_func)(const char *)
statement_effects get_live_out_paths(void)
void set_in_effects(statement_effects)
void reset_in_effects(void)
void reset_invariant_rw_effects(void)
statement_effects(* db_get_in_effects_func)(const char *)
void set_invariant_rw_effects(statement_effects)
statement_effects(* db_get_proper_rw_effects_func)(const char *)
void reset_rw_effects(void)
statement_effects(* db_get_rw_effects_func)(const char *)
static void init_live_paths_context(live_paths_analysis_context *ctxt, effects_representation_val representation)
static void live_paths_of_module_statement(statement stmt, live_paths_analysis_context *ctxt)
static void reset_live_paths_context(live_paths_analysis_context *ctxt)

References db_get_cumulated_in_effects_func, db_get_in_effects_func, db_get_invariant_in_effects_func, db_get_invariant_rw_effects_func, db_get_memory_resource(), db_get_proper_rw_effects_func, db_get_rw_effects_func, debug_off, debug_on, effects_dup(), free_effects_private_current_context_stack(), get_current_module_statement(), get_live_in_paths(), get_live_out_paths(), init_live_in_paths(), init_live_out_paths(), init_live_paths_context(), live_paths_of_module_statement(), make_effects_private_current_context_stack(), module_name(), module_name_to_entity(), module_statement, pips_debug, reset_cumulated_in_effects(), reset_current_module_entity(), reset_current_module_statement(), reset_in_effects(), reset_invariant_in_effects(), reset_invariant_rw_effects(), reset_live_in_paths(), reset_live_out_paths(), reset_live_paths_context(), reset_proper_rw_effects(), reset_rw_effects(), set_cumulated_in_effects(), set_current_module_entity(), set_current_module_statement(), set_in_effects(), set_invariant_in_effects(), set_invariant_rw_effects(), set_proper_rw_effects(), set_rw_effects(), and store_live_out_paths_list().

+ Here is the call graph for this function:

◆ live_paths_from_block_to_statements()

static bool live_paths_from_block_to_statements ( sequence  seq,
live_paths_analysis_context ctxt 
)
static

reversed version of the sequence to avoid recursion

the live out paths of the current statement are the live in paths of the next statement (or the live out of the while block if last statement)

Now let us compute the live in paths

The block live in paths are the live in paths of the first statement which is the last visited statement. However, in case of nested sequences, which may be the case when there are macros for instance, the live_in paths may have already been computed. It's not yet clear if the effects we have just computed are more precise or not.

Definition at line 1080 of file liveness_analysis_engine.c.

1082 {
1084  list l_stmt = sequence_statements(seq);
1085 
1086  pips_debug(1, "begin\n");
1087 
1088  if (ENDP(l_stmt))
1089  {
1090  if (get_bool_property("WARN_ABOUT_EMPTY_SEQUENCES"))
1091  pips_user_warning("empty sequence\n");
1092  store_live_in_paths_list(seq_stmt, NIL);
1093  }
1094  else
1095  {
1096  list l_rev_stmt = NIL; /* reversed version of the sequence to avoid recursion*/
1097  FOREACH(STATEMENT, stmt, l_stmt)
1098  {
1099  l_rev_stmt = CONS(STATEMENT, stmt, l_rev_stmt);
1100  }
1101 
1102  list l_next_stmt_live_in = load_live_out_paths_list(seq_stmt);
1103  FOREACH(STATEMENT, stmt, l_rev_stmt)
1104  {
1105  /* the live out paths of the current statement are the live in paths
1106  of the next statement (or the live out of the while block
1107  if last statement)
1108  */
1109  pips_debug(1,"dealing with statement with ordering: %03zd and number: %03zd\n",
1111 
1112  list l_live_out = l_next_stmt_live_in;
1113  pips_debug_effects(2, "storing effects:\n", l_live_out);
1115 
1116  /* Now let us compute the live in paths */
1118  l_next_stmt_live_in = load_live_in_paths_list(stmt);
1119  }
1120 
1121  /* The block live in paths are the live in paths of the first statement
1122  which is the last visited statement.
1123  However, in case of nested sequences, which may be the case when there are
1124  macros for instance, the live_in paths may have already been computed.
1125  It's not yet clear if the effects we have just computed are more precise
1126  or not.
1127  */
1128  if ( !bound_live_in_paths_p(seq_stmt) )
1129  {
1130  pips_debug_effects(2, "storing live_in paths of sequence statement:\n", l_next_stmt_live_in);
1131  store_live_in_paths_list(seq_stmt, effects_dup(l_next_stmt_live_in));
1132  }
1133 
1134  gen_free_list(l_rev_stmt);
1135  }
1136  pips_debug(1, "end\n");
1137 
1138  return true;
1139 }
static void live_in_paths_of_statement(statement s, live_paths_analysis_context *ctxt)
#define pips_user_warning
Definition: misc-local.h:146
#define sequence_statements(x)
Definition: ri.h:2360
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
Definition: statement.c:54

References bound_live_in_paths_p(), CONS, effects_dup(), ENDP, FOREACH, gen_free_list(), gen_get_ancestor(), get_bool_property(), live_in_paths_of_statement(), load_live_in_paths_list(), load_live_out_paths_list(), NIL, pips_debug, pips_debug_effects, pips_user_warning, sequence_statements, STATEMENT, statement_domain, statement_number, statement_ordering, store_live_in_paths_list(), and store_live_out_paths_list().

Referenced by live_paths_of_module_statement().

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

◆ live_paths_of_module_statement()

static void live_paths_of_module_statement ( statement  stmt,
live_paths_analysis_context ctxt 
)
static

for expression instructions solely, equivalent to gen_true otherwise

Stop on these nodes:

calls are treated in another phase

Definition at line 1155 of file liveness_analysis_engine.c.

1156 {
1157 
1159  (stmt, ctxt,
1161  //instruction_domain, live_paths_from_instruction_to_expression, gen_null,
1162  /* for expression instructions solely, equivalent to gen_true otherwise */
1169 
1170  /* Stop on these nodes: */
1171  call_domain, gen_false, gen_null, /* calls are treated in another phase*/
1173  NULL);
1174 
1175  return;
1176 }
bool gen_false(__attribute__((unused)) gen_chunk *unused)
Return false and ignore the argument.
Definition: genClib.c:2796
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
static bool live_paths_from_block_to_statements(sequence seq, live_paths_analysis_context *ctxt)
static bool live_out_paths_from_forloop_to_body(forloop l, live_paths_analysis_context *ctxt)
static void live_in_paths_of_loop(loop l, live_paths_analysis_context *ctxt)
static bool live_out_paths_from_test_to_branches(test t, _UNUSED_ live_paths_analysis_context *ctxt)
static bool live_out_paths_from_loop_to_body(loop l, live_paths_analysis_context *ctxt)
static bool live_out_paths_from_whileloop_to_body(whileloop l, live_paths_analysis_context *ctxt)
static void live_in_paths_of_whileloop(whileloop l, live_paths_analysis_context *ctxt)
static bool live_out_paths_from_unstructured_to_nodes(unstructured unstr, live_paths_analysis_context *ctxt)
#define forloop_domain
newgen_extensions_domain_defined
Definition: ri.h:178
#define test_domain
newgen_entity_domain_defined
Definition: ri.h:418
#define expression_domain
newgen_execution_domain_defined
Definition: ri.h:154
#define unstructured_domain
newgen_type_domain_defined
Definition: ri.h:442
#define loop_domain
newgen_language_domain_defined
Definition: ri.h:218
#define whileloop_domain
newgen_variable_domain_defined
Definition: ri.h:466
#define sequence_domain
newgen_reference_domain_defined
Definition: ri.h:346

References call_domain, expression_domain, forloop_domain, gen_context_multi_recurse(), gen_false(), gen_null(), gen_true(), live_in_paths_of_loop(), live_in_paths_of_statement(), live_in_paths_of_whileloop(), live_out_paths_from_forloop_to_body(), live_out_paths_from_loop_to_body(), live_out_paths_from_test_to_branches(), live_out_paths_from_unstructured_to_nodes(), live_out_paths_from_whileloop_to_body(), live_paths_from_block_to_statements(), loop_domain, sequence_domain, statement_domain, test_domain, unstructured_domain, and whileloop_domain.

Referenced by live_paths_engine().

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

◆ new_system_with_only_live_variable()

static Psysteme new_system_with_only_live_variable ( Psysteme  sc,
reference  ref,
list  llivein,
list  lliveout 
)
static

Create a new nsc system from the sc system of a region.

On this new nsc system only keep live variable. /param sc constraint system of the region /param ref reference variable that the region carry, have to keep on the new system of constraints /param llivein list of live in effect, variables to keep /param lliveout list of live out effect, variables to keep /return a new system of constraint for the region that only keep live variable

Definition at line 1264 of file liveness_analysis_engine.c.

1264  {
1265  Pbase base_keep = NULL;
1266  Pbase base_pj = base_copy(sc_base(sc));
1267  Psysteme nsc = sc_dup(sc);
1268 
1269  // Compute list of variable to keep
1270  entity ent = reference_variable(ref);
1271  if (base_contains_variable_p(base_pj, (Variable) ent))
1272  base_keep = base_add_variable(base_keep, (Variable) ent);
1273  list lind = reference_indices(ref);
1274  FOREACH(EXPRESSION, expind, lind) {
1275  entity entind = expression_to_entity(expind);
1276  if (base_contains_variable_p(base_pj, (Variable) entind))
1277  base_keep = base_add_variable(base_keep, (Variable) entind);
1278  }
1279 
1280  FOREACH(EFFECT, live, llivein) {
1281  reference liveref = effect_any_reference(live);
1282  entity liveent = reference_variable(liveref);
1283  if (base_contains_variable_p(base_pj, (Variable) liveent))
1284  base_keep = base_add_variable(base_keep, (Variable) liveent);
1285  }
1286 
1287  FOREACH(EFFECT, live, lliveout) {
1288  reference liveref = effect_any_reference(live);
1289  entity liveent = reference_variable(liveref);
1290  if (base_contains_variable_p(base_pj, (Variable) liveent))
1291  if (!base_contains_variable_p(base_keep, (Variable) liveent))
1292  base_keep = base_add_variable(base_keep, (Variable) liveent);
1293  }
1294 
1295  // Compute list of variable to project
1296  BASE_FOREACH(keep, base_keep) {
1297  vect_erase_var(&base_pj, keep);
1298  }
1299 
1300  ifdebug (4) {
1301  pips_debug(4, "Input system:\n");
1303  pips_debug(4, "Variables to project:\n");
1305  }
1306 
1307  // Project variable if possible
1308  // if not (overflow), keep the variable and generate a warning
1309  // if we use sc_projection_ofl_along_variables what we keep in case of overflow?
1310  //sc_projection_ofl_along_variables(nsc, elim); //add CATCH/TRY
1311  Psysteme scbackup = NULL;
1312  BASE_FOREACH(elim, base_pj) {
1313  scbackup = sc_dup(nsc);
1315  pips_user_warning("An overflow appear for the projection of %s. So this variable wasn't remove from the constraints system.\n", entity_name((entity) elim));
1316  nsc = sc_free(nsc);
1317  nsc = sc_dup(scbackup);
1318  }
1319  TRY {
1320  sc_projection_along_variable_ofl_ctrl(&nsc, elim, FWD_OFL_CTRL);
1321  sc_base_remove_variable(nsc, elim);
1322  nsc = sc_normalize(nsc);
1324  }
1325  scbackup = sc_free(scbackup);
1326  }
1327 
1328  ifdebug (4) {
1329  pips_debug(4, "New system:\n");
1331  }
1332 
1333  return nsc;
1334 }
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
#define CATCH(what)
@ overflow_error
#define UNCATCH(what)
#define TRY
Pbase base_add_variable(Pbase b, Variable var)
Pbase base_add_variable(Pbase b, Variable v): add variable v as a new dimension to basis b at the end...
Definition: base.c:88
bool base_contains_variable_p(Pbase b, Variable v)
bool base_contains_variable_p(Pbase b, Variable v): returns true if variable v is one of b's elements...
Definition: base.c:136
void vect_fprint(FILE *f, Pvecteur v, get_variable_name_t variable_name)
void vect_fprint(FILE * f, Pvecteur v, char * (*variable_name)()): impression d'un vecteur creux v su...
Definition: io.c:124
entity expression_to_entity(expression e)
just returns the entity of an expression, or entity_undefined
Definition: expression.c:3140
#define reference_variable(x)
Definition: ri.h:2326
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define reference_indices(x)
Definition: ri.h:2328
void sc_base_remove_variable(Psysteme sc, Variable v)
Definition: sc.c:239
Psysteme sc_dup(Psysteme ps)
Psysteme sc_dup(Psysteme ps): should becomes a link.
Definition: sc_alloc.c:176
char * default_variable_to_string(Variable v)
Definition: sc_debug.c:245
void sc_print(Psysteme ps, get_variable_name_t nom_var)
void sc_print()
Definition: sc_io.c:194
Psysteme sc_free(Psysteme in_ps)
Psysteme sc_free( in_ps ) AL 30/05/94 Free of in_ps.
Definition: sc_list.c:112
Psysteme sc_normalize(Psysteme ps)
Psysteme sc_normalize(Psysteme ps): normalisation d'un systeme d'equation et d'inequations lineaires ...
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
@ keep
bj > b1 -> h1/hj = h1
Definition: union-local.h:61
char *(* get_variable_name_t)(Variable)
Definition: vecteur-local.h:62
void * Variable
arithmetique is a requirement for vecteur, but I do not want to inforce it in all pips files....
Definition: vecteur-local.h:60
#define FWD_OFL_CTRL
#define BASE_FOREACH(v, b)
Pbase base_copy(Pbase b)
Direct duplication.
Definition: alloc.c:300
void vect_erase_var(Pvecteur *ppv, Variable v)
void vect_erase_var(Pvecteur * ppv, Variable v): projection du vecteur *ppv selon la direction v (i....
Definition: unaires.c:106

References base_add_variable(), base_contains_variable_p(), base_copy(), BASE_FOREACH, CATCH, default_variable_to_string(), EFFECT, effect_any_reference, entity_name, EXPRESSION, expression_to_entity(), FOREACH, FWD_OFL_CTRL, ifdebug, keep, overflow_error, pips_debug, pips_user_warning, ref, reference_indices, reference_variable, sc_base_remove_variable(), sc_dup(), sc_free(), sc_normalize(), sc_print(), TRY, UNCATCH, vect_erase_var(), and vect_fprint().

Referenced by filter_live_out_regions_statement().

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

◆ reset_converted_in_effects()

static void reset_converted_in_effects ( list lin,
live_paths_analysis_context ctxt 
)
static

◆ reset_converted_rw_effects()

static void reset_converted_rw_effects ( list lrw,
live_paths_analysis_context ctxt 
)
static

Definition at line 101 of file liveness_analysis_engine.c.

102 {
103  if (!ctxt->memory_effects_only)
104  gen_free_list(*lrw);
105  *lrw = NIL;
106 }

References gen_free_list(), live_paths_analysis_context::memory_effects_only, and NIL.

Referenced by live_in_paths_of_loop(), live_in_paths_of_statement(), live_in_paths_of_whileloop(), live_out_paths_from_forloop_to_body(), live_out_paths_from_loop_to_body(), and live_out_paths_from_whileloop_to_body().

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

◆ reset_live_out_summary_engine_context()

static void reset_live_out_summary_engine_context ( live_out_summary_engine_context ctxt)
static

Definition at line 185 of file liveness_analysis_engine.c.

186 {
189 }
#define list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69
#define entity_undefined
Definition: ri.h:2761

References live_out_summary_engine_context::current_callee, entity_undefined, live_out_summary_engine_context::l_current_paths, and list_undefined.

Referenced by live_out_summary_paths_engine().

+ Here is the caller graph for this function:

◆ reset_live_paths_context()

static void reset_live_paths_context ( live_paths_analysis_context ctxt)
static

Definition at line 81 of file liveness_analysis_engine.c.

82 {
83  if (! ctxt->memory_effects_only
85  // if the MEMORY_EFFECTS_ONLY is FALSE on input, and
86  // we did not want to compute IN non-memory effects,
87  // we have to reset MEMORY_EFFECTS_ONLY to FALSE.
88  set_bool_property("MEMORY_EFFECTS_ONLY", false);
89 }

References live_paths_analysis_context::memory_effects_only, live_paths_analysis_context::memory_in_out_effects_only, and set_bool_property().

Referenced by live_paths_engine().

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

◆ set_live_out_summary_engine_context()

static void set_live_out_summary_engine_context ( live_out_summary_engine_context ctxt,
entity  callee 
)
static

Definition at line 178 of file liveness_analysis_engine.c.

179 {
180  ctxt->current_callee = callee;
182 }

References callee, live_out_summary_engine_context::current_callee, live_out_summary_engine_context::l_current_paths, and list_undefined.

Referenced by live_out_summary_paths_engine().

+ Here is the caller graph for this function:

◆ update_live_out_summary_engine_context_paths()

static void update_live_out_summary_engine_context_paths ( live_out_summary_engine_context ctxt,
list  l_paths 
)
static

Definition at line 192 of file liveness_analysis_engine.c.

193 {
194  pips_debug_effects(3, "adding paths\n", l_paths);
196  ctxt->l_current_paths = l_paths;
197  else
198  // functions that can be pointed by effects_test_union_op:
199  // EffectsMayUnion
200  // RegionsMayUnion
201  // ReferenceTestUnion
202  ctxt->l_current_paths = (*effects_test_union_op)(ctxt->l_current_paths , l_paths,
204 
205  pips_debug_effects(3, "current paths\n", ctxt->l_current_paths);
206 }

References effects_same_action_p(), live_out_summary_engine_context::l_current_paths, list_undefined_p, and pips_debug_effects.

Referenced by live_out_paths_from_call_site_to_callee().

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