PIPS
translation.c
Go to the documentation of this file.
1 /*
2 
3  $Id: translation.c 23412 2017-08-09 15:07:09Z irigoin $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of PIPS.
8 
9  PIPS is free software: you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 #ifdef HAVE_CONFIG_H
25  #include "pips_config.h"
26 #endif
27 /* package simple effects : Be'atrice Creusillet 5/97
28  *
29  * File: interprocedural.c
30  * ~~~~~~~~~~~~~~~~~~~~~~~
31  *
32  * This File contains functions for the interprocedural computation of simple
33  * effects.
34  */
35 
36 #include <stdio.h>
37 #include <string.h>
38 
39 #include "genC.h"
40 #include "linear.h"
41 #include "ri.h"
42 #include "effects.h"
43 #include "text.h"
44 
45 #include "misc.h"
46 #include "text-util.h"
47 #include "ri-util.h"
48 #include "properties.h"
49 #include "prettyprint.h"
50 #include "effects-util.h"
51 
52 #include "effects-generic.h"
53 #include "effects-simple.h"
54 
55 /* Assume asl and isl have the same number of elements. Build
56  * subscript list osl by adding when possible the subscripts in asl
57  * and isl. See if the addition is exact.
58  *
59  * symbolic expressions are preserved at this stage, to be deleted
60  * later for simple effects because they will be replaced by
61  * *. However, it might be useful when descriptors are used.
62  */
63 bool add_points_to_subscript_lists(list * posl, list asl, list isl)
64 {
65  list casl, cisl;
66  bool exact_p = true;
67  for(casl=asl, cisl=isl; !ENDP(casl) && !ENDP(cisl); POP(casl), POP(cisl)) {
68  expression a = EXPRESSION(CAR(casl));
69  expression i = EXPRESSION(CAR(cisl));
72  *posl = CONS(EXPRESSION, u, *posl);
73  exact_p = false;
74  }
75  else if(expression_field_p(a)) {
76  if(expression_field_p(i)) {
77  pips_assert("Both expressions are identical", expression_equal_p(a,i));
79  *posl = CONS(EXPRESSION, f, *posl); // exactitude unchanged
80  }
81  else
82  pips_internal_error("Unexpected case.\n");
83  }
84  else {
85  intptr_t as, is;
86  if(expression_integer_value(a,&as)) {
87  if(expression_integer_value(i, &is)) {
88  expression ns = int_to_expression((int)as+is);
89  *posl = CONS(EXPRESSION, ns, *posl); // exactitude unchanged
90  }
91  else {
93  if(as==0) {
94  ns = copy_expression(i);
95  }
96  else {
98  copy_expression(a),
99  copy_expression(i));
100  }
101  *posl = CONS(EXPRESSION, ns, *posl); // exactitude unchanged
102  }
103  }
104  else {
106  if(expression_integer_value(i, &is) && is==0)
107  ns = copy_expression(a);
108  else
110  copy_expression(a),
111  copy_expression(i));
112  *posl = CONS(EXPRESSION, ns, *posl); // exactitude unchanged
113  }
114  }
115  }
116  *posl = gen_nreverse(*posl);
117  return exact_p;
118 }
119 
120 /* FI: Let's deal with simple cases I think I know how to deal with.
121  */
123 (reference input_ref, descriptor __attribute__ ((unused)) input_desc,
124  reference address_of_ref, descriptor __attribute__ ((unused)) address_of_desc,
125  int nb_common_indices,
126  reference *output_ref, descriptor __attribute__ ((unused)) * output_desc,
127  bool *exact_p)
128 {
129  list sl = reference_indices(address_of_ref);
130  bool ok_p = nb_common_indices==0 || ENDP(sl);
131  if(ok_p) {
132  list isl = reference_indices(input_ref);
133  list asl = reference_indices(address_of_ref);
134  int nis = (int) gen_length(isl);
135  int nas = (int) gen_length(asl);
136  if(nis==nas) {
139  if(type_equal_p(cit, cat)) {
140  *output_ref = make_reference(reference_variable(address_of_ref), NIL);
141  list osl = NIL;
142  *exact_p = add_points_to_subscript_lists(&osl, asl, isl);
143  reference_indices(*output_ref) = osl;
144  }
145  else
146  ok_p = false;
147  }
148  else if(nis==nas+1) {
149  // Not sure this is useful
152  if(type_equal_p(cit, cat)) {
153  *output_ref = make_reference(reference_variable(address_of_ref), NIL);
154  list osl = NIL;
155  *exact_p = add_points_to_subscript_lists(&osl, asl, CDR(isl));
156  reference_indices(*output_ref) = osl;
157  }
158  else
159  ok_p = false;
160  }
161  else if(nis>0 && nas==0) {
162  // EffectsWithPointsTo/array05a: input_ref "r[0][0][0][0]" and
163  // address_of_ref "t" where "r" is a pointer towards a 3-D array "t"
164  expression fs = EXPRESSION(CAR(isl));
165  if(zero_expression_p(fs)) {
166  reference n_input_ref = make_reference(reference_variable(input_ref),
168  type cit = points_to_reference_to_concrete_type(n_input_ref);
169  free_reference(n_input_ref);
171  if(type_equal_p(cit, cat)) {
172  /* FI: this is not always correct because the index list may hide
173  * dereferencings... We should use only the indices that
174  * match the type of address_of_ref and call recursively the
175  * translation. Or rely on Beatrice's code.
176  */
177  type rt = points_to_reference_to_concrete_type(address_of_ref);
178  int nd = maximal_type_depth(rt);
179  // FI: may be "nd" when POINTS_TO_STRICT_POINTER_TYPES is set to true
180  bool strict_p = get_bool_property("POINTS_TO_STRICT_POINTER_TYPES");
181  if(strict_p? nis<=nd : nis<=nd+1) {
182  *output_ref = copy_reference(address_of_ref); // No subscripts
183  *exact_p = exact_points_to_subscript_list_p(CDR(isl));
184  reference_indices(*output_ref) = gen_full_copy_list(CDR(isl));
185  }
186  else
187  ok_p = false; // Let Beatrice take care of it...
188  }
189  else
190  ok_p = false;
191  }
192  else
193  ok_p = false;
194  }
195  else
196  ok_p = false;
197  }
198  if(ok_p) {
199  ifdebug(1) {
201  type ot = points_to_reference_to_concrete_type(*output_ref);
203  pips_internal_error("Translation failure: the type of the translated cells is different from the type of the input cell.\n");
204  }
205  }
206  return ok_p;
207 }
208 
209 /** @brief translates a simple memory access path reference from given indices
210  using an address_of memory access path reference
211 
212  This function is used when we want to translate a cell or an effect on a[i][j][k] as input_ref,
213  knowing that a[i] = &address_of_ref. In this case nb_common_indices is 1 (which corresponds to [i])
214 
215  @param input_ref is the input simple cell reference
216  @param input_desc is here for compatibility with the corresponding convex cells function.
217 
218  @param address_of_ref is the simple cell reference giving the output base memory access path.
219  @param address_of_desc is here for compatibility with the corresponding convex cells function.
220 
221  @param nb_common_indices is the number of indices of input_ref which must be skipped (why is it unique for all points-to arcs?)
222  @param output_ref is a pointer on the resulting reference
223  @param output_desc is here for compatibility with the corresponding convex cells function.
224  @param exact_p is a pointer on a bool which is set to true if the translation is exact, false otherwise.
225 
226  FI->BC: more examples would be useful. For instance, let's have
227  "p->i[1]" as points-to and hence "i[1]" as "address_of_ref". Let's
228  have "p[0]" as input ref. The number of common indices is zero in
229  the points-to arc. However, the two indices should be fused and
230  not concatenated.
231 
232  FI->BC: another example due to Pointers/array15.c. Input_ref is
233  b[0][3] and address_of_ref is _b_1[0][0]. nb_common_indices is
234  0. b is a pointer to an array and the thing to do is to add the
235  indices one by one, not to concatenate anything...
236 
237  FI->BC: this function is way too long. It must handle very
238  different cases, e.g. arrays of pointers, struct as well as simple
239  scalar pointer to scalar or arrays. It would be nice to have an
240  example for each class of input.
241  */
243 (reference input_ref, descriptor __attribute__ ((unused)) input_desc,
244  reference address_of_ref, descriptor __attribute__ ((unused)) address_of_desc,
245  int nb_common_indices,
246  reference *output_ref, descriptor __attribute__ ((unused)) * output_desc,
247  bool *exact_p)
248 {
249  pips_debug(1, "input_ref: %s\n", reference_to_string(input_ref));
250  pips_debug(1, "address_of_ref: %s\n", reference_to_string(address_of_ref));
251  pips_debug(1, "nb_common_indices: %d \n", nb_common_indices);
252 
253  if(simple_cell_reference_with_address_of_cell_reference_translation_fi(input_ref, input_desc, address_of_ref, address_of_desc, nb_common_indices, output_ref, output_desc, exact_p)) { // Francois' special case
254  ;
255  }
256  else { // Beatrice's code
257 
258  // For instance, we enter with nb_common_indices==0
259  // input_ref == m[0][tab2][0]
260  // address_of_ref == _m_1[0], which means m->_m_1[0]
261 
262  /* assume exactness */
263  *exact_p = true;
264 
265  /* */
266  *output_ref = copy_reference(address_of_ref);
267  // FI: this is already wrong for Pointers/array15.c
268  // We need output_indices=reference_indices(*output_ref)
269  list output_indices = gen_last(reference_indices(*output_ref));
270  list input_remaining_indices = reference_indices(input_ref);
271  for(int i = 0; i<nb_common_indices; i++, POP(input_remaining_indices));
272 
273  /* special case for the first remaining index: we must add it to the
274  last index of build_ref. FI: In fact, to the first one... */
275  if (!ENDP(output_indices)) {
276  expression last_output_indices_exp = EXPRESSION(CAR(output_indices));
277  expression first_input_remaining_exp = EXPRESSION(CAR(input_remaining_indices));
279  /* adapted from the address_of case of c_simple_effects_on_formal_parameter_backward_translation
280  this maybe should be put in another function
281  */
282  if(!unbounded_expression_p(last_output_indices_exp)) {
283  if (expression_reference_p(last_output_indices_exp) &&
284  entity_field_p(expression_variable(last_output_indices_exp))) {
285  if (!expression_equal_integer_p(first_input_remaining_exp, 0)) {
286  pips_user_warning("potential memory overflow due to effect -> returning anywhere\n");
287  free_reference(*output_ref);
288  *output_ref = make_reference(entity_all_locations(), NIL);
289  *exact_p = false;
290  }
291  else
292  new_exp = last_output_indices_exp;
293  }
294 
295  else if(!unbounded_expression_p(first_input_remaining_exp)) {
296  value v;
297  intptr_t i_last_output_indices_exp;
298  intptr_t i_first_input_remaining_exp;
299 
300  bool b_i_last_output_indices_exp = expression_integer_value(last_output_indices_exp, &i_last_output_indices_exp);
301  bool b_i_first_input_remaining_exp = expression_integer_value(first_input_remaining_exp, &i_first_input_remaining_exp);
302 
303  if (b_i_last_output_indices_exp && i_last_output_indices_exp == 0) {
304  new_exp = copy_expression(first_input_remaining_exp);
305  POP(input_remaining_indices);
306  }
307  else if (b_i_first_input_remaining_exp && i_first_input_remaining_exp == 0) {
308  new_exp = copy_expression(last_output_indices_exp);
309  POP(input_remaining_indices);
310  }
311  else {
312  new_exp = MakeBinaryCall
314  copy_expression(last_output_indices_exp), copy_expression(first_input_remaining_exp));
315  /* Then we must try to evaluate the expression */
316  v = EvalExpression(new_exp);
317  if (! value_undefined_p(v) &&
318  value_constant_p(v)) {
319  constant vc = value_constant(v);
320  if (constant_int_p(vc)) {
321  free_expression(new_exp);
322  new_exp = int_to_expression(constant_int(vc));
323  }
324  }
325  POP(input_remaining_indices);
326  }
327  }
328  else {
329  new_exp = make_unbounded_expression();
330  *exact_p = false;
331  POP(input_remaining_indices);
332  }
333  if (! entity_all_locations_p(reference_variable(*output_ref))) {
334  /* FI->BC: this looks much more like a concatenation than
335  a substitution of the first subscript. */
336  //CAR(gen_last(reference_indices(*output_ref))).p
337  // = (void *) new_exp;
338  expression old_s = EXPRESSION(CAR(gen_last(reference_indices(*output_ref))));
339  free_expression(old_s);
340  // FI: I do not see why it should be a change of the last subscript
341  // I'd rather see a change of the first subscript...
342  EXPRESSION_(CAR(gen_last(reference_indices(*output_ref)))) = new_exp;
343  }
344  }
345  else {
346  *exact_p = false;
347  POP(input_remaining_indices); // a * subscript absorbs everything
348  }
349  }
350  else /* ENDP(output_indices) */ {
351  /* address_of_ref is a scalar: the first remaning index must be equal to 0 */
352  expression first_input_remaining_exp = EXPRESSION(CAR(input_remaining_indices));
353  if (!expression_equal_integer_p(first_input_remaining_exp, 0)) {
354  /* FI->BC: A much better job could be done using a function
355  similar to source_to_sinks(). See for instance
356  Pointers/properties03.c: if the analysis is performed at
357  points-to level, the result is precise; if the very same
358  analysis is performed by effects_with_points_to, an
359  anywhere results. */
360  pips_user_warning("potential memory overflow due to effect -> returning anywhere\n");
361  free_reference(*output_ref);
362  // FI->BC: conditionally to a property,
363  // ALIASING_ACROSS_TYPES, a typed anywhere should be generated
364  *output_ref = make_reference(entity_all_locations(), NIL);
365  *exact_p = false;
366  }
367  }
368 
369  // FI->BC: something is missing here points-to
370  // If the target is an array, the first subscript at least should be
371  // replicated: if "p" in a pointer to an array "a", "p[0]" is "a[0]", not "a"
372  //
373  // This happens because "int * p;" defines implictly "p" as a
374  // pointer to an array
375 
376  if (! entity_all_locations_p(reference_variable(*output_ref)))
377  {
378  entity v = reference_variable(*output_ref);
379  // type vt = entity_type(v); // FI: should probably be a concrete
380  // FI: see EffectWitPointsTo/call09.c
382  // type, but hopefully this has been done earlier when computing
383  // points-to
384  // FI: under some circumstances, the first zero subscript must
385  // be ignored. See for instance EffectsWithPointsTo/call09.c
386  // list sl = (false && array_type_p(vt))? input_remaining_indices :
387  // CDR(input_remaining_indices);
388  list sl = input_remaining_indices; // default value
389  // FI->FI: Beatrice uses a more powerful zero detection
390  if(!array_type_p(vt)
391  && !ENDP(sl)
393  sl = CDR(input_remaining_indices);
394 
395  FOREACH(EXPRESSION, input_ind, sl)
396  {
397  reference_indices(*output_ref) = gen_nconc(reference_indices(*output_ref),
399  copy_expression(input_ind),
400  NIL));
401  }
402  }
403  }
404 
405  // FI: the consistency of the regenerated reference should be checked
406  // by computing its type, if only, under a ifdebug() guard...
407  pips_debug(8, "output reference %s\n",
408  reference_to_string(*output_ref));
409  ifdebug(1) {
411  type ot = points_to_reference_to_concrete_type(*output_ref);
412  if(!anywhere_reference_p(*output_ref)
414  pips_internal_error("Translation failure: the type of the translated cells is different from the type of the input cell.\n");
415  }
416  return;
417 }
418 
419 /** @brief translates a simple memory access path reference from given indices
420  using an value_of memory access path reference
421 
422  This function is used when we want to translate a cell or an effect on a[i][j][k] as input_ref,
423  knowing that a[i] = value_of_ref. In this case nb_common_indices is 1 (which corresponds to [i])
424 
425  @param input_ref is the input simple cell reference
426  @param input_desc is here for compatibility with the corresponding convex cells function.
427 
428  @param value_of_ref is the simple cell reference giving the output base memory access path.
429  @param value_of_desc is here for compatibility with the corresponding convex cells function.
430 
431  @param nb_common_indices is the number of indices of input_ref which must be skipped
432  @param output_ref is a pointer on the resulting reference
433  @param output_desc is here for compatibility with the corresponding convex cells function.
434  @param exact_p is a pointer on a bool which is set to true if the translation is exact, false otherwise.
435 
436  */
438 (reference input_ref, descriptor __attribute__ ((unused)) input_desc,
439  reference value_of_ref, descriptor __attribute__ ((unused)) value_of_desc,
440  int nb_common_indices,
441  reference *output_ref, descriptor __attribute__ ((unused)) * output_desc,
442  bool *exact_p)
443 {
444  /* assume exactness */
445  *exact_p = true;
446 
447  /* we do not handle yet the cases where the type of value_of_ref does not match
448  the type of a[i]. I need a special function to test if types are compatible,
449  because type_equal_p is much too strict.
450  moreover the signature of the function may not be adapted in case of the reshaping of a array
451  of structs into an array of char for instance.
452  */
453  list input_inds = reference_indices(input_ref);
454  *output_ref = copy_reference(value_of_ref);
455 
456  /* we add the indices of the input reference past the nb_common_indices
457  (they have already be poped out) to the copy of the value_of reference */
458 
459  for(int i = 0; i<nb_common_indices; i++, POP(input_inds));
460  FOREACH(EXPRESSION, input_ind, input_inds)
461  {
462  reference_indices(*output_ref) = gen_nconc(reference_indices(*output_ref),
464  copy_expression(input_ind),
465  NIL));
466  }
467 
468 }
469 
471 (cell input_cell, descriptor input_desc,
472  cell address_of_cell, descriptor address_of_desc,
473  int nb_common_indices,
474  cell *output_cell, descriptor * output_desc,
475  bool *exact_p)
476 {
477  reference input_ref = cell_any_reference(input_cell);
478  reference address_of_ref = cell_any_reference(address_of_cell);
479  reference output_ref;
481  address_of_ref, address_of_desc,
482  nb_common_indices, &output_ref,
483  output_desc,
484  exact_p);
485 
486  *output_cell = make_cell_reference(output_ref);
487 }
488 
490 (cell input_cell, descriptor input_desc,
491  cell value_of_cell, descriptor value_of_desc,
492  int nb_common_indices,
493  cell *output_cell, descriptor * output_desc,
494  bool *exact_p)
495 {
496  reference input_ref = cell_any_reference(input_cell);
497  reference value_of_ref = cell_any_reference(value_of_cell);
498  reference output_ref;
500  value_of_ref, value_of_desc,
501  nb_common_indices, &output_ref,
502  output_desc,
503  exact_p);
504 
505  *output_cell = make_cell_reference(output_ref);
506 }
float a2sf[2] __attribute__((aligned(16)))
USER generates a user error (i.e., non fatal) by printing the given MSG according to the FMT.
Definition: 3dnow.h:3
cell make_cell_reference(reference _field_)
Definition: effects.c:293
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
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
entity entity_all_locations()
eturn ANY_MODULE:ANYWHERE (the top of the lattice)
void const char const char const int
void simple_cell_reference_with_address_of_cell_reference_translation(reference, descriptor, reference, descriptor, int, reference *, descriptor *, bool *)
bool add_points_to_subscript_lists(list *, list, list)
translation.c
bool simple_cell_reference_with_address_of_cell_reference_translation_fi(reference, descriptor, reference, descriptor, int, reference *, descriptor *, bool *)
void simple_cell_with_value_of_cell_translation(cell, descriptor, cell, descriptor, int, cell *, descriptor *, bool *)
void simple_cell_reference_with_value_of_cell_reference_translation(reference, descriptor, reference, descriptor, int, reference *, descriptor *, bool *)
void simple_cell_with_address_of_cell_translation(cell, descriptor, cell, descriptor, int, cell *, descriptor *, bool *)
type points_to_reference_to_concrete_type(reference)
Definition: type.c:685
reference cell_any_reference(cell)
API for reference.
Definition: effects.c:77
bool anywhere_reference_p(reference)
Definition: effects.c:378
bool exact_points_to_subscript_list_p(list)
See if the subscript list sl is precise, i.e.
Definition: points_to.c:1027
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
#define cat(args...)
Definition: freia.h:41
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304
#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
list gen_last(list l)
Return the last element of a list.
Definition: list.c:578
#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
list gen_full_copy_list(list l)
Copy a list structure with element copy.
Definition: list.c:535
#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
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
string reference_to_string(reference r)
Definition: expression.c:87
#define PLUS_OPERATOR_NAME
#define binary_intrinsic_expression(name, e1, e2)
bool entity_field_p(entity e)
e is the field of a structure
Definition: entity.c:857
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
value EvalExpression(expression e)
Evaluate statically an expression.
Definition: eval.c:108
bool expression_integer_value(expression e, intptr_t *pval)
Definition: eval.c:792
bool expression_field_p(expression e)
The expression is of kind "s.a", where "s" is a struct and a "a" field.
Definition: expression.c:491
bool zero_expression_p(expression e)
Definition: expression.c:1217
expression make_unbounded_expression()
Definition: expression.c:4339
expression MakeBinaryCall(entity f, expression eg, expression ed)
Creates a call expression to a function with 2 arguments.
Definition: expression.c:354
bool expression_equal_p(expression e1, expression e2)
Syntactic equality e1==e2.
Definition: expression.c:1347
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
bool expression_equal_integer_p(expression exp, int i)
================================================================
Definition: expression.c:1977
bool unbounded_expression_p(expression e)
Definition: expression.c:4329
entity expression_variable(expression e)
Definition: expression.c:532
bool array_type_p(type)
Definition: type.c:2942
bool type_equal_p(type, type)
Definition: type.c:547
size_t maximal_type_depth(type)
Number of steps to access the lowest leave of type t without a recursive test.
Definition: type.c:4856
bool type_equal_up_to_qualifiers_p(type, type)
Definition: type.c:552
type entity_basic_concrete_type(entity)
retrieves or computes and then returns the basic concrete type of an entity
Definition: type.c:3677
#define value_undefined_p(x)
Definition: ri.h:3017
#define value_constant(x)
Definition: ri.h:3073
#define EXPRESSION_(x)
Definition: ri.h:1220
#define reference_variable(x)
Definition: ri.h:2326
#define constant_int(x)
Definition: ri.h:850
#define value_constant_p(x)
Definition: ri.h:3071
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define constant_int_p(x)
Definition: ri.h:848
#define expression_undefined
Definition: ri.h:1223
#define reference_indices(x)
Definition: ri.h:2328
#define ifdebug(n)
Definition: sg.c:47
#define intptr_t
Definition: stdint.in.h:294
The structure used to build lists in NewGen.
Definition: newgen_list.h:41