PIPS
interprocedural.c File Reference
#include <stdio.h>
#include <string.h>
#include <setjmp.h>
#include "genC.h"
#include "linear.h"
#include "ri.h"
#include "effects.h"
#include "database.h"
#include "ri-util.h"
#include "prettyprint.h"
#include "effects-util.h"
#include "constants.h"
#include "misc.h"
#include "semantics.h"
#include "text.h"
#include "text-util.h"
#include "sommet.h"
#include "ray_dte.h"
#include "sg.h"
#include "sc.h"
#include "polyedre.h"
#include "transformer.h"
#include "pipsdbm.h"
#include "resources.h"
#include "effects-generic.h"
#include "effects-convex.h"
#include "effects-simple.h"
+ Include dependency graph for interprocedural.c:

Go to the source code of this file.

Macros

#define IS_EG   true
 package regions : Alexis Platonoff, 22 Aout 1990, Be'atrice Creusillet 10/94 More...
 
#define NOT_EG   false
 
#define PHI_FIRST   true
 
#define NOT_PHI_FIRST   false
 
#define BACKWARD   true
 
#define FORWARD   false
 
#define min(a, b)   (((a)<(b))?(a):(b))
 
#define max(a, b)   (((a)>(b))?(a):(b))
 

Functions

void convex_regions_translation_init (entity callee, list real_args, bool backward_p)
 jmp_buf overflow_error; More...
 
void convex_regions_translation_end ()
 
void reset_out_summary_regions_list ()
 
void update_out_summary_regions_list (list l_out)
 
list get_out_summary_regions_list ()
 
static bool stmt_filter (statement s)
 
list out_regions_from_caller_to_callee (entity caller, entity callee)
 
void out_regions_from_call_site_to_callee (call c)
 void out_regions_from_call_site_to_callee(call c) input : a potential call site for current_callee. More...
 
list in_regions_of_external (entity func, list real_args, transformer context)
 list in_regions_of_external(entity func, list real_args, transformer context) input : an external function func, and the list of real arguments used in the calling function. More...
 
list regions_of_external (entity func, list real_args, transformer context, bool proper)
 list regions_of_external(entity func, list real_args, transformer context) input : an external function func, and the list of real arguments used in the calling function. More...
 
list convex_regions_backward_translation (entity func, list real_args, list l_reg, transformer context)
 of effects More...
 
list convex_regions_forward_translation (entity callee, list real_args, list l_reg, transformer context)
 of effects More...
 
static list formal_regions_backward_translation (entity func, list real_args, list func_regions, transformer context)
 static list formal_regions_backward_translation(entity func, list real_args, func_regions, transformer context) input : an external function func, its real arguments at call site (real_args), its summary regions (with formal args), and the calling context. More...
 
static list common_regions_backward_translation (entity func, list func_regions)
 
static list common_region_translation (entity callee, region reg, bool backward)
 static list common_region_translation(entity func, region reg, bool backward) input : func is the called function, real_args are the real arguments, reg is the region to translate (it concerns an array in a common), and backward indicates the direction of the translation. More...
 
list regions_backward_translation (entity func, list real_args, list func_regions, transformer context, bool proper)
 list regions_backward_tranlation(entity func, list real_args, list func_regions, transformer context) input : an external function func, and the list of real arguments used in the calling function. More...
 
list c_convex_effects_on_formal_parameter_backward_translation (list l_sum_eff, expression real_arg, transformer context)
 
static list real_regions_forward_translation (entity func, list real_args, list l_reg, transformer context)
 static list real_regions_forward_translation(entity func, list real_args, l_reg, transformer context) input : the called function func, the real arguments of the call, the list of regions to translate, and the context of the call. More...
 
static list common_regions_forward_translation (entity func, list real_regions)
 static list common_regions_forward_translation (entity func, list real_regions) input : the called function, the list of real arguments at call site, and the list of regions to translate. More...
 
list regions_forward_translation (entity func, list real_args, list l_reg, transformer context)
 list regions_forward_translation(entity func, list real_args, l_reg, transformer context input : the called function func, the real arguments of the call, the list of regions to translate, and the context of the call. More...
 
list c_convex_effects_on_actual_parameter_forward_translation (entity callee, expression real_exp, entity formal_ent, list l_reg, transformer context)
 

Variables

static statement current_stmt = statement_undefined
 
static entity current_callee = entity_undefined
 
static list l_sum_out_reg = list_undefined
 

Macro Definition Documentation

◆ BACKWARD

#define BACKWARD   true

Definition at line 85 of file interprocedural.c.

◆ FORWARD

#define FORWARD   false

Definition at line 86 of file interprocedural.c.

◆ IS_EG

#define IS_EG   true

package regions : Alexis Platonoff, 22 Aout 1990, Be'atrice Creusillet 10/94

interprocedural

This File contains the main functions that compute the interprocedural translation of regions (forward and backward).

Vocabulary : _ A variable refered as a "region" is in fact of the NEWGEN type "effect". The use of the word "region" allows to keep the difference with the effects package. _ The word "func" always refers to the external called subroutine. _ The word "real" always refers to the calling subroutine

Definition at line 79 of file interprocedural.c.

◆ max

#define max (   a,
 
)    (((a)>(b))?(a):(b))

Definition at line 89 of file interprocedural.c.

◆ min

#define min (   a,
 
)    (((a)<(b))?(a):(b))

Definition at line 88 of file interprocedural.c.

◆ NOT_EG

#define NOT_EG   false

Definition at line 80 of file interprocedural.c.

◆ NOT_PHI_FIRST

#define NOT_PHI_FIRST   false

Definition at line 83 of file interprocedural.c.

◆ PHI_FIRST

#define PHI_FIRST   true

Definition at line 82 of file interprocedural.c.

Function Documentation

◆ c_convex_effects_on_actual_parameter_forward_translation()

list c_convex_effects_on_actual_parameter_forward_translation ( entity  callee,
expression  real_exp,
entity  formal_ent,
list  l_reg,
transformer  context 
)

it's an intrinsic : FI, cannot it be a constant?

first we compute a SIMPLE effect on the argument of the address_of operator. This is to distinguish between the general case and the case where the operand of the & operator is an array element. Simple effect indices are easier to retrieve.

there should be a FOREACH here to scan the whole list

there are indices but we don't know if they represent array dimensions, struct/union/enum fields, or pointer dimensions.

we build the constraint PHI_nb_phi_real >= last index of eff_real

well, not strictly necessary : forward propagation is only for OUT regions

now we compute a convex effect on the argument of the address_of operator and modify it's last dimension according to the fact that there is an addressing operator

here should be a FOREACH to handle all elements

array element operand : we replace the constraint on the last phi variable with

First we have to test if the eff_real access path leads to the eff_orig access path

to do that, if the entities are the same (well in fact we should also take care of aliasing), we add the constraints of eff_real to those of eff_orig, and the system must be feasible. We should also take care of linearization here.

I guess we could reuse convex_cell_reference_with_address_of_cell_reference_translation

At least part of the original effect corresponds to the actual argument : we need to translate it

first we translate the predicate in the callee's name space

Then we remove the phi variables common to the two regions except the last one if we are not in the general case

This is only valid when there is no linearization ; in the general case a translation system should be built

if not in the general case, we add the constraint phi_nb_phi_real == psi_nb_phi_real - exp_nb_phi_real

Finally, we must rename remaining phi variables from 2 add a PHI1==0 constraint in the general case, or, in the contrary, rename remaining phi variables from 1. We must also change the resulting region entity for the formal entity in all cases.

add PHI1 == 0

else of the if (sc_empty_p)

if(effect_entity(eff_orig) == effect_entity(eff_real) ...)

FOREACH

first we compute an effect on the real_arg

here should be a foreach to scan all the elements

First we have to test if the eff_real access path leads to the eff_orig access path

to do that, if the entities are the same (well in fact we should also take care of aliasing), we add the constraints of eff_real to those of eff_orig, and the system must be feasible.

At least part of the original effect corresponds to the actual argument : we need to translate it

first we perform the path translation

then we translate the predicate in the callee's name space

else of the if (sc_empty_p)

if(effect_entity(eff_orig) == effect_entity(eff_real) ...)

FOREACH

switch

Parameters
calleeallee
real_expeal_exp
formal_entormal_ent
l_reg_reg
contextontext

Definition at line 1163 of file interprocedural.c.

