PIPS
array_bound_check_instrumentation.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "genC.h"
#include "linear.h"
#include "ri.h"
#include "effects.h"
#include "ri-util.h"
#include "prettyprint.h"
#include "effects-util.h"
#include "database.h"
#include "pipsdbm.h"
#include "resources.h"
#include "misc.h"
#include "control.h"
#include "properties.h"
#include "alias_private.h"
#include "instrumentation.h"
+ Include dependency graph for array_bound_check_instrumentation.c:

Go to the source code of this file.

Data Structures

struct  abc_instrumentation_context_t
 context data structure for array_bound_check_instrumentation newgen recursion More...
 
struct  abc_number_of_operators_context_t
 

Macros

#define ABC_COUNT   "ARRAY_BOUND_CHECK_COUNT"
 

Typedefs

typedef struct abc_instrumentation_context_tabc_instrumentation_context_p
 
typedef struct abc_number_of_operators_context_tabc_number_of_operators_context_p
 

Functions

static int initial_code_abc_reference (reference r)
 
static int initial_code_abc_expression (expression e)
 
static int initial_code_abc_call (call cal)
 
static statement make_abc_count_statement (int n)
 
statement array_bound_check_display ()
 array_bound_check_instrumentation.c More...
 
static void abc_instrumentation_insert_before_statement (statement s, statement s1, abc_instrumentation_context_p context)
 
static void initial_code_abc_statement_rwt (statement s, abc_instrumentation_context_p context)
 
static bool abc_bound_violation_stop_statement_p (statement s)
 
static bool number_of_operators_flt (expression e, abc_number_of_operators_context_p context)
 
static int number_of_logical_operators (expression e)
 
static void pips_code_abc_statement_rwt (statement s, abc_instrumentation_context_p context)
 
static bool store_mapping (control c, abc_instrumentation_context_p context)
 
static bool push_uns (unstructured u, abc_instrumentation_context_p context)
 
static void pop_uns (unstructured u, abc_instrumentation_context_p context)
 
static void initial_code_abc_statement (statement module_statement)
 
static void pips_code_abc_statement (statement module_statement)
 
bool old_array_bound_check_instrumentation (const char *module_name)
 
bool array_bound_check_instrumentation (const char *module_name)
 

Variables

static entity abccount
 
static entity mod_ent
 
static list l_commons = NIL
 
static int number_of_scalar_variables = 0
 
static int number_of_array_variables = 0
 

Macro Definition Documentation

◆ ABC_COUNT

#define ABC_COUNT   "ARRAY_BOUND_CHECK_COUNT"

Definition at line 68 of file array_bound_check_instrumentation.c.

Typedef Documentation

◆ abc_instrumentation_context_p

◆ abc_number_of_operators_context_p

Function Documentation

◆ abc_bound_violation_stop_statement_p()

static bool abc_bound_violation_stop_statement_p ( statement  s)
static

Definition at line 308 of file array_bound_check_instrumentation.c.

309 {
310  if (stop_statement_p(s))
311  {
313  if (l!= NIL)
314  {
315  expression e = EXPRESSION(CAR(l));
317  // fprintf(stderr, "name = %s\n",name);
318  if (strstr(name,"Bound violation") != NULL) return true;
319  return false;
320  }
321  return false;
322  }
323  return false;
324 }
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
call statement_call(statement)
Get the call of a statement.
Definition: statement.c:1406
bool stop_statement_p(statement)
Test if a statement is a Fortran STOP.
Definition: statement.c:263
#define call_function(x)
Definition: ri.h:709
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define entity_name(x)
Definition: ri.h:2790
#define syntax_call(x)
Definition: ri.h:2736
#define call_arguments(x)
Definition: ri.h:711
#define expression_syntax(x)
Definition: ri.h:1247
The structure used to build lists in NewGen.
Definition: newgen_list.h:41

References call_arguments, call_function, CAR, entity_name, EXPRESSION, expression_syntax, NIL, statement_call(), stop_statement_p(), and syntax_call.

Referenced by pips_code_abc_statement_rwt().

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

◆ abc_instrumentation_insert_before_statement()

static void abc_instrumentation_insert_before_statement ( statement  s,
statement  s1,
abc_instrumentation_context_p  context 
)
static

If s is in an unstructured instruction, we must pay attention when inserting s1 before s.

take the control that has s as its statement

take the unstructured correspond to the control c

for a consistent unstructured, a test must have 2 successors, so if s1 is a test, we transform it into sequence in order to avoid this constraint. Then we create a new control for it, with the predecessors are those of c and the only one successor is c. The new predecessors of c are only the new control

