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

Go to the source code of this file.

Functions

static void flint_initialize_statement_def_use_variables (graph dependence_graph)
 Build the tables relating a statement with the variables it uses that have been initialized elsewhere. More...
 
static void flint_free_statement_def_use_variables ()
 Remove the flint_statement_def_use_variables data structure: More...
 
static bool flint_variable_uninitialize_elsewhere (statement s, entity a_variable)
 Return true if a_variable is not initialized elsewhere: More...
 
static bool flint_check_uninitialized_variables_in_statement (statement s)
 Warn about uninitialized variables in this statement: More...
 
void flint_uninitialized_variables (graph dependence_graph, statement module_stat)
 Warn about conservatively uninitialized variables in the module: More...
 

Variables

static hash_table flint_statement_def_use_variables
 
static bool flint_no_uninitialized_variable_ouput_yet
 

Function Documentation

◆ flint_check_uninitialized_variables_in_statement()

static bool flint_check_uninitialized_variables_in_statement ( statement  s)
static

Warn about uninitialized variables in this statement:

It appears that effects are packed by statement number or ordering. I assume that to factorize the prettyprint:

Nothing has been output yet: add a banner:

Go on recursion...

Definition at line 167 of file uninitialized_variables.c.

168 {
169  list effects_list = load_proper_rw_effects_list(s);
170 
171  bool something_said_about_this_statement = false;
172 
173  /* It appears that effects are packed by statement number or
174  ordering. I assume that to factorize the prettyprint: */
175  MAP(EFFECT, an_effect,
176  {
177  reference a_reference = effect_any_reference(an_effect);
178  entity a_variable = reference_variable(a_reference);
179  if (action_read_p(effect_action(an_effect))
182  /* Nothing has been output yet: add a banner: */
183  raw_flint_message(false,
184  "\n\nNon-initialized variables:"
185  "\n--------------------------\n");
187  }
188  if (!something_said_about_this_statement) {
189  raw_flint_message(false,
190  "In statement number %d (%d.%d):\n",
191  statement_number(s),
194  something_said_about_this_statement = true;
195  }
196  raw_flint_message(true,
197  "\t\"%s\" used but not initialized.\n",
199  }
200  },
201  effects_list);
202 
203  /* Go on recursion... */
204  return true;
205 }
list load_proper_rw_effects_list(statement)
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
#define effect_action(x)
Definition: effects.h:642
#define action_read_p(x)
Definition: effects.h:311
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
static entity a_variable
void raw_flint_message(bool count, char *fmt,...)
Same as flint_message but a bare bones version
Definition: flint.c:211
#define MAP(_map_CASTER, _map_item, _map_code, _map_list)
Apply/map an instruction block on all the elements of a list (old fashioned)
Definition: newgen_list.h:226
const char * entity_minimal_name(entity e)
Do preserve scope informations.
Definition: naming.c:214
#define ORDERING_NUMBER(o)
#define ORDERING_STATEMENT(o)
#define reference_variable(x)
Definition: ri.h:2326
#define statement_ordering(x)
Definition: ri.h:2454
#define statement_number(x)
Definition: ri.h:2452
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
static bool flint_no_uninitialized_variable_ouput_yet
static bool flint_variable_uninitialize_elsewhere(statement s, entity a_variable)
Return true if a_variable is not initialized elsewhere:

References a_variable, action_read_p, EFFECT, effect_action, effect_any_reference, entity_minimal_name(), flint_no_uninitialized_variable_ouput_yet, flint_variable_uninitialize_elsewhere(), load_proper_rw_effects_list(), MAP, ORDERING_NUMBER, ORDERING_STATEMENT, raw_flint_message(), reference_variable, statement_number, and statement_ordering.

Referenced by flint_uninitialized_variables().

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

◆ flint_free_statement_def_use_variables()

static void flint_free_statement_def_use_variables ( )
static

Remove the flint_statement_def_use_variables data structure:

Definition at line 133 of file uninitialized_variables.c.

134 {
135  HASH_MAP(a_statement, def_use_variables,
136  {
137  set_free((set) def_use_variables);
138  },
142 }
void hash_table_free(hash_table htp)
this function deletes a hash table that is no longer useful.
Definition: hash.c:327
#define HASH_MAP(k, v, code, ht)
Definition: newgen_hash.h:60
void set_free(set)
Definition: set.c:332
FI: I do not understand why the type is duplicated at the set level.
Definition: set.c:59
static hash_table flint_statement_def_use_variables

References flint_statement_def_use_variables, HASH_MAP, hash_table_free(), and set_free().

Referenced by flint_uninitialized_variables().

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

◆ flint_initialize_statement_def_use_variables()

static void flint_initialize_statement_def_use_variables ( graph  dependence_graph)
static

Build the tables relating a statement with the variables it uses that have been initialized elsewhere.

This function is heavily inspired by build_statement_to_statement_dependence_mapping() in the use-def elimination transformation:

Try to find at least one of the use-def chains between s and a successor:

Something is useful for the current statement if it writes something that is used in the current statement:

The dependance is not a use-def one, look forward...

FI: it looks more like a def-use...

Mark that we will visit the node that defined a source for this statement, if not already visited:

FI: in Fortran, with static aliasing, this is not really safe. a_variable is not uniquely defined

It is the first dependence found for use. Create the set.

Mark the fact that s2 create something useful for s1:

One use-def is enough for this variable couple:

Definition at line 46 of file uninitialized_variables.c.

47 {
49 
51  statement s1 = vertex_to_statement(a_vertex);
52 
53  pips_debug(7, "\tSuccessor list: %p for statement ordering %td\n",
54  vertex_successors(a_vertex),
56  FOREACH(SUCCESSOR, a_successor, vertex_successors(a_vertex)) {
57  vertex v2 = successor_vertex(a_successor);
59  dg_arc_label an_arc_label = successor_arc_label(a_successor);
60  pips_debug(7, "\t%p --> %p with conflicts\n", s1, s2);
61  /* Try to find at least one of the use-def chains between
62  s and a successor: */
63  FOREACH(CONFLICT, a_conflict,
64  dg_arc_label_conflicts(an_arc_label)) {
65  statement use;
66  statement def;
67  effect src_eff = conflict_source(a_conflict);
68  effect sink_eff = conflict_sink(a_conflict);
69 
70  ifdebug(7) {
71  fprintf(stderr, "\t\tfrom ");
72  print_words(stderr, words_effect(src_eff));
73  fprintf(stderr, " to ");
74  print_words(stderr, words_effect(sink_eff));
75  fprintf(stderr, "\n");
76  }
77 
78  /* Something is useful for the current statement if it writes
79  something that is used in the current statement: */
80  if (action_write_p(effect_action(src_eff))
81  && action_read_p(effect_action(sink_eff))) {
82  def = s1;
83  use = s2;
84  }
85  else
86  /* The dependance is not a use-def one, look forward... */
87  /* FI: it looks more like a def-use... */
88  continue;
89 
90  {
91  /* Mark that we will visit the node that defined a source
92  for this statement, if not already visited: */
93  /* FI: in Fortran, with static aliasing, this is not really
94  safe. a_variable is not uniquely defined */
96  set def_use_variables;
97 
98  def_use_variables = (set) hash_get(flint_statement_def_use_variables, (char *) use);
99 
100  if (def_use_variables == (set) HASH_UNDEFINED_VALUE) {
101  /* It is the first dependence found for use. Create the
102  set. */
103  def_use_variables = set_make(set_pointer);
104 
106  (char *) use,
107  (char *) def_use_variables);
108  }
109 
110  /* Mark the fact that s2 create something
111  useful for s1: */
112  set_add_element(def_use_variables,
113  def_use_variables,
114  (char *) a_variable);
115 
116  pips_debug(6, "\tUse: statement %p (%#tx). Def: statement %p (%#tx), variable \"%s\".\n",
117  use, (_uint) statement_ordering(use),
118  def, (_uint) statement_ordering(def),
120  }
121 
122  /* One use-def is enough for this variable
123  couple: */
124  break;
125  }
126  }
127  }
128 }
static graph dependence_graph
Definition: delay.c:93
#define dg_vertex_label_statement(x)
Definition: dg.h:235
#define conflict_sink(x)
Definition: dg.h:167
#define CONFLICT(x)
CONFLICT.
Definition: dg.h:134
#define dg_arc_label_conflicts(x)
Definition: dg.h:201
#define conflict_source(x)
Definition: dg.h:165
list words_effect(effect)
#define action_write_p(x)
Definition: effects.h:314
#define successor_vertex(x)
Definition: graph.h:118
#define successor_arc_label(x)
Definition: graph.h:116
#define vertex_vertex_label(x)
Definition: graph.h:152
#define vertex_successors(x)
Definition: graph.h:154
#define SUCCESSOR(x)
SUCCESSOR.
Definition: graph.h:86
#define graph_vertices(x)
Definition: graph.h:82
#define VERTEX(x)
VERTEX.
Definition: graph.h:122
#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
hash_table hash_table_make(hash_key_type key_type, size_t size)
Definition: hash.c:294
void * hash_get(const hash_table htp, const void *key)
this function retrieves in the hash table pointed to by htp the couple whose key is equal to key.
Definition: hash.c:449
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
statement vertex_to_statement(vertex v)
Vertex_to_statement looks for the statement that is pointed to by vertex v.
Definition: util.c:45
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
@ hash_pointer
Definition: newgen_hash.h:32
#define HASH_UNDEFINED_VALUE
value returned by hash_get() when the key is not found; could also be called HASH_KEY_NOT_FOUND,...
Definition: newgen_hash.h:56
struct _set_chunk * set
Definition: newgen_set.h:38
@ set_pointer
Definition: newgen_set.h:44
set set_make(set_type)
Create an empty set of any type but hash_private.
Definition: set.c:102
set set_add_element(set, const set, const void *)
Definition: set.c:152
uintptr_t _uint
Definition: newgen_types.h:54
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
s1
Definition: set.c:247
#define ifdebug(n)
Definition: sg.c:47
void print_words(FILE *fd, cons *lw)
Definition: print.c:263

References a_variable, action_read_p, action_write_p, CONFLICT, conflict_sink, conflict_source, dependence_graph, dg_arc_label_conflicts, dg_vertex_label_statement, effect_action, effect_any_reference, entity_minimal_name(), flint_statement_def_use_variables, FOREACH, fprintf(), graph_vertices, hash_get(), hash_pointer, hash_put(), hash_table_make(), HASH_UNDEFINED_VALUE, ifdebug, pips_debug, print_words(), reference_variable, s1, set_add_element(), set_make(), set_pointer, statement_ordering, SUCCESSOR, successor_arc_label, successor_vertex, VERTEX, vertex_successors, vertex_to_statement(), vertex_vertex_label, and words_effect().

Referenced by flint_uninitialized_variables().

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

◆ flint_uninitialized_variables()

void flint_uninitialized_variables ( graph  dependence_graph,
statement  module_stat 
)

Warn about conservatively uninitialized variables in the module:

uninitialized_variables.c

Parameters
dependence_graphependence_graph
module_statodule_stat

Definition at line 210 of file uninitialized_variables.c.

212 {
215 
216  gen_recurse(module_stat,
219  gen_null);
220 
222  raw_flint_message(false,
223  "\n");
224 
226 }
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
void gen_null(__attribute__((unused)) void *unused)
Ignore the argument.
Definition: genClib.c:2752
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
static void flint_initialize_statement_def_use_variables(graph dependence_graph)
Build the tables relating a statement with the variables it uses that have been initialized elsewhere...
static void flint_free_statement_def_use_variables()
Remove the flint_statement_def_use_variables data structure:
static bool flint_check_uninitialized_variables_in_statement(statement s)
Warn about uninitialized variables in this statement:

References dependence_graph, flint_check_uninitialized_variables_in_statement(), flint_free_statement_def_use_variables(), flint_initialize_statement_def_use_variables(), flint_no_uninitialized_variable_ouput_yet, gen_null(), gen_recurse, raw_flint_message(), and statement_domain.

Referenced by flinter().

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

◆ flint_variable_uninitialize_elsewhere()

static bool flint_variable_uninitialize_elsewhere ( statement  s,
entity  a_variable 
)
static

Return true if a_variable is not initialized elsewhere:

There is no variable for this statement with previously initialized value. Just return TRUE:

OK, looks like the variable have been previously initialized:

Definition at line 147 of file uninitialized_variables.c.

149 {
150  set def_use_variables = (set) hash_get(flint_statement_def_use_variables,
151  (char *) s);
152  if (def_use_variables == (set) HASH_UNDEFINED_VALUE)
153  /* There is no variable for this statement with previously
154  initialized value. Just return TRUE: */
155  return true;
156 
157  if (set_belong_p(def_use_variables, (char *) a_variable))
158  /* OK, looks like the variable have been previously initialized: */
159  return false;
160 
161  return true;
162 }
bool set_belong_p(const set, const void *)
Definition: set.c:194

References a_variable, flint_statement_def_use_variables, hash_get(), HASH_UNDEFINED_VALUE, and set_belong_p().

Referenced by flint_check_uninitialized_variables_in_statement().

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

Variable Documentation

◆ flint_no_uninitialized_variable_ouput_yet

bool flint_no_uninitialized_variable_ouput_yet
static

◆ flint_statement_def_use_variables