1165 {
1166  syntax real_s = expression_syntax(real_exp);
1167  list l_formal = NIL;
1168 
1169  pips_debug_effects(6,"initial regions :\n", l_reg);
1170 
1171 
1172  switch (syntax_tag(real_s))
1173  {
1174  case is_syntax_call:
1175  {
1176  call real_call = syntax_call(real_s);
1177  entity real_op = call_function(real_call);
1178  list args = call_arguments(real_call);
1179  type uet = ultimate_type(entity_type(real_op));
1180  value real_op_v = entity_initial(real_op);
1181 
1182  pips_debug(5, "call case, function %s \n", module_local_name(real_op));
1183  if(type_functional_p(uet))
1184  {
1185  if (value_code_p(real_op_v))
1186  {
1187  pips_debug(5, "external function\n");
1188  pips_user_warning("Nested function calls are ignored. Consider splitting the code before running PIPS\n");
1189  l_formal = NIL;
1190  break;
1191  }
1192  else /* it's an intrinsic : FI, cannot it be a constant? */
1193  {
1194  pips_debug(5, "intrinsic function\n");
1195 
1196  if (ENTITY_ASSIGN_P(real_op))
1197  {
1198  pips_debug(5, "assignment case\n");
1200  (callee, EXPRESSION(CAR(CDR(args))), formal_ent, l_reg, context);
1201  break;
1202  }
1203  else if(ENTITY_ADDRESS_OF_P(real_op))
1204  {
1205  expression arg1 = EXPRESSION(CAR(args));
1206  list l_real_arg = NIL;
1207  effect eff_real;
1208  int nb_phi_real;
1209  Psysteme sc_nb_phi_real;
1210  expression exp_nb_phi_real = expression_undefined;
1211  bool general_case = true;
1212  bool in_out = in_out_methods_p();
1213 
1214  pips_debug(5, "address of case\n");
1215 
1216  /* first we compute a SIMPLE effect on the argument of the address_of operator.
1217  * This is to distinguish between the general case and the case where
1218  * the operand of the & operator is an array element.
1219  * Simple effect indices are easier to retrieve.
1220  */
1222  list l_eff_real = NIL;
1224  (arg1, &l_eff_real, true);
1225 
1226  eff_real = EFFECT(CAR(l_eff_real)); /* there should be a FOREACH here to scan the whole list */
1227  gen_free_list(l_eff_real);
1228 
1229  nb_phi_real = (int) gen_length(reference_indices(effect_any_reference(eff_real)));
1230  gen_full_free_list(l_real_arg);
1231 
1232  /* there are indices but we don't know if they represent array dimensions,
1233  * struct/union/enum fields, or pointer dimensions.
1234  */
1235  if(nb_phi_real > 0)
1236  {
1237  reference eff_real_ref = effect_any_reference(eff_real);
1238  list l_inds_real = NIL, l_tmp = NIL;
1239  reference ref_tmp;
1240  type t = type_undefined;
1241 
1242  for(l_inds_real = reference_indices(eff_real_ref); !ENDP(CDR(l_inds_real)); POP(l_inds_real))
1243  {
1244  l_tmp = gen_nconc(l_tmp, CONS(EXPRESSION, copy_expression(EXPRESSION(CAR(l_inds_real))), NIL));
1245  }
1246 
1247  ref_tmp = make_reference(reference_variable(eff_real_ref), l_tmp);
1248  t = simple_effect_reference_type(ref_tmp);
1249  free_reference(ref_tmp);
1250 
1251  if (type_undefined_p(t))
1252  pips_internal_error("undefined type not expected ");
1253 
1255  {
1256  pips_debug(5,"array element or sub-array case\n");
1257  general_case = false;
1258  /* we build the constraint PHI_nb_phi_real >= last index of eff_real */
1259  exp_nb_phi_real = copy_expression(EXPRESSION(CAR(l_inds_real))); // copy necessary because eff_real is freed afterwards
1260  sc_nb_phi_real = sc_new();
1261  (void) sc_add_phi_equation(&sc_nb_phi_real,
1262  copy_expression(exp_nb_phi_real),
1263  nb_phi_real, NOT_EG, NOT_PHI_FIRST);
1264  }
1265  else
1266  pips_debug(5, "general case\n");
1267  }
1268 
1269  free_effect(eff_real);
1270  eff_real = effect_undefined;
1271  /* well, not strictly necessary : forward propagation is only for OUT regions */
1272  if (in_out)
1274  else
1277 
1278  /* now we compute a *convex* effect on the argument of the
1279  * address_of operator and modify it's last dimension
1280  * according to the fact that there is an addressing operator
1281  */
1282 
1283  l_eff_real = NIL;
1285  (arg1, &l_eff_real, true);
1286  eff_real = EFFECT(CAR(l_eff_real)); /*There should be a FOREACH to handle all elements */
1287  gen_free_list(l_eff_real);
1288 
1289  gen_full_free_list(l_real_arg);
1290 
1291  if (!general_case)
1292  {
1293  /* array element operand : we replace the constraint on the last
1294  * phi variable with */
1295  entity phi_nb_phi_real = make_phi_entity(nb_phi_real);
1296  region_exact_projection_along_variable(eff_real, phi_nb_phi_real);
1297  region_sc_append_and_normalize(eff_real, sc_nb_phi_real, 1);
1298  (void) sc_free(sc_nb_phi_real);
1299  }
1300 
1301  FOREACH(EFFECT, eff_orig, l_reg)
1302  {
1303  int nb_phi_orig = (int) gen_length(reference_indices(effect_any_reference(eff_orig)));
1304 
1305  /* First we have to test if the eff_real access path leads to the eff_orig access path */
1306 
1307  /* to do that, if the entities are the same (well in fact we should also
1308  * take care of aliasing), we add the constraints of eff_real to those of eff_orig,
1309  * and the system must be feasible.
1310  * We should also take care of linearization here.
1311  */
1312  bool exact_p;
1313  if(path_preceding_p(eff_real, eff_orig, transformer_undefined, false, &exact_p))
1314  {
1315  // functions that can be pointed by effect_dup_func:
1316  // simple_effect_dup
1317  // region_dup
1318  // copy_effect
1319  effect eff_formal = (*effect_dup_func)(eff_orig);
1320  region_sc_append_and_normalize(eff_formal, region_system(eff_real), 1);
1321 
1322  if (sc_empty_p(region_system(eff_formal)))
1323  {
1324  pips_debug(5, "the original effect does not correspond to the actual argument \n");
1325  free_effect(eff_formal);
1326  }
1327  else
1328  {
1329  /* I guess we could reuse convex_cell_reference_with_address_of_cell_reference_translation */
1330  /* At least part of the original effect corresponds to the actual argument :
1331  * we need to translate it
1332  */
1333  Psysteme sc_formal;
1334  reference ref_formal = effect_any_reference(eff_formal);
1335  reference new_ref;
1336  list new_inds = NIL;
1337  int i, min_phi, min_i;
1338 
1339  pips_debug_effect(5, "matching access paths, considered effect is : \n", eff_formal);
1340 
1341  /* first we translate the predicate in the callee's name space */
1343  pips_debug_effect(5, "eff_formal after context translation: \n", eff_formal);
1344 
1345  /* Then we remove the phi variables common to the two regions
1346  * except the last one if we are not in the general case */
1347  /* This is only valid when there is no linearization ; in the general case
1348  * a translation system should be built
1349  */
1350  sc_formal = region_system(eff_formal);
1351  for(i = 1; i <= nb_phi_real; i++)
1352  {
1353  entity phi_i = make_phi_entity(i);
1354  entity psi_i = make_psi_entity(i);
1355 
1356  sc_formal = sc_variable_rename(sc_formal, (Variable) phi_i, (Variable) psi_i);
1357  }
1358  /* if not in the general case, we add the constraint
1359  * phi_nb_phi_real == psi_nb_phi_real - exp_nb_phi_real
1360  */
1361  if (!general_case)
1362  {
1363  entity phi = make_phi_entity(nb_phi_real);
1364  Pvecteur v_phi = vect_new((Variable) phi, VALUE_ONE);
1365  entity psi = make_psi_entity(nb_phi_real);
1366  Pvecteur v_psi = vect_new((Variable) psi, VALUE_ONE);
1367  Pvecteur v = vect_substract(v_phi, v_psi);
1368  normalized nexp = NORMALIZE_EXPRESSION(exp_nb_phi_real);
1369  if (normalized_linear_p(nexp))
1370  {
1371  pips_debug(6, "normalized last index : "
1372  "adding phi_nb_phi_real == psi_nb_phi_real - exp_nb_phi_real \n");
1373  Pvecteur v1 = vect_copy(normalized_linear(nexp));
1374  Pvecteur v2;
1375  v2 = vect_add(v, v1);
1376  sc_formal = sc_constraint_add(sc_formal, contrainte_make(v2), true);
1377  vect_rm(v1);
1378  }
1379  vect_rm(v_psi);
1380  vect_rm(v);
1381  }
1382  region_system(eff_formal) = sc_formal;
1383  pips_debug_effect(5, "eff_formal before removing psi variables: \n", eff_formal);
1384  region_remove_psi_variables(eff_formal);
1385  pips_debug_effect(5, "eff_formal after renaming common dimensions: \n", eff_formal);
1386 
1387  /* Finally, we must rename remaining phi variables from 2
1388  * add a PHI1==0 constraint in the general case,
1389  * or, in the contrary, rename remaining phi variables from 1.
1390  * We must also change the resulting region
1391  * entity for the formal entity in all cases.
1392  */
1393  min_phi = general_case? 2:1;
1394  min_i = general_case ? nb_phi_real+1 : nb_phi_real;
1395  sc_formal = region_system(eff_formal);
1396 
1397  pips_debug(8, "nb_phi_real: %d, min_i: %d, min_phi: %d\n", nb_phi_real, min_i, min_phi);
1398  for(i = min_i; i <= nb_phi_orig; i++)
1399  {
1400  pips_debug(8, "renaming %d-th index into %d-th\n", i, i-min_i+min_phi);
1401  entity phi_i = make_phi_entity(i);
1402  entity psi_formal = make_psi_entity(i-min_i+min_phi);
1403 
1404  // the call to gen_nth is rather costly
1405  expression original_index_exp =
1406  EXPRESSION( gen_nth(i-1, cell_indices(effect_cell(eff_orig))));
1407 
1408  pips_assert("index expression of an effect must be a reference",
1409  expression_reference_p(original_index_exp));
1410  if (entity_field_p(reference_variable(expression_reference(original_index_exp))))
1411  {
1412  pips_debug(8, "field expression (%s)\n",
1413  entity_name(reference_variable(expression_reference(original_index_exp))));
1414  new_inds = gen_nconc(new_inds,
1415  CONS(EXPRESSION,
1416  copy_expression(original_index_exp),
1417  NIL));
1418  }
1419  else
1420  {
1421  pips_debug(8, "phi expression \n");
1422  sc_formal = sc_variable_rename(sc_formal, (Variable) phi_i, (Variable) psi_formal);
1423 
1424  new_inds = gen_nconc(new_inds,
1425  CONS(EXPRESSION,
1426  make_phi_expression(i-nb_phi_real+1),
1427  NIL));
1428  }
1429 
1430  }
1431  for(i=min_phi; i<= nb_phi_orig-min_i+min_phi; i++)
1432  {
1433  entity phi_i = make_phi_entity(i);
1434  entity psi_i = make_psi_entity(i);
1435  sc_formal = sc_variable_rename(sc_formal, (Variable) psi_i, (Variable) phi_i);
1436  }
1437  region_system(eff_formal) = sc_formal;
1438  pips_debug_effect(5, "eff_formal after shifting dimensions: \n", eff_formal);
1439 
1440  if(general_case)
1441  {
1442  /* add PHI1 == 0 */
1443  sc_formal = region_system(eff_formal);
1444  (void) sc_add_phi_equation(&sc_formal, int_to_expression(0), 1, IS_EG, PHI_FIRST);
1445  region_system(eff_formal) = sc_formal;
1446  new_inds = CONS(EXPRESSION, make_phi_expression(1), new_inds);
1447  }
1448 
1449  free_reference(ref_formal);
1450  new_ref = make_reference(formal_ent, new_inds);
1451  cell_reference(effect_cell(eff_formal)) = new_ref;
1452  pips_debug_effect(5, "final eff_formal : \n", eff_formal);
1453  l_formal = RegionsMustUnion(l_formal, CONS(EFFECT, eff_formal, NIL),
1455  pips_debug_effects(6,"l_formal after adding new effect : \n", l_formal);
1456 
1457  } /* else of the if (sc_empty_p) */
1458 
1459  } /* if(effect_entity(eff_orig) == effect_entity(eff_real) ...)*/
1460 
1461  } /* FOREACH */
1462 
1463  if (!expression_undefined_p(exp_nb_phi_real))
1464  free_expression(exp_nb_phi_real);
1465  break;
1466  }
1467  else
1468  {
1469  pips_debug(5, "Other intrinsic case : entering general case \n");
1470  }
1471  }
1472  }
1473  else if(type_variable_p(uet))
1474  {
1475  pips_user_warning("Effects of call thru functional pointers are ignored\n");
1476  l_formal = NIL;
1477  break;
1478  }
1479  }
1480  // entering general case which includes general calls
1481  _FALLTHROUGH_;
1482  case is_syntax_reference:
1483  case is_syntax_subscript:
1484  {
1485  effect eff_real = effect_undefined;
1486 
1487  pips_debug(5, "general case\n");
1488 
1489  /* first we compute an effect on the real_arg */
1490  if (syntax_reference_p(real_s))
1492  else
1493  {
1494  list l_eff_real = NIL;
1496  (real_exp, &l_eff_real, true);
1497  gen_full_free_list(l_real_arg);
1498  if (!ENDP(l_eff_real))
1499  eff_real = EFFECT(CAR(l_eff_real)); /*there should be a foreach to scan all the elements */
1500  gen_free_list(l_eff_real);
1501  }
1502 
1503  if (!effect_undefined_p(eff_real))
1504  {
1505  FOREACH(EFFECT, eff_orig, l_reg)
1506  {
1507  int nb_phi_orig = (int) gen_length(reference_indices(effect_any_reference(eff_orig)));
1508  int nb_phi_real = (int) gen_length(reference_indices(effect_any_reference(eff_real)));
1509  /* First we have to test if the eff_real access path leads to the eff_orig access path */
1510 
1511  /* to do that, if the entities are the same (well in fact we should also
1512  take care of aliasing), we add the constraints of eff_real to those of eff_orig,
1513  and the system must be feasible.
1514  */
1515 
1516  bool exact_p;
1517  if(path_preceding_p(eff_real, eff_orig, transformer_undefined, true, &exact_p)
1518  && nb_phi_orig >= nb_phi_real)
1519  {
1520  effect eff_orig_dup = (*effect_dup_func)(eff_orig);
1521  region_sc_append_and_normalize(eff_orig_dup, region_system(eff_real), 1);
1522 
1523  if (sc_empty_p(region_system(eff_orig_dup)))
1524  {
1525  pips_debug(5, "the original effect does not correspond to the actual argument \n");
1526  free_effect(eff_orig_dup);
1527  }
1528  else
1529  {
1530  /* At least part of the original effect corresponds to the actual argument :
1531  we need to translate it
1532  */
1533  reference ref_formal = make_reference(formal_ent, NIL);
1534  effect eff_formal = make_reference_region(ref_formal, copy_action(effect_action(eff_orig)));
1535 
1536  pips_debug_effect(5, "matching access paths, considered effect is : \n", eff_orig_dup);
1537 
1538  /* first we perform the path translation */
1539  reference n_eff_ref;
1540  descriptor n_eff_d;
1541  effect n_eff;
1542  bool exact_translation_p;
1544  effect_descriptor(eff_orig_dup),
1545  ref_formal,
1546  effect_descriptor(eff_formal),
1547  nb_phi_real,
1548  &n_eff_ref, &n_eff_d,
1549  &exact_translation_p);
1550  n_eff = make_effect(make_cell_reference(n_eff_ref), copy_action(effect_action(eff_orig)),
1551  exact_translation_p? copy_approximation(effect_approximation(eff_orig)) : make_approximation_may(),
1552  n_eff_d);
1553  pips_debug_effect(5, "final eff_formal : \n", n_eff);
1554 
1555  /* then we translate the predicate in the callee's name space */
1557  pips_debug_effect(5, "eff_formal after context translation: \n", n_eff);
1558 
1559  l_formal = RegionsMustUnion(l_formal, CONS(EFFECT, n_eff, NIL),effects_same_action_p);
1560  pips_debug_effects(6, "l_formal after adding new effect : \n", l_formal);
1561  } /* else of the if (sc_empty_p) */
1562 
1563  } /* if(effect_entity(eff_orig) == effect_entity(eff_real) ...)*/
1564 
1565 
1566 
1567  /* */
1568 
1569  } /* FOREACH */
1570  }
1571 
1572  break;
1573  }
1574  case is_syntax_application:
1575  {
1576  pips_internal_error("Application not supported yet");
1577  break;
1578  }
1579 
1580  case is_syntax_cast:
1581  {
1582  pips_debug(6, "cast expression\n");
1583  type formal_ent_type = entity_basic_concrete_type(formal_ent);
1584  expression cast_exp = cast_expression(syntax_cast(real_s));
1585  type cast_exp_type = expression_to_type(cast_exp);
1587  {
1588  l_formal =
1590  (callee, cast_exp,
1591  formal_ent, l_reg, context);
1592  }
1593  else
1594  {
1595  expression formal_exp = entity_to_expression(formal_ent);
1596  l_formal = c_actual_argument_to_may_summary_effects(formal_exp, 'w');
1597  free_expression(formal_exp);
1598  }
1599  free_type(cast_exp_type);
1600  break;
1601  }
1602  case is_syntax_range:
1603  {
1604  pips_user_error("Illegal effective parameter: range\n");
1605  break;
1606  }
1607 
1609  {
1610  pips_debug(6, "sizeofexpression : -> NIL");
1611  l_formal = NIL;
1612  break;
1613  }
1614  case is_syntax_va_arg:
1615  {
1616  pips_internal_error("va_arg not supported yet");
1617  break;
1618  }
1619  default:
1620  pips_internal_error("Illegal kind of syntax");
1621 
1622  } /* switch */
1623 
1624 
1625  pips_debug_effects(6,"resulting regions :\n", l_formal);
1626  return(l_formal);
1627 
1628 }
cell make_cell_reference(reference _field_)
Definition: effects.c:293
action copy_action(action p)
ACTION.
Definition: effects.c:77
void free_effect(effect p)
Definition: effects.c:451
approximation copy_approximation(approximation p)
APPROXIMATION.
Definition: effects.c:132
approximation make_approximation_may(void)
Definition: effects.c:179
effect make_effect(cell a1, action a2, approximation a3, descriptor a4)
Definition: effects.c:484
void free_reference(reference p)
Definition: ri.c:2050
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
void free_expression(expression p)
Definition: ri.c:853
void free_type(type p)
Definition: ri.c:2658
static entity callee
Definition: alias_pairs.c:62
void const char const char const int
#define VALUE_ONE
Pcontrainte contrainte_make(Pvecteur pv)
Pcontrainte contrainte_make(Pvecteur pv): allocation et initialisation d'une contrainte avec un vecte...
Definition: alloc.c:73
#define region_system(reg)
list RegionsMustUnion(list l1, list l2, bool(*union_combinable_p)(effect, effect))
list RegionsMustUnion(list l1, list l2, union_combinable_p) input : two lists of regions output : a l...
#define NOT_EG
#define NOT_PHI_FIRST
#define PHI_FIRST
list c_convex_effects_on_actual_parameter_forward_translation(entity callee, expression real_exp, entity formal_ent, list l_reg, transformer context)
#define IS_EG
package regions : Alexis Platonoff, 22 Aout 1990, Be'atrice Creusillet 10/94
void convex_region_descriptor_translation(effect)
entity make_phi_entity(int)
effect make_reference_region(reference, action)
void region_sc_append_and_normalize(effect, Psysteme, int)
void convex_cell_reference_with_value_of_cell_reference_translation(reference, descriptor, reference, descriptor, int, reference *, descriptor *, bool *)
bool sc_add_phi_equation(Psysteme *, expression, int, bool, bool)
expression make_phi_expression(int)
void region_exact_projection_along_variable(effect, entity)
void set_methods_for_convex_in_out_effects(void)
Definition: methods.c:469
void init_convex_inout_prettyprint(const char *)
void region_remove_psi_variables(effect)
bool in_out_methods_p(void)
Definition: methods.c:476
void set_methods_for_convex_rw_effects(void)
Definition: methods.c:358
entity make_psi_entity(int)
#define pips_debug_effects(level, message, l_eff)
#define pips_debug_effect(level, message, eff)
for debug
list generic_proper_effects_of_complex_address_expression(expression, list *, int)
type simple_effect_reference_type(reference)
list c_actual_argument_to_may_summary_effects(expression, tag)
bool effects_same_action_p(effect, effect)
bool path_preceding_p(effect, effect, transformer, bool, bool *)
Definition: eval.c:132
void set_methods_for_proper_simple_effects(void)
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
list cell_indices(cell)
Definition: effects.c:64
bool basic_concrete_types_compatible_for_effects_interprocedural_translation_p(type, type)
tests if the actual argument type and the formal argument type are compatible with the current state ...
Definition: type.c:699
action make_action_write_memory(void)
To ease the extension of action with action_kind.
Definition: effects.c:1011
#define cell_reference(x)
Definition: effects.h:469
#define effect_undefined_p(x)
Definition: effects.h:615
#define effect_action(x)
Definition: effects.h:642
#define effect_undefined
Definition: effects.h:614
#define effect_descriptor(x)
Definition: effects.h:646
#define effect_approximation(x)
Definition: effects.h:644
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
#define effect_cell(x)
Definition: effects.h:640
void gen_full_free_list(list l)
Definition: genClib.c:1023
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
size_t gen_length(const list l)
Definition: list.c:150
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
#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
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
gen_chunk gen_nth(int n, const list l)
to be used as ENTITY(gen_nth(3, l))...
Definition: list.c:710
#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_user_warning
Definition: misc-local.h:146
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define pips_internal_error
Definition: misc-local.h:149
#define _FALLTHROUGH_
Definition: misc-local.h:238
#define pips_user_error
Definition: misc-local.h:147
#define ENTITY_ASSIGN_P(e)
#define NORMALIZE_EXPRESSION(e)
#define ENTITY_ADDRESS_OF_P(e)
bool entity_field_p(entity e)
e is the field of a structure
Definition: entity.c:857
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
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
bool expression_reference_p(expression e)
Test if an expression is a reference.
Definition: expression.c:528
reference expression_reference(expression e)
Short cut, meaningful only if expression_reference_p(e) holds.
Definition: expression.c:1832
type ultimate_type(type)
Definition: type.c:3466
type expression_to_type(expression)
For an array declared as int a[10][20], the type returned for a[i] is int [20].
Definition: type.c:2486
type entity_basic_concrete_type(entity)
retrieves or computes and then returns the basic concrete type of an entity
Definition: type.c:3677
#define type_functional_p(x)
Definition: ri.h:2950
#define value_code_p(x)
Definition: ri.h:3065
#define syntax_reference_p(x)
Definition: ri.h:2728
#define transformer_undefined
Definition: ri.h:2847
#define syntax_reference(x)
Definition: ri.h:2730
#define syntax_tag(x)
Definition: ri.h:2727
#define normalized_linear_p(x)
Definition: ri.h:1779
#define call_function(x)
Definition: ri.h:709
#define reference_variable(x)
Definition: ri.h:2326
#define syntax_cast(x)
Definition: ri.h:2739
#define type_variable(x)
Definition: ri.h:2949
@ is_syntax_range
Definition: ri.h:2692
@ is_syntax_application
Definition: ri.h:2697
@ is_syntax_cast
Definition: ri.h:2694
@ is_syntax_call
Definition: ri.h:2693
@ is_syntax_va_arg
Definition: ri.h:2698
@ is_syntax_reference
Definition: ri.h:2691
@ is_syntax_sizeofexpression
Definition: ri.h:2695
@ is_syntax_subscript
Definition: ri.h:2696
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define cast_expression(x)
Definition: ri.h:747
#define type_undefined_p(x)
Definition: ri.h:2884
#define expression_undefined
Definition: ri.h:1223
#define entity_name(x)
Definition: ri.h:2790
#define reference_indices(x)
Definition: ri.h:2328
#define syntax_call(x)
Definition: ri.h:2736
#define expression_undefined_p(x)
Definition: ri.h:1224
#define variable_dimensions(x)
Definition: ri.h:3122
#define type_undefined
Definition: ri.h:2883
#define call_arguments(x)
Definition: ri.h:711
#define entity_type(x)
Definition: ri.h:2792
#define normalized_linear(x)
Definition: ri.h:1781
#define expression_syntax(x)
Definition: ri.h:1247
#define type_variable_p(x)
Definition: ri.h:2947
#define entity_initial(x)
Definition: ri.h:2796
Psysteme sc_variable_rename(Psysteme s, Variable v_old, Variable v_new)
Psysteme sc_variable_rename(Psysteme s, Variable v_old, Variable v_new): reecriture du systeme s remp...
Definition: sc.c:157
Psysteme sc_new(void)
Psysteme sc_new(): alloue un systeme vide, initialise tous les champs avec des valeurs nulles,...
Definition: sc_alloc.c:55
bool sc_empty_p(Psysteme sc)
bool sc_empty_p(Psysteme sc): check if the set associated to sc is the constant sc_empty or not.
Definition: sc_alloc.c:350
Psysteme sc_constraint_add(Psysteme sc, Pcontrainte c, bool equality)
Definition: sc_insert_eq.c:115
Psysteme sc_free(Psysteme in_ps)
Psysteme sc_free( in_ps ) AL 30/05/94 Free of in_ps.
Definition: sc_list.c:112
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
Definition: delay.c:253
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
Pbase vect_copy(Pvecteur b)
direct duplication.
Definition: alloc.c:240
Pvecteur vect_new(Variable var, Value coeff)
Pvecteur vect_new(Variable var,Value coeff): allocation d'un vecteur colineaire au vecteur de base va...
Definition: alloc.c:110
void vect_rm(Pvecteur v)
void vect_rm(Pvecteur v): desallocation des couples de v;
Definition: alloc.c:78
Pvecteur vect_add(Pvecteur v1, Pvecteur v2)
package vecteur - operations binaires
Definition: binaires.c:53
Pvecteur vect_substract(Pvecteur v1, Pvecteur v2)
Pvecteur vect_substract(Pvecteur v1, Pvecteur v2): allocation d'un vecteur v dont la valeur est la di...
Definition: binaires.c:75