if c is the entry node of the correspond unstructured u, the newc will become the new entry node of u

Definition at line 168 of file array_bound_check_instrumentation.c.

170 {
171  /* If s is in an unstructured instruction, we must pay attention
172  when inserting s1 before s. */
174  {
175  /* take the control that has s as its statement */
177  if (stack_size(context->uns)>0)
178  {
179  /* take the unstructured correspond to the control c */
181  control newc;
182  ifdebug(2)
183  {
184  fprintf(stderr, "Unstructured case: \n");
185  print_statement(s);
186  }
187  /* for a consistent unstructured, a test must have 2 successors,
188  so if s1 is a test, we transform it into sequence in order
189  to avoid this constraint.
190  Then we create a new control for it, with the predecessors
191  are those of c and the only one successor is c.
192  The new predecessors of c are only the new control*/
193  if (statement_test_p(s1))
194  {
195  list seq = CONS(STATEMENT,s1,NIL);
197  make_sequence(seq)));
198  newc = make_control(s2, control_predecessors(c), CONS(CONTROL, c, NIL));
199  }
200  else
202  // replace c by newc as successor of each predecessor of c
203  MAP(CONTROL, co,
204  {
205  MAPL(lc,
206  {
207  if (CONTROL(CAR(lc))==c) CONTROL_(CAR(lc)) = newc;
208  }, control_successors(co));
209  },control_predecessors(c));
211  /* if c is the entry node of the correspond unstructured u,
212  the newc will become the new entry node of u */
213  if (unstructured_control(u)==c)
214  unstructured_control(u) = newc;
215  }
216  else
217  // there is no unstructured (?)
218  insert_statement(s,s1,true);
219  }
220  else
221  // structured case
222  insert_statement(s,s1,true);
223 }
control apply_persistant_statement_to_control(persistant_statement_to_control f, statement k)
Definition: ri.c:1597
instruction make_instruction(enum instruction_utype tag, void *val)
Definition: ri.c:1166
bool bound_persistant_statement_to_control_p(persistant_statement_to_control f, statement k)
Definition: ri.c:1609
sequence make_sequence(list a)
Definition: ri.c:2125
control make_control(statement a1, list a2, list a3)
Definition: ri.c:523
statement instruction_to_statement(instruction)
Build a statement from a give instruction.
Definition: statement.c:597
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
#define MAPL(_map_list_cp, _code, _l)
Apply some code on the addresses of all the elements of a list.
Definition: newgen_list.h:203
#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
bool statement_test_p(statement)
Definition: statement.c:343
void insert_statement(statement, statement, bool)
This is the normal entry point.
Definition: statement.c:2570
void * stack_head(const stack)
returns the item on top of stack s
Definition: stack.c:420
int stack_size(const stack)
observers
void print_statement(statement)
Print a statement on stderr.
Definition: statement.c:98
#define unstructured_control
After the modification in Newgen: unstructured = entry:control x exit:control we have create a macro ...
#define CONTROL_(x)
Definition: ri.h:913
#define control_predecessors(x)
Definition: ri.h:943
struct _newgen_struct_unstructured_ * unstructured
Definition: ri.h:447
#define CONTROL(x)
CONTROL.
Definition: ri.h:910
@ is_instruction_sequence
Definition: ri.h:1469
#define control_successors(x)
Definition: ri.h:945
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
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
Definition: delay.c:253

References apply_persistant_statement_to_control(), bound_persistant_statement_to_control_p(), CAR, CONS, CONTROL, CONTROL_, control_predecessors, control_successors, fprintf(), ifdebug, insert_statement(), instruction_to_statement(), is_instruction_sequence, make_control(), make_instruction(), make_sequence(), MAP, MAPL, NIL, print_statement(), s1, stack_head(), stack_size(), STATEMENT, statement_test_p(), and unstructured_control.

Referenced by initial_code_abc_statement_rwt(), and pips_code_abc_statement_rwt().

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

◆ array_bound_check_display()

statement array_bound_check_display ( void  )

array_bound_check_instrumentation.c

Attention : no strdup => newgen error

Definition at line 158 of file array_bound_check_instrumentation.c.

159 {
160  string message = " PRINT *,\'Number of bound checks:\', ARRAY_BOUND_CHECK_COUNT\n" ;
161  /* Attention : no strdup => newgen error */
162  // statement retour = make_call_statement(CONTINUE_FUNCTION_NAME,
163  // NIL,entity_undefined,message);
166 }
statement make_call_statement(string, list, entity, string)
This function is limited to intrinsics calls...
Definition: statement.c:1274
#define CONTINUE_FUNCTION_NAME
#define entity_undefined
Definition: ri.h:2761
char * strdup()

References CONTINUE_FUNCTION_NAME, entity_undefined, make_call_statement(), NIL, and strdup().

Referenced by initial_code_abc_statement_rwt(), and pips_code_abc_statement_rwt().

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

◆ array_bound_check_instrumentation()

bool array_bound_check_instrumentation ( const char *  module_name)

ser_log("*\n%d variable in %s *\n",gen_length(l),entity_name(sec)); number_of_variables = number_of_variables + gen_length(l);

Eliminate 4 special variables : MAIN000:DYNAMIC, MAIN000:STATIC,MAIN000:HEAP, MAIN000:STACK

Parameters
module_nameodule_name

Definition at line 557 of file array_bound_check_instrumentation.c.

558 {
561  MAP(ENTITY,ent,
562  {
563  if (!formal_parameter_p(ent))
564  {
565  if (variable_in_common_p(ent))
566  {
568  if (!entity_in_list_p(sec,l_commons))
569  {
570  area a = type_area(entity_type(sec));
571  list l = area_layout(a);
572  /*user_log("*\n%d variable in %s *\n",gen_length(l),entity_name(sec));
573  number_of_variables = number_of_variables + gen_length(l);*/
574  MAP(ENTITY, e,
575  {
576  type t = entity_type(e);
577  if (type_variable_p(t))
578  {
579  if (entity_scalar_p(e))
580  {
581  user_log("*\nCommon and scalar variable %s *\n",entity_name(e));
583  }
584  else
585  {
586  user_log("*\nCommon and array variable %s *\n",entity_name(e));
588  }
589  }
590  },l);
592  }
593  }
594  else
595  {
596  if (local_entity_of_module_p(ent,mod))
597  {
598  type t = entity_type(ent);
599  user_log("*\nLocal variable %s of type %d *\n",entity_name(ent),type_tag(t));
600  if (type_variable_p(t))
601  {
602  if (entity_scalar_p(ent))
603  {
604  user_log("*\nLocal and scalar variable %s *\n",entity_name(ent));
606  }
607  else
608  {
609  user_log("*\nLocal and array variable %s *\n",entity_name(ent));
611  }
612  }
613  }
614  }
615  }
616  },d);
617  /* Eliminate 4 special variables : MAIN000:*DYNAMIC*, MAIN000:*STATIC*,MAIN000:*HEAP*, MAIN000:*STACK* **/
618  user_log("*\nNumber of scalar variables :%d *\n", number_of_scalar_variables);
619  user_log("*\nNumber of array variables :%d *\n", number_of_array_variables);
620  return true;
621 }
void user_log(const char *format,...)
Definition: message.c:234
static list l_commons
static int number_of_scalar_variables
static int number_of_array_variables
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
bool entity_in_list_p(entity ent, list ent_l)
look for ent in ent_l
Definition: entity.c:2221
entity local_name_to_top_level_entity(const char *n)
This function try to find a top-level entity from a local name.
Definition: entity.c:1450
bool local_entity_of_module_p(entity e, entity module)
This test shows that "e" has been declared in "module".
Definition: entity.c:1069
bool entity_scalar_p(entity)
The concrete type of e is a scalar type.
Definition: variable.c:1113
bool variable_in_common_p(entity)
true if v is in a common.
Definition: variable.c:1570
bool formal_parameter_p(entity)
Definition: variable.c:1489
#define type_tag(x)
Definition: ri.h:2940
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define entity_storage(x)
Definition: ri.h:2794
#define code_declarations(x)
Definition: ri.h:784
#define ram_section(x)
Definition: ri.h:2249
#define area_layout(x)
Definition: ri.h:546
#define value_code(x)
Definition: ri.h:3067
#define type_area(x)
Definition: ri.h:2946
#define storage_ram(x)
Definition: ri.h:2521
#define entity_type(x)
Definition: ri.h:2792
#define type_variable_p(x)
Definition: ri.h:2947
#define entity_initial(x)
Definition: ri.h:2796

References area_layout, code_declarations, CONS, ENTITY, entity_in_list_p(), entity_initial, entity_name, entity_scalar_p(), entity_storage, entity_type, formal_parameter_p(), gen_nconc(), l_commons, local_entity_of_module_p(), local_name_to_top_level_entity(), MAP, module_name(), NIL, number_of_array_variables, number_of_scalar_variables, ram_section, storage_ram, type_area, type_tag, type_variable_p, user_log(), value_code, and variable_in_common_p().

+ Here is the call graph for this function:

◆ initial_code_abc_call()