References _FALLTHROUGH_, basic_concrete_types_compatible_for_effects_interprocedural_translation_p(), c_actual_argument_to_may_summary_effects(), c_convex_effects_on_actual_parameter_forward_translation(), call_arguments, call_function, callee, CAR, cast_expression, CDR, cell_indices(), cell_reference, CONS, contrainte_make(), convex_cell_reference_with_value_of_cell_reference_translation(), convex_region_descriptor_translation(), copy_action(), copy_approximation(), copy_expression(), EFFECT, effect_action, effect_any_reference, effect_approximation, effect_cell, effect_descriptor, effect_undefined, effect_undefined_p, effects_same_action_p(), ENDP, ENTITY_ADDRESS_OF_P, ENTITY_ASSIGN_P, entity_basic_concrete_type(), entity_field_p(), entity_initial, entity_name, entity_to_expression(), entity_type, EXPRESSION, expression_reference(), expression_reference_p(), expression_syntax, expression_to_type(), expression_undefined, expression_undefined_p, FOREACH, free_effect(), free_expression(), free_reference(), free_type(), gen_free_list(), gen_full_free_list(), gen_length(), gen_nconc(), gen_nth(), generic_proper_effects_of_complex_address_expression(), get_current_module_entity(), in_out_methods_p(), init_convex_inout_prettyprint(), int, int_to_expression(), IS_EG, is_syntax_application, is_syntax_call, is_syntax_cast, is_syntax_range, is_syntax_reference, is_syntax_sizeofexpression, is_syntax_subscript, is_syntax_va_arg, make_action_write_memory(), make_approximation_may(), make_cell_reference(), make_effect(), make_phi_entity(), make_phi_expression(), make_psi_entity(), make_reference(), make_reference_region(), module_local_name(), NIL, NORMALIZE_EXPRESSION, normalized_linear, normalized_linear_p, NOT_EG, NOT_PHI_FIRST, path_preceding_p(), PHI_FIRST, pips_assert, pips_debug, pips_debug_effect, pips_debug_effects, pips_internal_error, pips_user_error, pips_user_warning, POP, reference_indices, reference_variable, region_exact_projection_along_variable(), region_remove_psi_variables(), region_sc_append_and_normalize(), region_system, RegionsMustUnion(), sc_add_phi_equation(), sc_constraint_add(), sc_empty_p(), sc_free(), sc_new(), sc_variable_rename(), set_methods_for_convex_in_out_effects(), set_methods_for_convex_rw_effects(), set_methods_for_proper_simple_effects(), simple_effect_reference_type(), syntax_call, syntax_cast, syntax_reference, syntax_reference_p, syntax_tag, transformer_undefined, type_functional_p, type_undefined, type_undefined_p, type_variable, type_variable_p, ultimate_type(), value_code_p, VALUE_ONE, variable_dimensions, vect_add(), vect_copy(), vect_new(), vect_rm(), and vect_substract().