static int initial_code_abc_call ( call  cal)
static

Definition at line 135 of file array_bound_check_instrumentation.c.

136 {
137  list args = call_arguments(cal);
138  int retour = 0;
139  while (!ENDP(args))
140  {
141  expression e = EXPRESSION(CAR(args));
142  int temp = initial_code_abc_expression(e);
143  retour = retour + temp;
144  args = CDR(args);
145  }
146  return retour;
147 }
static int initial_code_abc_expression(expression e)
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111

References call_arguments, CAR, CDR, ENDP, EXPRESSION, and initial_code_abc_expression().

Referenced by initial_code_abc_expression(), and initial_code_abc_statement_rwt().

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

◆ initial_code_abc_expression()

static int initial_code_abc_expression ( expression  e)
static

the syntax of an expression can be a reference, a range or a call

There is nothing to check here

Definition at line 115 of file array_bound_check_instrumentation.c.

116 {
117  /* the syntax of an expression can be a reference, a range or a call*/
118  if (!expression_implied_do_p(e))
119  {
120  syntax s = expression_syntax(e);
121  tag t = syntax_tag(s);
122  switch (t){
123  case is_syntax_call:
125  case is_syntax_reference:
127  case is_syntax_range:
128  /* There is nothing to check here*/
129  return 0;
130  }
131  }
132  return 0;
133 }
static int initial_code_abc_call(call cal)
static int initial_code_abc_reference(reference r)
int tag
TAG.
Definition: newgen_types.h:92
bool expression_implied_do_p(e)
Definition: expression.c:817
#define syntax_reference(x)
Definition: ri.h:2730
#define syntax_tag(x)
Definition: ri.h:2727
@ is_syntax_range
Definition: ri.h:2692
@ is_syntax_call
Definition: ri.h:2693
@ is_syntax_reference
Definition: ri.h:2691

References expression_implied_do_p(), expression_syntax, initial_code_abc_call(), initial_code_abc_reference(), is_syntax_call, is_syntax_range, is_syntax_reference, syntax_call, syntax_reference, and syntax_tag.

Referenced by initial_code_abc_call(), initial_code_abc_reference(), and initial_code_abc_statement_rwt().

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

◆ initial_code_abc_reference()

static int initial_code_abc_reference ( reference  r)
static

Definition at line 92 of file array_bound_check_instrumentation.c.

93 {
94  int retour = 0;
95  if (array_reference_p(r))
96  {
99  {
100  list arrayinds = reference_indices(r);
101  int i;
102  for (i=1;i <= (int) gen_length(arrayinds);i++)
103  {
104  expression ith = find_ith_argument(arrayinds,i);
105  int temp = initial_code_abc_expression(ith);
106  // two bound checks : lower and upper
107  retour = retour + 2;
108  retour = retour + temp;
109  }
110  }
111  }
112  return retour;
113 }
void const char const char const int
bool array_need_bound_check_p(entity e)
This function returns true, if the array needs bound checks false, otherwise.
size_t gen_length(const list l)
Definition: list.c:150
expression find_ith_argument(list args, int n)
Definition: expression.c:1147
bool array_reference_p(reference r)
predicates on references
Definition: expression.c:1861
#define reference_variable(x)
Definition: ri.h:2326
#define reference_indices(x)
Definition: ri.h:2328

References array_need_bound_check_p(), array_reference_p(), find_ith_argument(), gen_length(), initial_code_abc_expression(), int, reference_indices, and reference_variable.

Referenced by initial_code_abc_expression().

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

◆ initial_code_abc_statement()

static void initial_code_abc_statement ( statement  module_statement)
static

Definition at line 432 of file array_bound_check_instrumentation.c.

433 {
437 
442  NULL);
443 
445  stack_free(&context.uns);
446 
447 }
persistant_statement_to_control make_persistant_statement_to_control(void)
Definition: ri.c:1594
void free_persistant_statement_to_control(persistant_statement_to_control p)
Definition: ri.c:1561
static statement module_statement
Definition: alias_check.c:125
static void initial_code_abc_statement_rwt(statement s, abc_instrumentation_context_p context)
static void pop_uns(unstructured u, abc_instrumentation_context_p context)
static bool push_uns(unstructured u, abc_instrumentation_context_p context)
static bool store_mapping(control c, abc_instrumentation_context_p context)
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
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
void stack_free(stack *)
type, bucket_size, policy
Definition: stack.c:292
stack stack_make(int, int, int)
allocation
Definition: stack.c:246
#define unstructured_domain
newgen_type_domain_defined
Definition: ri.h:442
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
#define control_domain
newgen_controlmap_domain_defined
Definition: ri.h:98
context data structure for array_bound_check_instrumentation newgen recursion