Referenced by c_convex_effects_on_actual_parameter_forward_translation(), set_methods_for_convex_effects(), and set_methods_for_convex_rw_pointer_effects().

+ Here is the caller graph for this function:

◆ c_convex_effects_on_formal_parameter_backward_translation()

list c_convex_effects_on_formal_parameter_backward_translation ( list  l_sum_eff,
expression  real_arg,
transformer  context 
)
Parameters
l_sum_effis a list of effects on a C function formal parameter. These effects must be visible from the caller, which means that their reference has at leat one index.
real_argis an expression. It's the real argument corresponding to the formal parameter which memory effects are represented by l_sum_eff.
contextis the transformer translating the callee's neame space into the caller's name space.
Returns
a list of effects which are the translation of l_sum_eff in the caller's name space.

the result

if it's a pointer or a partially indexed array We should do more testing here to check if types are compatible...

the test here may not be right. I guess I should use basic_concrete_type here BC

Then we compute the region corresponding to the real argument

this could easily be made generic BC.

FI: I add the restriction on store regions, but they should have been eliminated before translation is attempted

we translate the initial region descriptor into the caller's name space

and then perform the translation

shouldn't it be a union ? BC

if (pointer_type_p(real_arg_t))

else

case is_syntax_reference

first we compute an effect on the argument of the address_of operator (to treat cases like &(n->m))

we translate the initial region descriptor into the caller's name space

if(!ENDP(eff_ind))

else du if (effect_undefined_p(eff_real) || ...)

FOREACH(EFFECT, eff, l_sum_eff)

FOREACH (EFFECT, eff_real, l_eff_real)

if it's a pointer or a partially indexed array We should do more testing here to check if types are compatible...

first compute the region corresponding to the real argument

this could easily be made generic BC.

FI: I add the restriction on store regions, but they should have been eliminated before translation is attempted

we translate the initial region descriptor into the caller's name space

and then perform the translation

shouldn't it be a union ? BC

if (pointer_type_p(real_arg_t))

else

first we compute an effect on the real_arg

first we translate the formal region predicate

Then we append the formal region to the real region

Well this is valid only in the general case : we should verify that types are compatible.

else du if (effect_undefined_p(eff_real))

shouldn't it be a union ? BC

FOREACH(EFFECT, eff, l_sum_eff)

BC : do not generate effects on HEAP

n_eff = heap_effect(get_current_module_entity(), copy_action(effect_action(eff)));

case is_syntax_call

we should test here the compatibility of the casted expression type with the formal entity type. It is not available here, however, I think it's equivalent to test the compatibility with the real arg expression type since the current function is called after testing the compatilibty between the real expression type and the formal parameter type.

let us at least generate effects on all memory locations reachable from the cast expression

switch

free_type(real_arg_t);

Parameters
l_sum_eff_sum_eff
real_argeal_arg
contextontext

Definition at line 523 of file interprocedural.c.