References control_domain, free_persistant_statement_to_control(), gen_context_multi_recurse(), gen_null(), gen_true(), initial_code_abc_statement_rwt(), make_persistant_statement_to_control(), module_statement, pop_uns(), push_uns(), stack_free(), stack_make(), statement_domain, store_mapping(), and unstructured_domain.

Referenced by old_array_bound_check_instrumentation().

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

◆ initial_code_abc_statement_rwt()

static void initial_code_abc_statement_rwt ( statement  s,
abc_instrumentation_context_p  context 
)
static

There are 2 kinds of statement which cause the execution of the program to terminate

  1. STOP statement in every module
  2. END statement in main program ( PIPS considers the END statement of MAIN PROGRAM as a RETURN statement) we display the counter of bound checks before these kinds of statement

This code is not correct ! The counting statement must be inserted in the body of the loop !

bug Example abc_ins.f : there is STOP statement in the branch of if statement
IF (A(1).GE.L) ... STOP ENDIF free_instruction(s) in insert_statement will be not consistent => core dumped Solution : like pips_code_abc_statement_rwt

Definition at line 225 of file array_bound_check_instrumentation.c.

226 {
228  tag t = instruction_tag(i);
229  switch(t){
230  case is_instruction_call:
231  {
232  call cal = instruction_call(i);
233  int n = initial_code_abc_call(cal);
234  if (n > 0)
235  {
238  message_assert("statement is consistent",
240  }
242  {
243  /* There are 2 kinds of statement which cause the execution of the program to terminate
244  1. STOP statement in every module
245  2. END statement in main program
246  ( PIPS considers the END statement of MAIN PROGRAM as a RETURN statement)
247  we display the counter of bound checks before these kinds of statement */
250  message_assert("statement is consistent",
252  }
253  break;
254  }
256  {
259  int n = initial_code_abc_expression(e1);
260  /* This code is not correct !
261  The counting statement must be inserted in the body of the loop !*/
262  if (n>0)
263  {
266  message_assert("statement is consistent",
268  }
269  break;
270  }
271  case is_instruction_test:
272  {
273  test it = instruction_test(i);
274  expression e1 = test_condition(it);
275  int n = initial_code_abc_expression(e1);
276  if (n>0)
277  {
279  ifdebug(3)
280  {
281  fprintf(stderr, "\n Statement to be inserted before a test: ");
282  print_statement(sta);
283  print_statement(s);
284  }
285  /* bug Example abc_ins.f : there is STOP statement in the branch of if statement
286  IF (A(1).GE.L)
287  ...
288  STOP
289  ENDIF
290  free_instruction(s) in insert_statement will be not consistent => core dumped
291  Solution : like pips_code_abc_statement_rwt */
293  message_assert("statement is consistent",
295  }
296  break;
297  }
299  case is_instruction_loop:
301  break;
302  default:
303  pips_internal_error("Unexpected instruction tag %d ", t );
304  break;
305  }
306 }
bool statement_consistent_p(statement p)
Definition: ri.c:2195
static statement make_abc_count_statement(int n)
statement array_bound_check_display()
array_bound_check_instrumentation.c
static entity mod_ent
static void abc_instrumentation_insert_before_statement(statement s, statement s1, abc_instrumentation_context_p context)
bool return_statement_p(statement)
Test if a statement is a C or Fortran "return".
Definition: statement.c:172
#define pips_internal_error
Definition: misc-local.h:149
#define message_assert(msg, ex)
Definition: newgen_assert.h:47
bool entity_main_module_p(entity e)
Definition: entity.c:700
@ is_instruction_unstructured
Definition: ri.h:1475
@ is_instruction_whileloop
Definition: ri.h:1472
@ is_instruction_test
Definition: ri.h:1470
@ is_instruction_call
Definition: ri.h:1474
@ is_instruction_loop
Definition: ri.h:1471
#define instruction_tag(x)
Definition: ri.h:1511
#define test_condition(x)
Definition: ri.h:2833
#define instruction_whileloop(x)
Definition: ri.h:1523
#define statement_instruction(x)
Definition: ri.h:2458
#define instruction_call(x)
Definition: ri.h:1529
#define instruction_test(x)
Definition: ri.h:1517
#define whileloop_condition(x)
Definition: ri.h:3160

References abc_instrumentation_insert_before_statement(), array_bound_check_display(), entity_main_module_p(), fprintf(), ifdebug, initial_code_abc_call(), initial_code_abc_expression(), instruction_call, instruction_tag, instruction_test, instruction_whileloop, is_instruction_call, is_instruction_loop, is_instruction_sequence, is_instruction_test, is_instruction_unstructured, is_instruction_whileloop, make_abc_count_statement(), message_assert, mod_ent, pips_internal_error, print_statement(), return_statement_p(), statement_consistent_p(), statement_instruction, stop_statement_p(), test_condition, and whileloop_condition.

Referenced by initial_code_abc_statement().

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

◆ make_abc_count_statement()

static statement make_abc_count_statement ( int  n)
static

Definition at line 149 of file array_bound_check_instrumentation.c.

150 {
153  left,
154  int_to_expression(n));
155  return make_assign_statement(left,right);
156 }
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
static entity abccount
statement make_assign_statement(expression, expression)
Definition: statement.c:583
#define PLUS_OPERATOR_NAME
#define binary_intrinsic_expression(name, e1, e2)
expression reference_to_expression(reference r)
Definition: expression.c:196
expression int_to_expression(_int i)
transform an int into an expression and generate the corresponding entity if necessary; it is not cle...
Definition: expression.c:1188

References abccount, binary_intrinsic_expression, int_to_expression(), make_assign_statement(), make_reference(), NIL, PLUS_OPERATOR_NAME, and reference_to_expression().

Referenced by initial_code_abc_statement_rwt(), and pips_code_abc_statement_rwt().

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

◆ number_of_logical_operators()

static int number_of_logical_operators ( expression  e)
static

Definition at line 340 of file array_bound_check_instrumentation.c.

341 {
343  context.number =1;
347  gen_null2);
348  return context.number;
349 }
static bool number_of_operators_flt(expression e, abc_number_of_operators_context_p context)
#define gen_context_recurse(start, ctxt, domain_number, flt, rwt)
Definition: genC.h:285
void gen_null2(__attribute__((unused)) void *u1, __attribute__((unused)) void *u2)
idem with 2 args, to please overpeaky compiler checks
Definition: genClib.c:2758
#define expression_domain
newgen_execution_domain_defined
Definition: ri.h:154

References expression_domain, gen_context_recurse, gen_null2(), and number_of_operators_flt().

Referenced by pips_code_abc_statement_rwt().

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

◆ number_of_operators_flt()

static bool number_of_operators_flt ( expression  e,
abc_number_of_operators_context_p  context 
)
static

Definition at line 326 of file array_bound_check_instrumentation.c.

327 {
328  if (expression_call_p(e))
329  {
331  {
332  context->number ++;;
333  return true;
334  }
335  return false;
336  }
337  return false;
338 }
bool logical_operator_expression_p(expression e)
C xor is missing.
Definition: expression.c:573
bool expression_call_p(expression e)
Definition: expression.c:415

References expression_call_p(), and logical_operator_expression_p().

Referenced by number_of_logical_operators().

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

◆ old_array_bound_check_instrumentation()

bool old_array_bound_check_instrumentation ( const char *  module_name)

add COMMON ARRAY_BOUND_CHECK_COUNT to the declaration if main program : DATA ARRAY_BOUND_CHECK_COUNT 0

Begin the array bound check instrumentation phase. Get the code from dbm (true resource)

Before running the array_bound_check phase, for the implied-DO expression (in statement READ, WRITE of Fortran), we will create new Pips' loops before the READ/WRITE statement, it means that instead of checking array references for implied-DO statement (which is not true if we do it like other statements), we will check array references in new loops added

Reorder the module, because new loops have been added

Reorder the module, because new statements have been added

Parameters
module_nameodule_name

Definition at line 466 of file array_bound_check_instrumentation.c.

467 {
469  /* add COMMON ARRAY_BOUND_CHECK_COUNT to the declaration
470  if main program : DATA ARRAY_BOUND_CHECK_COUNT 0*/
471  string new_decl =
472  " INTEGER*8 ARRAY_BOUND_CHECK_COUNT\n"
473  " COMMON /ARRAY_BOUND_CHECK/ ARRAY_BOUND_CHECK_COUNT\n";
474  string new_decl_init =
475  " DATA ARRAY_BOUND_CHECK_COUNT /0/\n";
476  string old_decl;
477  basic b = make_basic_int(8);
481  old_decl = code_decls_text(entity_code(mod_ent));
482  // user_log("Old declaration = %s\n", code_decls_text(entity_code(mod_ent)));
484  // MAIN PROGRAM
486  = strdup(concatenate(old_decl, new_decl, new_decl_init,NULL));
487  else
489  = strdup(concatenate(old_decl, new_decl, NULL));
490  free(old_decl), old_decl = NULL;
491  // user_log("New declaration = %s\n", code_decls_text(entity_code(mod_ent)));
492  // fprintf(stderr, "NEW = %s\n", code_decls_text(entity_code(mod_ent)));
493  /* Begin the array bound check instrumentation phase.
494  * Get the code from dbm (true resource) */
496  db_get_memory_resource(DBR_CODE, module_name, true);
499  debug_on("ARRAY_BOUND_CHECK_INSTRUMENTATION_DEBUG_LEVEL");
500  if (get_bool_property("INITIAL_CODE_ARRAY_BOUND_CHECK_INSTRUMENTATION"))
501  {
502  // instrument the initial code
503  // Rewrite Implied_DO code
504 
505  /* Before running the array_bound_check phase,
506  * for the implied-DO expression (in statement
507  * READ, WRITE of Fortran), we will create new Pips' loops
508  * before the READ/WRITE statement,
509  * it means that instead of checking array references
510  * for implied-DO statement (which is not
511  * true if we do it like other statements), we will check
512  * array references in new loops added*/
513 
514  // rewrite_implied_do(module_statement);
515  /* Reorder the module, because new loops have been added */
516  // module_reorder(module_statement);
517  ifdebug(1)
518  {
519  debug(1, " Initial code array bound check instrumentation",
520  "Begin for %s\n", module_name);
521  pips_assert("Statement is consistent ...",
523  }
525  }
526  if (get_bool_property("PIPS_CODE_ARRAY_BOUND_CHECK_INSTRUMENTATION"))
527  {
528  ifdebug(1)
529  {
530  debug(1, "PIPS code array bound check instrumentation ",
531  "Begin for %s\n", module_name);
532  pips_assert("Statement is consistent ...",
534  }
535 
537  }
538  /* Reorder the module, because new statements have been added */
540  ifdebug(1)
541  {
542  pips_assert("Statement is consistent ...",
544  debug(1, "Array bound check instrumentation","End for %s\n", module_name);
545  }
546  debug_off();
551  return true;
552 }
basic make_basic_int(intptr_t _field_)
Definition: ri.c:158
static void pips_code_abc_statement(statement module_statement)
static void initial_code_abc_statement(statement module_statement)
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
void free(void *)
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
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
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
#define DB_PUT_MEMORY_RESOURCE(res_name, own_name, res_val)
conform to old interface.
Definition: pipsdbm-local.h:66
#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
void debug(const int the_expected_debug_level, const char *calling_function_name, const char *a_message_format,...)
ARARGS0.
Definition: debug.c:189
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
hash_table set_ordering_to_statement(statement s)
To be used instead of initialize_ordering_to_statement() to make sure that the hash table ots is in s...
Definition: ordering.c:172
void reset_ordering_to_statement(void)
Reset the mapping from ordering to statement.
Definition: ordering.c:185
bool module_reorder(statement body)
Reorder a module and recompute order to statement if any.
Definition: reorder.c:244
code entity_code(entity e)
Definition: entity.c:1098
entity make_scalar_entity(const char *, const char *, basic)
entity make_scalar_entity(name, module_name, base)
Definition: variable.c:331
#define code_decls_text(x)
Definition: ri.h:786

References ABC_COUNT, abccount, code_decls_text, concatenate(), db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug(), debug_off, debug_on, entity_code(), entity_main_module_p(), free(), get_bool_property(), get_current_module_entity(), ifdebug, initial_code_abc_statement(), local_name_to_top_level_entity(), make_basic_int(), make_scalar_entity(), mod_ent, module_name(), module_reorder(), module_statement, pips_assert, pips_code_abc_statement(), reset_current_module_entity(), reset_current_module_statement(), reset_ordering_to_statement(), set_current_module_entity(), set_current_module_statement(), set_ordering_to_statement(), statement_consistent_p(), and strdup().

+ Here is the call graph for this function:

◆ pips_code_abc_statement()

◆ pips_code_abc_statement_rwt()

static void pips_code_abc_statement_rwt ( statement  s,
abc_instrumentation_context_p  context 
)
static

s is a bound check generated by PIPS which has this form: IF (e) THEN STOP "Bound violation ...." ENDIF we replace it by: ARRAY_BOUND_CHECK_COUNT = ARRAY_BOUND_CHECK_COUNT + n IF (e) THEN PRINT *,'Number of bound checks : ', ARRAY_BOUND_CHECK_COUNT STOP "Bound violation ...." ENDIF

There are 2 kinds of statement which cause the execution of the program to terminate

  1. STOP statement in every module
  2. END statement in main program ( PIPS considers the END statement of MAIN PROGRAM as a RETURN statement) we display the counter of bound checks before these kinds of statement The case of STOP "Bound violation" is done separately

Definition at line 351 of file array_bound_check_instrumentation.c.

352 {
354  tag t = instruction_tag(i);
355  switch(t){
356  case is_instruction_test:
357  {
358  test it = instruction_test(i);
359  statement true_branch = test_true(it);
360  if (abc_bound_violation_stop_statement_p(true_branch))
361  {
362  /* s is a bound check generated by PIPS which has this form:
363  IF (e) THEN
364  STOP "Bound violation ...."
365  ENDIF
366  we replace it by:
367  ARRAY_BOUND_CHECK_COUNT = ARRAY_BOUND_CHECK_COUNT + n
368  IF (e) THEN
369  PRINT *,'Number of bound checks : ', ARRAY_BOUND_CHECK_COUNT
370  STOP "Bound violation ...."
371  ENDIF */
372  expression e = test_condition(it);
373  int n = number_of_logical_operators(e);
376  list ls1 = CONS(STATEMENT,s1,CONS(STATEMENT,true_branch,NIL));
377  list ls2;
379  make_sequence(ls1)));
380  ls2 = CONS(STATEMENT,sta,CONS(STATEMENT,copy_statement(s),NIL));
382  make_sequence(ls2));
383  }
384  break;
385  }
386  case is_instruction_call:
387  {
390  {
391  /* There are 2 kinds of statement which cause the execution of the program to terminate
392  1. STOP statement in every module
393  2. END statement in main program
394  ( PIPS considers the END statement of MAIN PROGRAM as a RETURN statement)
395  we display the counter of bound checks before these kinds of statement
396  The case of STOP "Bound violation" is done separately */
399  }
400  break;
401  }
404  case is_instruction_loop:
406  break;
407  default:
408  pips_internal_error("Unexpected instruction tag %d ", t );
409  break;
410  }
411 }
statement copy_statement(statement p)
STATEMENT.
Definition: ri.c:2186
static int number_of_logical_operators(expression e)
static bool abc_bound_violation_stop_statement_p(statement s)
#define test_true(x)
Definition: ri.h:2835

References abc_bound_violation_stop_statement_p(), abc_instrumentation_insert_before_statement(), array_bound_check_display(), CONS, copy_statement(), entity_main_module_p(), instruction_tag, instruction_test, instruction_to_statement(), is_instruction_call, is_instruction_loop, is_instruction_sequence, is_instruction_test, is_instruction_unstructured, is_instruction_whileloop, make_abc_count_statement(), make_instruction(), make_sequence(), mod_ent, NIL, number_of_logical_operators(), pips_internal_error, return_statement_p(), s1, STATEMENT, statement_instruction, stop_statement_p(), test_condition, and test_true.

Referenced by pips_code_abc_statement().

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

◆ pop_uns()

static void pop_uns ( unstructured  u,
abc_instrumentation_context_p  context 
)
static

Definition at line 426 of file array_bound_check_instrumentation.c.

427 {
428  pips_assert("true", u==u && context==context);
429  stack_pop(context->uns);
430 }
void * stack_pop(stack)
POPs one item from stack s.
Definition: stack.c:399

References pips_assert, and stack_pop().

Referenced by initial_code_abc_statement(), and pips_code_abc_statement().

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

◆ push_uns()

static bool push_uns ( unstructured  u,
abc_instrumentation_context_p  context 
)
static

Definition at line 420 of file array_bound_check_instrumentation.c.

421 {
422  stack_push((char *) u, context->uns);
423  return true;
424 }
void stack_push(void *, stack)
stack use
Definition: stack.c:373

References stack_push().

Referenced by initial_code_abc_statement(), and pips_code_abc_statement().

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

◆ store_mapping()

static bool store_mapping ( control  c,
abc_instrumentation_context_p  context 
)
static

Definition at line 413 of file array_bound_check_instrumentation.c.

414 {
416  control_statement(c), c);
417  return true;
418 }
void extend_persistant_statement_to_control(persistant_statement_to_control f, statement k, control v)
Definition: ri.c:1603
#define control_statement(x)
Definition: ri.h:941

References control_statement, and extend_persistant_statement_to_control().

Referenced by initial_code_abc_statement(), and pips_code_abc_statement().

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

Variable Documentation

◆ abccount

◆ l_commons

◆ mod_ent

◆ number_of_array_variables

int number_of_array_variables = 0
static

◆ number_of_scalar_variables

int number_of_scalar_variables = 0
static