526 {
527  list l_eff = NIL; /* the result */
528  syntax real_s = expression_syntax(real_arg);
529  type real_arg_t = expression_to_type(real_arg);
530 
531 
532  ifdebug(5)
533  {
534  pips_debug(8, "begin for real arg %s, of type %s and effects :\n",
535  expression_to_string(real_arg),
536  type_to_string(real_arg_t));
537  (*effects_prettyprint_func)(l_sum_eff);
538  }
539 
540  switch (syntax_tag(real_s))
541  {
542  case is_syntax_reference:
543  {
544  reference real_ref = syntax_reference(real_s);
545  entity real_ent = reference_variable(real_ref);
546  list real_ind = reference_indices(real_ref);
547 
548  /* if it's a pointer or a partially indexed array
549  * We should do more testing here to check if types
550  * are compatible...
551  */
552 
553  /* the test here may not be right. I guess I should use basic_concrete_type here BC */
554  if (pointer_type_p(real_arg_t) ||
555  gen_length(real_ind) < type_depth(entity_type(real_ent)))
556  {
557  FOREACH(EFFECT, eff, l_sum_eff) {
558  reference new_ref = copy_reference(real_ref);
559  effect real_eff = effect_undefined;
560 
561  pips_debug(8, "pointer type real arg reference\n");
562 
563  /* Then we compute the region corresponding to the
564  * real argument
565  */
566  pips_debug(8, "effect on the pointed area : \n");
567  // functions that can be pointed by reference_to_effect_func:
568  // reference_to_simple_effect
569  // reference_to_convex_region
570  // reference_to_reference_effect
571  real_eff = (*reference_to_effect_func)
572  (new_ref, copy_action(effect_action(eff)), false);
573 
574  /* this could easily be made generic BC. */
575  /* FI: I add the restriction on store regions, but
576  * they should have been eliminated before translation
577  * is attempted */
578  if(!anywhere_effect_p(real_eff) && store_effect_p(real_eff))
579  {
580  reference n_eff_ref;
581  descriptor n_eff_d;
582  effect n_eff;
583  bool exact_translation_p;
584  // functions that can be pointed by effect_dup_func:
585  // simple_effect_dup
586  // region_dup
587  // copy_effect
588  effect init_eff = (*effect_dup_func)(eff);
589 
590  /* we translate the initial region descriptor
591  * into the caller's name space
592  */
594  /* and then perform the translation */
596  effect_descriptor(init_eff),
597  effect_any_reference(real_eff),
598  effect_descriptor(real_eff),
599  0,
600  &n_eff_ref, &n_eff_d,
601  &exact_translation_p);
602  n_eff = make_effect(make_cell_reference(n_eff_ref), copy_action(effect_action(eff)),
603  exact_translation_p? copy_approximation(effect_approximation(eff)) : make_approximation_may(),
604  n_eff_d);
605  /* shouldn't it be a union ? BC */
606  l_eff = gen_nconc(l_eff, CONS(EFFECT, n_eff, NIL));
607  free_effect(init_eff);
608  free_effect(real_eff);
609  }
610  }
611  } /* if (pointer_type_p(real_arg_t)) */
612  else
613  {
614  pips_debug(8, "real arg reference is not a pointer and is not a partially indexed array -> NIL \n");
615 
616  } /* else */
617  break;
618  } /* case is_syntax_reference */
619  case is_syntax_subscript:
620  {
621  pips_debug(8, "Subscript not supported yet -> anywhere");
622  bool read_p = false, write_p = false;
623  FOREACH(EFFECT, eff, l_sum_eff)
624  {
625  if(effect_write_p(eff)) write_p = true;
626  else read_p = true;
627  }
628 
629  if (write_p)
631  if (read_p)
633  break;
634  }
635  case is_syntax_call:
636  {
637  call real_call = syntax_call(real_s);
638  entity real_op = call_function(real_call);
639  list args = call_arguments(real_call);
640  effect n_eff = effect_undefined;
641 
642  if (ENTITY_ASSIGN_P(real_op))
643  {
645  (l_sum_eff, EXPRESSION(CAR(CDR(args))), context);
646  }
647  else if(ENTITY_ADDRESS_OF_P(real_op))
648  {
649  expression arg1 = EXPRESSION(CAR(args));
650  list l_real_arg = NIL;
651  list l_eff_real;
652 
653  /* first we compute an effect on the argument of the
654  * address_of operator (to treat cases like &(n->m))*/
655  pips_debug(6, "addressing operator case \n");
656 
657  l_real_arg =
659  (arg1, &l_eff_real, true);
660 
661  pips_debug_effects(6, "base effects :\n", l_eff_real);
662 
663  FOREACH(EFFECT, eff_real, l_eff_real)
664  {
665  FOREACH(EFFECT, eff, l_sum_eff) {
666  reference eff_ref = effect_any_reference(eff);
667  list eff_ind = reference_indices(eff_ref);
668 
669  pips_debug_effect(6, "current formal effect :\n", eff);
670 
671  if (effect_undefined_p(eff_real) || anywhere_effect_p(eff_real))
672  {
674  }
675  else
676  {
677  if(!ENDP(eff_ind))
678  {
679  // functions that can be pointed by effect_dup_func:
680  // simple_effect_dup
681  // region_dup
682  // copy_effect
683  effect eff_init = (*effect_dup_func)(eff);
684 
685  /* we translate the initial region descriptor
686  * into the caller's name space
687  */
689 
690  reference output_ref;
691  descriptor output_desc;
692  bool exact;
693 
695  (effect_any_reference(eff), effect_descriptor(eff_init),
696  effect_any_reference(eff_real), effect_descriptor(eff_real),
697  0,
698  &output_ref, &output_desc,
699  &exact);
700 
702  {
703  free_reference(output_ref);
705  }
706  else
707  {
708  n_eff = make_effect(make_cell_reference(output_ref),
711  output_desc);
712  pips_debug_effect(6, "resulting effect: \n", n_eff);
713  }
714  } /* if(!ENDP(eff_ind))*/
715  } /* else du if (effect_undefined_p(eff_real) || ...) */
716 
717  l_eff = gen_nconc(l_eff, CONS(EFFECT, n_eff, NIL));
718  } /* FOREACH(EFFECT, eff, l_sum_eff) */
719  } /* FOREACH (EFFECT, eff_real, l_eff_real) */
720 
721  gen_free_list(l_real_arg);
722  gen_full_free_list(l_eff_real);
723 
724  }
725  else if(ENTITY_DEREFERENCING_P(real_op))
726  {
727  // expression arg1 = EXPRESSION(CAR(args));
728 
729  pips_debug(6, "dereferencing operator case \n");
730 
731  /* if it's a pointer or a partially indexed array
732  * We should do more testing here to check if types
733  * are compatible...
734  */
735  if (pointer_type_p(real_arg_t) ||
736  !ENDP(variable_dimensions(type_variable(real_arg_t))))
737  {
738  pips_debug(8, "pointer type real arg\n");
739  /* first compute the region corresponding to the
740  * real argument
741  */
742  list l_real_eff = NIL;
743  list l_real_arg =
745  (real_arg, &l_real_eff, true);
746 
747  pips_debug_effects(6, "base effects :\n", l_real_eff);
748 
749  FOREACH(EFFECT, real_eff, l_real_eff)
750  {
751  FOREACH(EFFECT, eff, l_sum_eff) {
752  /* this could easily be made generic BC. */
753  /* FI: I add the restriction on store regions, but
754  * they should have been eliminated before translation
755  * is attempted */
756  if(!anywhere_effect_p(real_eff) && store_effect_p(real_eff))
757  {
758  reference n_eff_ref;
759  descriptor n_eff_d;
760  effect n_eff;
761  bool exact_translation_p;
762  // functions that can be pointed by effect_dup_func:
763  // simple_effect_dup
764  // region_dup
765  // copy_effect
766  effect init_eff = (*effect_dup_func)(eff);
767 
768  /* we translate the initial region descriptor
769  * into the caller's name space
770  */
772  /* and then perform the translation */
774  effect_descriptor(init_eff),
775  effect_any_reference(real_eff),
776  effect_descriptor(real_eff),
777  0,
778  &n_eff_ref, &n_eff_d,
779  &exact_translation_p);
780  n_eff = make_effect(make_cell_reference(n_eff_ref), copy_action(effect_action(eff)),
781  exact_translation_p? copy_approximation(effect_approximation(eff)) : make_approximation_may(),
782  n_eff_d);
783  /* shouldn't it be a union ? BC */
784  l_eff = gen_nconc(l_eff, CONS(EFFECT, n_eff, NIL));
785  free_effect(init_eff);
786  }
787  }
788  }
789  gen_free_list(l_real_arg);
790  gen_full_free_list(l_real_eff);
791 
792  } /* if (pointer_type_p(real_arg_t)) */
793  else
794  {
795  pips_debug(8, "real arg reference is not a pointer and is not a partially indexed array -> NIL \n");
796  } /* else */
797  break;
798  }
799  else if(ENTITY_POINT_TO_P(real_op)|| ENTITY_FIELD_P(real_op))
800  {
801  list l_real_arg = NIL;
802  list l_eff_real = NIL;
803  /* first we compute an effect on the real_arg */
804 
805  pips_debug(6, "point_to or field operator\n");
807  (real_arg, &l_eff_real, true);
808 
809  FOREACH(EFFECT, eff_real, l_eff_real)
810  {
811  FOREACH(EFFECT, eff, l_sum_eff) {
812  // functions that can be pointed by effect_dup_func:
813  // simple_effect_dup
814  // region_dup
815  // copy_effect
816  effect eff_formal = (*effect_dup_func)(eff);
817  effect new_eff;
818 
819  if (effect_undefined_p(eff_real))
821  else
822  {
823  // functions that can be pointed by effect_dup_func:
824  // simple_effect_dup
825  // region_dup
826  // copy_effect
827  new_eff = (*effect_dup_func)(eff_real);
828  effect_approximation_tag(new_eff) =
830  effect_action_tag(new_eff) =
831  effect_action_tag(eff);
832 
833 
834  /* first we translate the formal region predicate */
836 
837  /* Then we append the formal region to the real region */
838  /* Well this is valid only in the general case :
839  * we should verify that types are compatible. */
840  new_eff = region_append(new_eff, eff_formal);
841  free_effect(eff_formal);
842 
843  } /* else du if (effect_undefined_p(eff_real)) */
844 
845  /* shouldn't it be a union ? BC */
846  l_eff = gen_nconc(l_eff, CONS(EFFECT, new_eff, NIL));
847  } /* FOREACH(EFFECT, eff, l_sum_eff) */
848  }
849  gen_free_list(l_real_arg);
850  gen_full_free_list(l_eff_real);
851 
852  }
853  else if(ENTITY_MALLOC_SYSTEM_P(real_op))
854  {
855  /* BC : do not generate effects on HEAP */
856  /* n_eff = heap_effect(get_current_module_entity(),
857  * copy_action(effect_action(eff)));*/
858  }
859  else
860  {
861  l_eff = gen_nconc
862  (l_eff,
864  }
865 
866  if (n_eff != effect_undefined && l_eff == NIL)
867  l_eff = CONS(EFFECT,n_eff, NIL);
868  break;
869  } /* case is_syntax_call */
870  case is_syntax_cast :
871  {
872  pips_debug(5, "cast case\n");
873  expression cast_exp = cast_expression(syntax_cast(real_s));
874  type cast_t = expression_to_type(cast_exp);
875  /* we should test here the compatibility of the casted expression type with
876  * the formal entity type. It is not available here, however, I think it's
877  * equivalent to test the compatibility with the real arg expression type
878  * since the current function is called after testing the compatilibty between
879  * the real expression type and the formal parameter type.
880  */
882  {
883  l_eff = gen_nconc
884  (l_eff,
886  (l_sum_eff, cast_exp, context));
887  }
888  else if (!ENDP(l_sum_eff))
889  {
890  /* let us at least generate effects on all memory locations reachable from
891  * the cast expression
892  */
893  bool read_p = false, write_p = false;
894  FOREACH(EFFECT, eff, l_sum_eff)
895  {
896  if(effect_write_p(eff)) write_p = true;
897  else read_p = false;
898  }
899  tag t = write_p ? (read_p ? 'x' : 'w') : 'r';
900  l_eff = gen_nconc
901  (l_eff,
903  }
904 
905  break;
906  }
908  {
909  pips_debug(5,"sizeof expression -> NIL");
910  break;
911  }
912  case is_syntax_va_arg :
913  {
914  pips_internal_error("va_arg() : should have been treated before");
915  break;
916  }
917  case is_syntax_application :
918  {
919  bool read_p = false, write_p = false;
920  pips_user_warning("Application not supported yet -> anywhere effect\n");
921  FOREACH(EFFECT, eff, l_sum_eff)
922  {
923  if(effect_write_p(eff)) write_p = true;
924  else read_p = true;
925  }
926  if (write_p)
928  if (read_p)
930  break;
931  }
932  case is_syntax_range :
933  {
934  pips_user_error("Illegal effective parameter: range\n");
935  break;
936  }
937  default:
938  pips_internal_error("Illegal kind of syntax");
939  break;
940  } /* switch */
941 
942  /* free_type(real_arg_t); */
943 
945  // functions that can be pointed by effects_precondition_composition_op:
946  // effects_composition_with_preconditions_nop
947  // convex_regions_precondition_compose
948  (*effects_precondition_composition_op)(l_eff, context, false);
949  }
950  ifdebug(8)
951  {
952  pips_debug(8, "end with effects :\n");
953  print_regions(l_eff);
954  }
955 
956  return(l_eff);
957 }
reference copy_reference(reference p)
REFERENCE.
Definition: ri.c:2047
bool entity_all_locations_p(entity e)
test if an entity is the top of the lattice
list c_convex_effects_on_formal_parameter_backward_translation(list l_sum_eff, expression real_arg, transformer context)
void convex_cell_reference_with_address_of_cell_reference_translation(reference, descriptor, reference, descriptor, int, reference *, descriptor *, bool *)
void print_regions(list)
effect region_append(effect, effect)
effect make_anywhere_effect(action)
#define effect_approximation_tag(eff)
#define effect_write_p(eff)
#define effect_action_tag(eff)
bool store_effect_p(effect)
Definition: effects.c:1062
bool anywhere_effect_p(effect)
Is it an anywhere effect? ANYMMODULE:ANYWHERE
Definition: effects.c:346
action make_action_read_memory(void)
Definition: effects.c:1017
bool types_compatible_for_effects_interprocedural_translation_p(type, type)
tests if the actual argument type and the formal argument type are compatible with the current state ...
Definition: type.c:932
int tag
TAG.
Definition: newgen_types.h:92
string expression_to_string(expression e)
Definition: expression.c:77
#define ENTITY_DEREFERENCING_P(e)
#define ENTITY_POINT_TO_P(e)
#define ENTITY_FIELD_P(e)
C data structure and pointer management.
#define ENTITY_MALLOC_SYSTEM_P(e)
bool pointer_type_p(type)
Check for scalar pointers.
Definition: type.c:2993
size_t type_depth(type)
Number of steps to access the lowest leave of type t without dereferencing.
Definition: type.c:4880
string type_to_string(const type)
type.c
Definition: type.c:51
#define transformer_undefined_p(x)
Definition: ri.h:2848
#define ifdebug(n)
Definition: sg.c:47

References anywhere_effect_p(), c_actual_argument_to_may_summary_effects(), c_convex_effects_on_formal_parameter_backward_translation(), call_arguments, call_function, CAR, cast_expression, CDR, CONS, convex_cell_reference_with_address_of_cell_reference_translation(), convex_cell_reference_with_value_of_cell_reference_translation(), convex_region_descriptor_translation(), copy_action(), copy_approximation(), copy_reference(), EFFECT, effect_action, effect_action_tag, effect_any_reference, effect_approximation, effect_approximation_tag, effect_descriptor, effect_undefined, effect_undefined_p, effect_write_p, ENDP, ENTITY_ADDRESS_OF_P, entity_all_locations_p(), ENTITY_ASSIGN_P, ENTITY_DEREFERENCING_P, ENTITY_FIELD_P, ENTITY_MALLOC_SYSTEM_P, ENTITY_POINT_TO_P, entity_type, EXPRESSION, expression_syntax, expression_to_string(), expression_to_type(), FOREACH, free_effect(), free_reference(), gen_free_list(), gen_full_free_list(), gen_length(), gen_nconc(), generic_proper_effects_of_complex_address_expression(), ifdebug, is_syntax_application, is_syntax_call, is_syntax_cast, is_syntax_range, is_syntax_reference, is_syntax_sizeofexpression, is_syntax_subscript, is_syntax_va_arg, make_action_read_memory(), make_action_write_memory(), make_anywhere_effect(), make_approximation_may(), make_cell_reference(), make_effect(), NIL, pips_debug, pips_debug_effect, pips_debug_effects, pips_internal_error, pips_user_error, pips_user_warning, pointer_type_p(), print_regions(), reference_indices, reference_variable, region_append(), store_effect_p(), syntax_call, syntax_cast, syntax_reference, syntax_tag, transformer_undefined_p, type_depth(), type_to_string(), type_variable, types_compatible_for_effects_interprocedural_translation_p(), and variable_dimensions.

Referenced by c_convex_effects_on_formal_parameter_backward_translation(), set_methods_for_convex_effects(), and set_methods_for_convex_rw_pointer_effects().

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

◆ common_region_translation()

static list common_region_translation ( entity  callee,
region  reg,
bool  backward 
)
static

static list common_region_translation(entity func, region reg, bool backward) input : func is the called function, real_args are the real arguments, reg is the region to translate (it concerns an array in a common), and backward indicates the direction of the translation.

output : a list of regions, that are the translation of the initial region. modifies : nothing: duplicates the original region. comment : the algorithm is the following

Scan the variables of the common that belong to the target function For each variable do if it has elements in common with the variable of the initial region if both variables have the same layout in the common perform the translation using array_region-translation else use the subscript values, and take into account the relative offset of the variables in the common add to the translated region the declaration system of the target variable to have a smaller region. until all the elements of the initial variable have been translated.

If the entity is a top-level entity, no translation; It is the case for variables dexcribing I/O effects (LUNS).

First, we search if the common is declared in the target function; if not, we have to deterministically choose an arbitrary function in which the common is declared. It will be our reference. By deterministically, I mean that this function shall be chosen whenever we try to translate from this common to a routine where it is not declared.

If common not declared in caller, use the subroutine of the first entity that appears in the common layout. (not really deterministic: I should take the first name in lexical order. BC.

first, we calculate the offset and size of the region entity

then, we perform the translation

these entities have elements in common

Definition at line 1656 of file interprocedural.c.

1658 {
1659  list new_regions = NIL;
1660  entity reg_ent = region_entity(reg);
1661  entity caller = get_current_module_entity();
1662  entity source_func = backward ? callee : caller;
1663  entity target_func = backward ? caller : callee;
1664  entity entity_target_func = target_func;
1665  entity ccommon;
1666  list l_tmp, l_com_ent;
1667  int reg_ent_size, total_size, reg_ent_begin_offset, reg_ent_end_offset;
1668  region new_reg;
1669  bool found = false;
1670 
1671 
1672  ifdebug(5)
1673  {
1674  pips_debug(5,"input region: \n%s\n", region_to_string(reg));
1675  }
1676 
1677  /* If the entity is a top-level entity, no translation;
1678  * It is the case for variables dexcribing I/O effects (LUNS).
1679  */
1680 
1681  if (top_level_entity_p(reg_ent) || io_entity_p(reg_ent)
1682  || rand_effects_entity_p(reg_ent))
1683  {
1684  pips_debug(5,"top-level entity.\n");
1685  new_reg = region_translation
1686  (reg, source_func, reference_undefined,
1687  reg_ent, target_func, reference_undefined,
1688  0, backward);
1689  new_regions = CONS(EFFECT, new_reg, NIL);
1690  return(new_regions);
1691  }
1692 
1693 
1694 
1695  ifdebug(6)
1696  {
1697  pips_debug(5, "target function: %s (local name: %s)\n",
1698  entity_name(target_func), module_local_name(target_func));
1699  }
1700 
1701  /* First, we search if the common is declared in the target function;
1702  * if not, we have to deterministically choose an arbitrary function
1703  * in which the common is declared. It will be our reference.
1704  * By deterministically, I mean that this function shall be chosen whenever
1705  * we try to translate from this common to a routine where it is not
1706  * declared.
1707  */
1708  ccommon = ram_section(storage_ram(entity_storage(reg_ent)));
1709  l_com_ent = area_layout(type_area(entity_type(ccommon)));
1710 
1711  pips_debug(6, "common name: %s\n", entity_name(ccommon));
1712 
1713  for( l_tmp = l_com_ent; !ENDP(l_tmp) && !found; l_tmp = CDR(l_tmp) )
1714  {
1715  entity com_ent = ENTITY(CAR(l_tmp));
1716  if (strcmp(entity_module_name(com_ent),
1717  module_local_name(target_func)) == 0)
1718  {
1719  found = true;
1720  }
1721  }
1722 
1723  /* If common not declared in caller, use the subroutine of the first entity
1724  * that appears in the common layout. (not really deterministic: I should
1725  * take the first name in lexical order. BC.
1726  */
1727  if(!found)
1728  {
1729  entity ent = ENTITY(CAR(l_com_ent));
1730  entity_target_func =
1732  ifdebug(6)
1733  {
1734  pips_debug(6, "common not declared in caller,\n"
1735  "\t using %s declarations instead\n",
1736  entity_name(entity_target_func));
1737  }
1738  }
1739 
1740  /* first, we calculate the offset and size of the region entity */
1741  reg_ent_size = array_size(reg_ent);
1742  reg_ent_begin_offset = ram_offset(storage_ram(entity_storage(reg_ent)));
1743  reg_ent_end_offset = reg_ent_begin_offset + reg_ent_size - 1;
1744 
1745  pips_debug(6,
1746  "\n\treg_ent: size = %d, offset_begin = %d, offset_end = %d\n",
1747  reg_ent_size, reg_ent_begin_offset, reg_ent_end_offset);
1748 
1749  /* then, we perform the translation */
1750  ccommon = ram_section(storage_ram(entity_storage(reg_ent)));
1751  l_com_ent = area_layout(type_area(entity_type(ccommon)));
1752  total_size = 0;
1753 
1754  for(; !ENDP(l_com_ent) && (total_size < reg_ent_size);
1755  l_com_ent = CDR(l_com_ent))
1756  {
1757  entity new_ent = ENTITY(CAR(l_com_ent));
1758 
1759  pips_debug(6, "current entity: %s\n", entity_name(new_ent));
1760 
1761  if (strcmp(entity_module_name(new_ent),
1762  module_local_name(entity_target_func)) == 0)
1763  {
1764  int new_ent_size = array_size(new_ent);
1765  int new_ent_begin_offset =
1767  int new_ent_end_offset = new_ent_begin_offset + new_ent_size - 1;
1768 
1769  pips_debug(6, "\n\t new_ent: size = %d, "
1770  "offset_begin = %d, offset_end = %d \n",
1771  new_ent_size, new_ent_begin_offset, new_ent_end_offset);
1772 
1773  if ((new_ent_begin_offset <= reg_ent_end_offset) &&
1774  (reg_ent_begin_offset <= new_ent_end_offset ))
1775  /* these entities have elements in common */
1776  {
1777  int offset = reg_ent_begin_offset - new_ent_begin_offset;
1778 
1779  new_reg = region_translation
1780  (reg, source_func, reference_undefined,
1781  new_ent, target_func, reference_undefined,
1782  (Value) offset, backward);
1783  new_regions = RegionsMustUnion(new_regions,
1784  CONS(EFFECT, new_reg, NIL),
1786  total_size += min (reg_ent_begin_offset,new_ent_end_offset)
1787  - max(reg_ent_begin_offset, new_ent_begin_offset) + 1;
1788  }
1789  }
1790  }
1791 
1792  ifdebug(5)
1793  {
1794  pips_debug(5, "output regions: \n");
1795  print_regions(new_regions);
1796  }
1797  return(new_regions);
1798 }
int Value
#define region_entity(reg)
#define region
simulation of the type region
#define min(a, b)
#define max(a, b)
static Value offset
Definition: translation.c:283
string region_to_string(effect)
effect region_translation(effect, entity, reference, entity, entity, reference, Value, bool)
static int array_size(dim)
ARRAY_SIZE returns the number of elements in the array whose dimension list is DIM.
Definition: genClib.c:155
bool rand_effects_entity_p(entity e)
Definition: entity.c:1152
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
bool io_entity_p(entity e)
Several implicit entities are declared to define the implicit effects of IO statements.
Definition: entity.c:1139
bool top_level_entity_p(entity e)
Check if the scope of entity e is global.
Definition: entity.c:1130
const char * entity_module_name(entity e)
See comments about module_name().
Definition: entity.c:1092
#define reference_undefined
Definition: ri.h:2302
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define entity_storage(x)
Definition: ri.h:2794
#define ram_section(x)
Definition: ri.h:2249
#define area_layout(x)
Definition: ri.h:546
#define type_area(x)
Definition: ri.h:2946
#define storage_ram(x)
Definition: ri.h:2521
#define ram_offset(x)
Definition: ri.h:2251

References area_layout, array_size(), callee, CAR, CDR, CONS, EFFECT, effects_same_action_p(), ENDP, ENTITY, entity_module_name(), entity_name, entity_storage, entity_type, get_current_module_entity(), ifdebug, io_entity_p(), max, min, module_local_name(), module_name_to_entity(), NIL, offset, pips_debug, print_regions(), ram_offset, ram_section, rand_effects_entity_p(), reference_undefined, region, region_entity, region_to_string(), region_translation(), RegionsMustUnion(), storage_ram, top_level_entity_p(), and type_area.

Referenced by common_regions_backward_translation(), and common_regions_forward_translation().

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

◆ common_regions_backward_translation()

static list common_regions_backward_translation ( entity  func,
list  func_regions 
)
static

we are only interested in regions concerning common variables. They are the entities with a ram storage. They can not be dynamic variables, because these latter were eliminated of the code_regions (cf. region_of_module).

Definition at line 486 of file interprocedural.c.

487 {
488  list real_regions = NIL;
489 
490  MAP(EFFECT, func_reg,
491  {
492  /* we are only interested in regions concerning common variables.
493  * They are the entities with a ram storage. They can not be dynamic
494  * variables, because these latter were eliminated of the code_regions
495  * (cf. region_of_module). */
497  {
498  list regs = common_region_translation(func, func_reg, BACKWARD);
499  real_regions = RegionsMustUnion(real_regions, regs,
501  }
502  },
503  func_regions);
504 
505  return(real_regions);
506 
507 }
static list common_region_translation(entity func, region reg, bool backward)
static list common_region_translation(entity func, region reg, bool backward) input : func is the cal...
#define BACKWARD
#define MAP(_map_CASTER, _map_item, _map_code, _map_list)
Apply/map an instruction block on all the elements of a list (old fashioned)
Definition: newgen_list.h:226
#define storage_ram_p(x)
Definition: ri.h:2519

References BACKWARD, common_region_translation(), EFFECT, effects_same_action_p(), entity_storage, MAP, NIL, region_entity, RegionsMustUnion(), and storage_ram_p.

Referenced by regions_backward_translation().

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

◆ common_regions_forward_translation()

static list common_regions_forward_translation ( entity  func,
list  real_regions 
)
static

static list common_regions_forward_translation (entity func, list real_regions) input : the called function, the list of real arguments at call site, and the list of regions to translate.

output : the translated list of regions. modifies : nothing. comment :

we are only interested in regions concerning common variables. They are the entities with a ram storagethat are not dynamic variables

Definition at line 1138 of file interprocedural.c.

1139 {
1140  list func_regions = NIL;
1141 
1142  MAP(EFFECT, real_reg,
1143  {
1144  storage real_s = entity_storage(region_entity(real_reg));
1145  /* we are only interested in regions concerning common variables.
1146  * They are the entities with a ram storagethat are not dynamic
1147  * variables*/
1148  if (storage_ram_p(real_s) &&
1150  && !heap_area_p(ram_section(storage_ram(real_s)))
1151  && !stack_area_p(ram_section(storage_ram(real_s))))
1152  {
1153  list regs = common_region_translation(func, real_reg, FORWARD);
1154  func_regions = RegionsMustUnion(func_regions, regs,
1156  }
1157  },
1158  real_regions);
1159 
1160  return(func_regions);
1161 }
#define FORWARD
bool dynamic_area_p(entity aire)
Definition: area.c:68
bool stack_area_p(entity aire)
Definition: area.c:104
bool heap_area_p(entity aire)
Definition: area.c:86

References common_region_translation(), dynamic_area_p(), EFFECT, effects_same_action_p(), entity_storage, FORWARD, heap_area_p(), MAP, NIL, ram_section, region_entity, RegionsMustUnion(), stack_area_p(), storage_ram, and storage_ram_p.

Referenced by regions_forward_translation().

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

◆ convex_regions_backward_translation()

list convex_regions_backward_translation ( entity  func,
list  real_args,
list  l_reg,
transformer  context 
)

of effects

Parameters
funcunc
real_argseal_args
l_reg_reg
contextontext

Definition at line 298 of file interprocedural.c.

300 {
301  list l_res = NIL;
302 
303  l_res = regions_backward_translation(func, real_args, l_reg, context, true);
304 
305  return l_res;
306 }
list regions_backward_translation(entity func, list real_args, list func_regions, transformer context, bool proper)
list regions_backward_tranlation(entity func, list real_args, list func_regions, transformer context)...

References NIL, and regions_backward_translation().

Referenced by set_methods_for_convex_effects(), and set_methods_for_convex_rw_pointer_effects().

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

◆ convex_regions_forward_translation()

list convex_regions_forward_translation ( entity  callee,
list  real_args,
list  l_reg,
transformer  context 
)

of effects

Parameters
calleeallee
real_argseal_args
l_reg_reg
contextontext

Definition at line 309 of file interprocedural.c.

311 {
312  list l_res = NIL;
313 
315  l_res = regions_forward_translation(callee, real_args, l_reg, context);
317  l_res = generic_c_effects_forward_translation(callee, real_args, l_reg, context);
318  return l_res;
319 }
list regions_forward_translation(entity func, list real_args, list l_reg, transformer context)
list regions_forward_translation(entity func, list real_args, l_reg, transformer context input : the ...
list generic_c_effects_forward_translation(entity, list, list, transformer)
bool c_module_p(entity m)
Test if a module "m" is written in C.
Definition: entity.c:2777
bool fortran_module_p(entity m)
Test if a module is in Fortran.
Definition: entity.c:2799

References c_module_p(), callee, fortran_module_p(), generic_c_effects_forward_translation(), get_current_module_entity(), NIL, and regions_forward_translation().

Referenced by set_methods_for_convex_effects(), and set_methods_for_convex_rw_pointer_effects().

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

◆ convex_regions_translation_end()

void convex_regions_translation_end ( void  )

Definition at line 108 of file interprocedural.c.

109 {
112 }
void reset_arguments_to_eliminate(void)
void reset_translation_context_sc(void)

References reset_arguments_to_eliminate(), and reset_translation_context_sc().

Referenced by set_methods_for_convex_effects(), and set_methods_for_convex_rw_pointer_effects().

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

◆ convex_regions_translation_init()

void convex_regions_translation_init ( entity  callee,
list  real_args,
bool  backward_p 
)

jmp_buf overflow_error;

interprocedural.c

Parameters
calleeallee
real_argseal_args
backward_packward_p

Definition at line 98 of file interprocedural.c.

99 {
100 
102  if (backward_p)
104  else
106 }
void set_backward_arguments_to_eliminate(entity)
void set_forward_arguments_to_eliminate(void)
void set_interprocedural_translation_context_sc(entity, list)

References callee, set_backward_arguments_to_eliminate(), set_forward_arguments_to_eliminate(), and set_interprocedural_translation_context_sc().

Referenced by set_methods_for_convex_effects(), and set_methods_for_convex_rw_pointer_effects().

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

◆ formal_regions_backward_translation()

static list formal_regions_backward_translation ( entity  func,
list  real_args,
list  func_regions,
transformer  context 
)
static

static list formal_regions_backward_translation(entity func, list real_args, func_regions, transformer context) input : an external function func, its real arguments at call site (real_args), its summary regions (with formal args), and the calling context.

output : the translated formal regions. modifies : ? comment :

Algorithm :

let func_regions be the list of the regions on variables of func let real_regions be the list of the translated regions on common variables

real_regions = empty FOR each expression real_exp IN real_args arg_num = number in the list of the function real arguments FOR each func_reg IN func_regions func_ent = entity of the region func_reg IF func_ent is the formal parameter numbered arg_num IF real_exp is an lhs (expression with one entity) real_reg = translation of the region func_reg real_regions = (real_regions) U {real_reg} ELSE real_regions = (real_regions) U (regions of the expression real_exp) ENDIF ENDIF ENDFOR ENDFOR

If the formal parameter corresponds to the real argument then we perform the translation.

If the real argument is a reference to an entity, then we translate the regions of the corresponding formal parameter

The indices of the reference are always evaluated

Else, the real argument is a complex expression, which is merely evaluated during execution of the program; Since Fortran forbids write effects on expressions passed as arguments, the regions on the formal parameter are merely ignored. The regions computed are those of the real parameter expression.

Definition at line 414 of file interprocedural.c.

419 {
420  list real_regions = NIL, r_args;
421  int arg_num;
422 
423  pips_debug(8, "begin\n");
424 
425  for (r_args = real_args, arg_num = 1; r_args != NIL;
426  r_args = CDR(r_args), arg_num++)
427  {
428  MAP(EFFECT, func_reg,
429  {
430  entity func_ent = region_entity(func_reg);
431 
432  /* If the formal parameter corresponds to the real argument then
433  * we perform the translation.
434  */
435  if (ith_parameter_p(func, func_ent, arg_num))
436  {
437  expression real_exp = EXPRESSION(CAR(r_args));
438  syntax real_syn = expression_syntax(real_exp);
439 
440  /* If the real argument is a reference to an entity, then we
441  * translate the regions of the corresponding formal parameter
442  */
443  if (syntax_reference_p(real_syn))
444  {
445  reference real_ref = syntax_reference(real_syn);
446  list real_inds = reference_indices(real_ref);
447  entity real_ent = reference_variable(real_ref);
448  region real_reg;
449  real_reg =
450  region_translation(func_reg, func, reference_undefined,
451  real_ent, get_current_module_entity(), real_ref,
453 
454  real_regions = regions_add_region(real_regions, real_reg);
455  /* The indices of the reference are always evaluated */
456  if (! ENDP(real_inds))
457  real_regions = gen_nconc
458  (real_regions,
460  }
461  /* Else, the real argument is a complex expression, which
462  * is merely evaluated during execution of the program;
463  * Since Fortran forbids write effects on expressions
464  * passed as arguments, the regions on the formal parameter
465  * are merely ignored. The regions computed are those of the
466  * real parameter expression.
467  */
468  else
469  {
470  real_regions =
471  gen_nconc(real_regions,
473  }
474  }
475  }, func_regions);
476  }
477 
478  ifdebug(5)
479  {
480  pips_debug(5, "proper real regions\n");
481  print_regions(real_regions);
482  }
483  return(real_regions);
484 }
#define VALUE_ZERO
list proper_regions_of_expressions(list, transformer)
list regions_add_region(list, effect)
list generic_proper_effects_of_expression(expression)
bool ith_parameter_p(entity, entity, int)
returns true if v is the ith formal parameter of function f
Definition: util.c:125

References BACKWARD, CAR, CDR, EFFECT, ENDP, EXPRESSION, expression_syntax, gen_nconc(), generic_proper_effects_of_expression(), get_current_module_entity(), ifdebug, ith_parameter_p(), MAP, NIL, pips_debug, print_regions(), proper_regions_of_expressions(), reference_indices, reference_undefined, reference_variable, region, region_entity, region_translation(), regions_add_region(), syntax_reference, syntax_reference_p, and VALUE_ZERO.

Referenced by regions_backward_translation().

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

◆ get_out_summary_regions_list()

list get_out_summary_regions_list ( void  )

Definition at line 135 of file interprocedural.c.

136 {
137  return(l_sum_out_reg);
138 }
static list l_sum_out_reg

References l_sum_out_reg.

◆ in_regions_of_external()

list in_regions_of_external ( entity  func,
list  real_args,
transformer  context 
)

list in_regions_of_external(entity func, list real_args, transformer context) input : an external function func, and the list of real arguments used in the calling function.

output : the corresponding list of regions, at call site. modifies : nothing. comment : The effects of "func" are computed into externals effects, ie. ‘translated’. The translation is made in two phases : _ regions on formal parameters _ regions on common parameters

Get the regions of "func".

translate them

Parameters
funcunc
real_argseal_args
contextontext

Definition at line 232 of file interprocedural.c.

236 {
237  list le = NIL;
238  const char *func_name = module_local_name(func);
239 
240  pips_debug(4, "translation regions for %s\n", func_name);
241 
242  if (! entity_module_p(func))
243  {
244  pips_internal_error("%s: bad function", func_name);
245  }
246  else
247  {
248  list func_regions;
249 
250  /* Get the regions of "func". */
251  func_regions = effects_to_list((effects)
252  db_get_memory_resource(DBR_IN_SUMMARY_REGIONS, func_name, true));
253  /* translate them */
254  le = regions_backward_translation(func, real_args, func_regions, context,
255  SUMMARY);
256  }
257  return le;
258 }
#define SUMMARY
list effects_to_list(effects)
Definition: effects.c:209
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
bool entity_module_p(entity e)
Definition: entity.c:683

References db_get_memory_resource(), effects_to_list(), entity_module_p(), module_local_name(), NIL, pips_debug, pips_internal_error, regions_backward_translation(), and SUMMARY.

+ Here is the call graph for this function:

◆ out_regions_from_call_site_to_callee()

void out_regions_from_call_site_to_callee ( call  c)

void out_regions_from_call_site_to_callee(call c) input : a potential call site for current_callee.

output : nothing modifies : l_sum_out_reg becomes the may union of l_sum_out_reg and the translated out regions of the current call site. comment :

Definition at line 205 of file interprocedural.c.

206 {
208  list l_out = NIL, l_tmp = NIL;
209 
210  if (call_function(c) != current_callee)
211  return;
212 
215 
217  context);
219 }
static statement current_stmt
void update_out_summary_regions_list(list l_out)
static entity current_callee
list load_statement_out_regions(statement)
transformer load_statement_precondition(statement)

References call_arguments, call_function, current_callee, current_stmt, load_statement_out_regions(), load_statement_precondition(), NIL, regions_forward_translation(), and update_out_summary_regions_list().

Referenced by out_regions_from_caller_to_callee().

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

◆ out_regions_from_caller_to_callee()

list out_regions_from_caller_to_callee ( entity  caller,
entity  callee 
)

All we need to perform the translation

Parameters
calleraller
calleeallee

Definition at line 150 of file interprocedural.c.

151 {
152  const char *caller_name;
153  statement caller_statement;
154 
157  caller_name = module_local_name(caller);
158  pips_debug(2, "begin for caller: %s\n", caller_name);
159 
160  /* All we need to perform the translation */
162  db_get_memory_resource(DBR_CODE, caller_name, true) );
164  db_get_memory_resource(DBR_CUMULATED_EFFECTS, caller_name, true));
166  db_get_memory_resource(DBR_PROPER_EFFECTS, caller_name, true));
167  module_to_value_mappings(caller);
169  db_get_memory_resource(DBR_PRECONDITIONS, caller_name, true));
170 
172  db_get_memory_resource(DBR_OUT_REGIONS, caller_name, true) );
173 
174  caller_statement = (statement)
175  db_get_memory_resource (DBR_CODE, caller_name, true);
176 
178  gen_multi_recurse(caller_statement,
181  NULL);
182 
185 
187 
193  //free_value_mappings();
194  pips_debug(2, "end\n");
195  return(l_sum_out_reg);
196 }
static const char * caller_name
Definition: alias_check.c:122
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
void out_regions_from_call_site_to_callee(call c)
void out_regions_from_call_site_to_callee(call c) input : a potential call site for current_callee.
static bool stmt_filter(statement s)
void reset_out_effects(void)
void reset_proper_rw_effects(void)
void set_proper_rw_effects(statement_effects)
void set_cumulated_rw_effects(statement_effects)
void set_out_effects(statement_effects)
void reset_cumulated_rw_effects(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
void gen_multi_recurse(void *o,...)
Multi recursion visitor function.
Definition: genClib.c:3428
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
#define call_domain
newgen_callees_domain_defined
Definition: ri.h:58
void module_to_value_mappings(entity m)
void module_to_value_mappings(entity m): build hash tables between variables and values (old,...
Definition: mappings.c:624
void reset_precondition_map(void)
void set_precondition_map(statement_mapping)
void free_value_mappings(void)
Normal call to free the mappings.
Definition: value.c:1212

References call_domain, callee, caller_name, current_callee, db_get_memory_resource(), free_value_mappings(), gen_multi_recurse(), gen_null(), l_sum_out_reg, module_local_name(), module_to_value_mappings(), out_regions_from_call_site_to_callee(), pips_debug, reset_cumulated_rw_effects(), reset_current_module_entity(), reset_current_module_statement(), reset_out_effects(), reset_precondition_map(), reset_proper_rw_effects(), set_cumulated_rw_effects(), set_current_module_entity(), set_current_module_statement(), set_out_effects(), set_precondition_map(), set_proper_rw_effects(), statement_domain, and stmt_filter().

+ Here is the call graph for this function:

◆ real_regions_forward_translation()

static list real_regions_forward_translation ( entity  func,
list  real_args,
list  l_reg,
transformer  context 
)
static

static list real_regions_forward_translation(entity func, list real_args, l_reg, transformer context) input : the called function func, the real arguments of the call, the list of regions to translate, and the context of the call.

output : the list of translated regions correponding to the formal arguments of the called function. modifies : l_reg and the regions it contains. comment : for each real argument in real_args if it is a reference for each region in l_reg if the current region concerns the current real argument if the corresponding formal parameter is a scalar the translated region is a scalar region, which reference is the formal argument, and which action and approximation are those of the initial region. else it is an array, and the tranlation is performed by another procedure. endfor else, it is a complex expression we search the regions in l_reg corresponding to the elements accessed in the complex expression. and we make a read region corresponding to the formal scalar parameter. endif endfor

for each actual parameter expression, we search in the actual regions the corresponding elements. If it exists, we make the corresponding regions, and translate them

if

REVOIR ICI

else

for

Definition at line 1045 of file interprocedural.c.

1049 {
1050  entity caller = get_current_module_entity();
1051  int arg_num;
1052  list l_formal = NIL;
1053  list r_args = real_args;
1054 
1055  /* for each actual parameter expression, we search in the actual regions
1056  * the corresponding elements. If it exists, we make the corresponding
1057  * regions, and translate them */
1058 
1059  ifdebug(8)
1060  {
1061  pips_debug(8,"initial regions :\n");
1062  print_regions(l_reg);
1063  }
1064 
1065  for (arg_num = 1; !ENDP(r_args); r_args = CDR(r_args), arg_num++)
1066  {
1067  expression real_exp = EXPRESSION(CAR(r_args));
1068  entity formal_ent = find_ith_formal_parameter(func, arg_num);
1069 
1070  if (syntax_reference_p(expression_syntax(real_exp)))
1071  {
1072  reference real_ref = syntax_reference(expression_syntax(real_exp));
1073  entity real_ent = reference_variable(real_ref);
1074 
1075  MAP(EFFECT, reg,
1076  {
1077  entity reg_ent = region_entity(reg);
1078 
1079  pips_debug(8, " real = %s, formal = %s \n",
1080  entity_name(real_ent), entity_name(reg_ent));
1081 
1082  if (same_entity_p(reg_ent , real_ent))
1083  {
1084  region formal_reg;
1085  formal_reg = region_translation(
1086  reg, caller, real_ref,
1087  formal_ent, func, reference_undefined,
1088  VALUE_ZERO, FORWARD);
1089  l_formal = RegionsMustUnion(
1090  l_formal,
1091  CONS(EFFECT, formal_reg, NIL),
1093  }
1094  }, l_reg);
1095 
1096  } /* if */
1097  else
1098  {
1099  /* REVOIR ICI */
1100  list l_exp_reg = regions_of_expression(real_exp, context);
1101  list l_real_exp =
1102  RegionsIntersection(l_exp_reg, effects_dup(l_reg),
1104 
1105  pips_debug(8, "real argument is a complex expression \n"
1106  "\tit can not correspond to a written formal parameter.\n");
1107 
1108  if (!ENDP(l_real_exp))
1109  {
1111  region formal_reg =
1113  free_action(r);
1114  effect_to_may_effect(formal_reg);
1115  l_formal = RegionsMustUnion(l_formal,
1116  CONS(EFFECT, formal_reg, NIL),
1118  regions_free(l_real_exp);
1119  }
1120 
1121  } /* else */
1122 
1123  } /* for */
1124 
1125 
1126  return(l_formal);
1127 }
void free_action(action p)
Definition: effects.c:80
list RegionsIntersection(list l1, list l2, bool(*intersection_combinable_p)(effect, effect))
list RegionsIntersection(list l1,l2, bool (*intersection_combinable_p)(effect, effect)) input : outpu...
list regions_of_expression(expression, transformer)
effect reference_whole_region(reference, action)
reference make_regions_reference(entity)
void regions_free(list)
list effects_dup(list)
void effect_to_may_effect(effect)
bool same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321
entity find_ith_formal_parameter(entity the_fnct, int rank)
This function gives back the ith formal parameter, which is found in the declarations of a call or a ...
Definition: entity.c:1863

References CAR, CDR, CONS, EFFECT, effect_to_may_effect(), effects_dup(), effects_same_action_p(), ENDP, entity_name, EXPRESSION, expression_syntax, find_ith_formal_parameter(), FORWARD, free_action(), get_current_module_entity(), ifdebug, make_action_read_memory(), make_regions_reference(), MAP, NIL, pips_debug, print_regions(), reference_undefined, reference_variable, reference_whole_region(), region, region_entity, region_translation(), regions_free(), regions_of_expression(), RegionsIntersection(), RegionsMustUnion(), same_entity_p(), syntax_reference, syntax_reference_p, and VALUE_ZERO.

Referenced by regions_forward_translation().

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

◆ regions_backward_translation()

list regions_backward_translation ( entity  func,
list  real_args,
list  func_regions,
transformer  context,
bool  proper 
)

list regions_backward_tranlation(entity func, list real_args, list func_regions, transformer context) input : an external function func, and the list of real arguments used in the calling function.

output : the corresponding list of regions, at call site. modifies : nothing. comment : The effects of "func" are computed into externals effects, ie. ‘translated’. The translation is made in two phases : _ regions on formal parameters _ regions on common parameters

Compute the regions on formal variables.

Compute the regions on common variables (static & global variables).

FI: add local precondition (7 December 1992)

Parameters
funcunc
real_argseal_args
func_regionsunc_regions
contextontext
properroper

Definition at line 341 of file interprocedural.c.

344 {
345  list le = NIL;
346  list tce, tfe;
347 
348  ifdebug(4)
349  {
350  pips_debug(4,"Initial regions\n");
351  print_regions(func_regions);
352  }
353 
356 
357  /* Compute the regions on formal variables. */
358  tfe = formal_regions_backward_translation(func,real_args,func_regions,context);
359 
360  /* Compute the regions on common variables (static & global variables). */
361  tce = common_regions_backward_translation(func, func_regions);
362 
363  if (proper)
364  le = gen_nconc(tce,tfe);
365  else
366  le = RegionsMustUnion(tce, tfe, effects_same_action_p);
367 
368  /* FI: add local precondition (7 December 1992) */
369  le = regions_add_context(le, context);
370 
371  ifdebug(4)
372  {
373  pips_debug(4, " Translated_regions :\n");
374  print_regions(le);
375  }
376 
379  return(le);
380 }
static list common_regions_backward_translation(entity func, list func_regions)
static list formal_regions_backward_translation(entity func, list real_args, list func_regions, transformer context)
static list formal_regions_backward_translation(entity func, list real_args, func_regions,...
list regions_add_context(list, transformer)

References common_regions_backward_translation(), effects_same_action_p(), formal_regions_backward_translation(), gen_nconc(), ifdebug, NIL, pips_debug, print_regions(), regions_add_context(), RegionsMustUnion(), reset_arguments_to_eliminate(), reset_translation_context_sc(), set_backward_arguments_to_eliminate(), and set_interprocedural_translation_context_sc().

Referenced by convex_regions_backward_translation(), in_regions_of_external(), and regions_of_external().

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

◆ regions_forward_translation()

list regions_forward_translation ( entity  func,
list  real_args,
list  l_reg,
transformer  context 
)

list regions_forward_translation(entity func, list real_args, l_reg, transformer context input : the called function func, the real arguments of the call, the list of regions to translate, and the context of the call.

output : the translated list of regions : real arguments are translated into formal arguments, and common variables of the caller into common variables of the callee. modifies : nothing. comment :

Parameters
funcunc
real_argseal_args
l_reg_reg
contextontext

Definition at line 980 of file interprocedural.c.

984 {
985  list l_t_reg = NIL;
986  list l_form_reg, l_common_reg;
987 
988  ifdebug(3)
989  {
990  pips_debug(3,"initial regions :\n");
991  print_regions(l_reg);
992  }
993 
996 
998  (func, real_args, l_reg, context);
999  l_common_reg = common_regions_forward_translation(func, l_reg);
1000  l_t_reg = RegionsMustUnion
1001  (l_form_reg, l_common_reg, effects_same_action_p);
1002 
1003  ifdebug(3)
1004  {
1005  pips_debug(3,"final regions : \n");
1006  print_regions(l_t_reg);
1007  }
1008 
1011  return l_t_reg;
1012 }
static list real_regions_forward_translation(entity func, list real_args, list l_reg, transformer context)
static list real_regions_forward_translation(entity func, list real_args, l_reg, transformer context)...
static list common_regions_forward_translation(entity func, list real_regions)
static list common_regions_forward_translation (entity func, list real_regions) input : the called fu...

References common_regions_forward_translation(), effects_same_action_p(), ifdebug, NIL, pips_debug, print_regions(), real_regions_forward_translation(), RegionsMustUnion(), reset_arguments_to_eliminate(), reset_translation_context_sc(), set_forward_arguments_to_eliminate(), and set_interprocedural_translation_context_sc().

Referenced by convex_regions_forward_translation(), and out_regions_from_call_site_to_callee().

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

◆ regions_of_external()

list regions_of_external ( entity  func,
list  real_args,
transformer  context,
bool  proper 
)

list regions_of_external(entity func, list real_args, transformer context) input : an external function func, and the list of real arguments used in the calling function.

output : the corresponding list of regions, at call site. modifies : nothing. comment : The effects of "func" are computed into externals effects, ie. ‘translated’. The translation is made in two phases : _ regions on formal parameters _ regions on common parameters

Get the regions of "func".

translate them

Parameters
funcunc
real_argseal_args
contextontext
properroper

Definition at line 271 of file interprocedural.c.

273 {
274  list le = NIL;
275  const char *func_name = module_local_name(func);
276 
277  pips_debug(4, "translation regions for %s\n", func_name);
278 
279  if (! entity_module_p(func))
280  {
281  pips_internal_error("%s: bad function", func_name);
282  }
283  else
284  {
285  list func_regions;
286 
287  /* Get the regions of "func". */
288  func_regions = effects_to_list((effects)
289  db_get_memory_resource(DBR_SUMMARY_REGIONS, func_name, true));
290  /* translate them */
291  le = regions_backward_translation(func, real_args, func_regions, context,
292  proper);
293  }
294  return le;
295 }

References db_get_memory_resource(), effects_to_list(), entity_module_p(), module_local_name(), NIL, pips_debug, pips_internal_error, and regions_backward_translation().

+ Here is the call graph for this function:

◆ reset_out_summary_regions_list()

void reset_out_summary_regions_list ( void  )

Definition at line 121 of file interprocedural.c.

122 {
124 }
#define list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69

References l_sum_out_reg, and list_undefined.

Referenced by regions_to_loops().

+ Here is the caller graph for this function:

◆ stmt_filter()

static bool stmt_filter ( statement  s)
static

Definition at line 140 of file interprocedural.c.

142 {
143  pips_debug(1, "statement %td\n", statement_number(s));
144 
145  current_stmt = s;
146  return(true);
147 }
#define statement_number(x)
Definition: ri.h:2452

References current_stmt, pips_debug, and statement_number.

Referenced by out_regions_from_caller_to_callee().

+ Here is the caller graph for this function:

◆ update_out_summary_regions_list()

void update_out_summary_regions_list ( list  l_out)
Parameters
l_out_out

Definition at line 126 of file interprocedural.c.

127 {
129  l_sum_out_reg = l_out;
130  else
133 }
list RegionsMayUnion(list l1, list l2, bool(*union_combinable_p)(effect, effect))
list RegionsMayUnion(list l1, list l2, union_combinable_p) input : two lists of regions output : a li...
#define list_undefined_p(c)
Return if a list is undefined.
Definition: newgen_list.h:75

References effects_same_action_p(), l_sum_out_reg, list_undefined_p, and RegionsMayUnion().

Referenced by out_regions_from_call_site_to_callee().

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

Variable Documentation

◆ current_callee

◆ current_stmt

◆ l_sum_out_reg